Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenexpr.c
Go to the documentation of this file.
00001 /* 00002 * Expression Abstract Syntax Tree Functions 00003 * 00004 * Copyright 2002 Ove Kaaven 00005 * Copyright 2006-2008 Robert Shearman 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #include "config.h" 00023 00024 #include <stdio.h> 00025 #include <stdlib.h> 00026 #include <stdarg.h> 00027 #include <assert.h> 00028 #include <ctype.h> 00029 #include <string.h> 00030 00031 #include "widl.h" 00032 #include "utils.h" 00033 #include "expr.h" 00034 #include "header.h" 00035 #include "typetree.h" 00036 #include "typegen.h" 00037 00038 static int is_integer_type(const type_t *type) 00039 { 00040 switch (type_get_type(type)) 00041 { 00042 case TYPE_ENUM: 00043 return TRUE; 00044 case TYPE_BASIC: 00045 switch (type_basic_get_type(type)) 00046 { 00047 case TYPE_BASIC_INT8: 00048 case TYPE_BASIC_INT16: 00049 case TYPE_BASIC_INT32: 00050 case TYPE_BASIC_INT64: 00051 case TYPE_BASIC_INT: 00052 case TYPE_BASIC_INT3264: 00053 case TYPE_BASIC_CHAR: 00054 case TYPE_BASIC_HYPER: 00055 case TYPE_BASIC_BYTE: 00056 case TYPE_BASIC_WCHAR: 00057 case TYPE_BASIC_ERROR_STATUS_T: 00058 return TRUE; 00059 case TYPE_BASIC_FLOAT: 00060 case TYPE_BASIC_DOUBLE: 00061 case TYPE_BASIC_HANDLE: 00062 return FALSE; 00063 } 00064 return FALSE; 00065 default: 00066 return FALSE; 00067 } 00068 } 00069 00070 static int is_signed_integer_type(const type_t *type) 00071 { 00072 switch (type_get_type(type)) 00073 { 00074 case TYPE_ENUM: 00075 return FALSE; 00076 case TYPE_BASIC: 00077 switch (type_basic_get_type(type)) 00078 { 00079 case TYPE_BASIC_INT8: 00080 case TYPE_BASIC_INT16: 00081 case TYPE_BASIC_INT32: 00082 case TYPE_BASIC_INT64: 00083 case TYPE_BASIC_INT: 00084 case TYPE_BASIC_INT3264: 00085 return type_basic_get_sign(type) < 0; 00086 case TYPE_BASIC_CHAR: 00087 return TRUE; 00088 case TYPE_BASIC_HYPER: 00089 case TYPE_BASIC_BYTE: 00090 case TYPE_BASIC_WCHAR: 00091 case TYPE_BASIC_ERROR_STATUS_T: 00092 case TYPE_BASIC_FLOAT: 00093 case TYPE_BASIC_DOUBLE: 00094 case TYPE_BASIC_HANDLE: 00095 return FALSE; 00096 } 00097 /* FALLTHROUGH */ 00098 default: 00099 return FALSE; 00100 } 00101 } 00102 00103 static int is_float_type(const type_t *type) 00104 { 00105 return (type_get_type(type) == TYPE_BASIC && 00106 (type_basic_get_type(type) == TYPE_BASIC_FLOAT || 00107 type_basic_get_type(type) == TYPE_BASIC_DOUBLE)); 00108 } 00109 00110 expr_t *make_expr(enum expr_type type) 00111 { 00112 expr_t *e = xmalloc(sizeof(expr_t)); 00113 e->type = type; 00114 e->ref = NULL; 00115 e->u.lval = 0; 00116 e->is_const = FALSE; 00117 e->cval = 0; 00118 return e; 00119 } 00120 00121 expr_t *make_exprl(enum expr_type type, int val) 00122 { 00123 expr_t *e = xmalloc(sizeof(expr_t)); 00124 e->type = type; 00125 e->ref = NULL; 00126 e->u.lval = val; 00127 e->is_const = FALSE; 00128 /* check for numeric constant */ 00129 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) 00130 { 00131 /* make sure true/false value is valid */ 00132 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); 00133 e->is_const = TRUE; 00134 e->cval = val; 00135 } 00136 return e; 00137 } 00138 00139 expr_t *make_exprd(enum expr_type type, double val) 00140 { 00141 expr_t *e = xmalloc(sizeof(expr_t)); 00142 e->type = type; 00143 e->ref = NULL; 00144 e->u.dval = val; 00145 e->is_const = TRUE; 00146 e->cval = val; 00147 return e; 00148 } 00149 00150 expr_t *make_exprs(enum expr_type type, char *val) 00151 { 00152 expr_t *e; 00153 e = xmalloc(sizeof(expr_t)); 00154 e->type = type; 00155 e->ref = NULL; 00156 e->u.sval = val; 00157 e->is_const = FALSE; 00158 /* check for predefined constants */ 00159 switch (type) 00160 { 00161 case EXPR_IDENTIFIER: 00162 { 00163 var_t *c = find_const(val, 0); 00164 if (c) 00165 { 00166 e->u.sval = c->name; 00167 free(val); 00168 e->is_const = TRUE; 00169 e->cval = c->eval->cval; 00170 } 00171 break; 00172 } 00173 case EXPR_CHARCONST: 00174 if (!val[0]) 00175 error_loc("empty character constant\n"); 00176 else if (val[1]) 00177 error_loc("multi-character constants are endian dependent\n"); 00178 else 00179 { 00180 e->is_const = TRUE; 00181 e->cval = *val; 00182 } 00183 break; 00184 default: 00185 break; 00186 } 00187 return e; 00188 } 00189 00190 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr) 00191 { 00192 expr_t *e; 00193 type_t *tref; 00194 00195 if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER) 00196 error_loc("invalid storage class for type expression\n"); 00197 00198 tref = var->type; 00199 00200 e = xmalloc(sizeof(expr_t)); 00201 e->type = type; 00202 e->ref = expr; 00203 e->u.tref = tref; 00204 e->is_const = FALSE; 00205 if (type == EXPR_SIZEOF) 00206 { 00207 /* only do this for types that should be the same on all platforms */ 00208 if (is_integer_type(tref) || is_float_type(tref)) 00209 { 00210 e->is_const = TRUE; 00211 e->cval = type_memsize(tref); 00212 } 00213 } 00214 /* check for cast of constant expression */ 00215 if (type == EXPR_CAST && expr->is_const) 00216 { 00217 if (is_integer_type(tref)) 00218 { 00219 unsigned int cast_type_bits = type_memsize(tref) * 8; 00220 unsigned int cast_mask; 00221 00222 e->is_const = TRUE; 00223 if (is_signed_integer_type(tref)) 00224 { 00225 cast_mask = (1 << (cast_type_bits - 1)) - 1; 00226 if (expr->cval & (1 << (cast_type_bits - 1))) 00227 e->cval = -((-expr->cval) & cast_mask); 00228 else 00229 e->cval = expr->cval & cast_mask; 00230 } 00231 else 00232 { 00233 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */ 00234 cast_mask = ((1 << (cast_type_bits - 1)) - 1) | 00235 1 << (cast_type_bits - 1); 00236 e->cval = expr->cval & cast_mask; 00237 } 00238 } 00239 else 00240 { 00241 e->is_const = TRUE; 00242 e->cval = expr->cval; 00243 } 00244 } 00245 free(var); 00246 return e; 00247 } 00248 00249 expr_t *make_expr1(enum expr_type type, expr_t *expr) 00250 { 00251 expr_t *e; 00252 e = xmalloc(sizeof(expr_t)); 00253 e->type = type; 00254 e->ref = expr; 00255 e->u.lval = 0; 00256 e->is_const = FALSE; 00257 /* check for compile-time optimization */ 00258 if (expr->is_const) 00259 { 00260 e->is_const = TRUE; 00261 switch (type) 00262 { 00263 case EXPR_LOGNOT: 00264 e->cval = !expr->cval; 00265 break; 00266 case EXPR_POS: 00267 e->cval = +expr->cval; 00268 break; 00269 case EXPR_NEG: 00270 e->cval = -expr->cval; 00271 break; 00272 case EXPR_NOT: 00273 e->cval = ~expr->cval; 00274 break; 00275 default: 00276 e->is_const = FALSE; 00277 break; 00278 } 00279 } 00280 return e; 00281 } 00282 00283 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2) 00284 { 00285 expr_t *e; 00286 e = xmalloc(sizeof(expr_t)); 00287 e->type = type; 00288 e->ref = expr1; 00289 e->u.ext = expr2; 00290 e->is_const = FALSE; 00291 /* check for compile-time optimization */ 00292 if (expr1->is_const && expr2->is_const) 00293 { 00294 e->is_const = TRUE; 00295 switch (type) 00296 { 00297 case EXPR_ADD: 00298 e->cval = expr1->cval + expr2->cval; 00299 break; 00300 case EXPR_SUB: 00301 e->cval = expr1->cval - expr2->cval; 00302 break; 00303 case EXPR_MOD: 00304 if (expr2->cval == 0) 00305 { 00306 error_loc("divide by zero in expression\n"); 00307 e->cval = 0; 00308 } 00309 else 00310 e->cval = expr1->cval % expr2->cval; 00311 break; 00312 case EXPR_MUL: 00313 e->cval = expr1->cval * expr2->cval; 00314 break; 00315 case EXPR_DIV: 00316 if (expr2->cval == 0) 00317 { 00318 error_loc("divide by zero in expression\n"); 00319 e->cval = 0; 00320 } 00321 else 00322 e->cval = expr1->cval / expr2->cval; 00323 break; 00324 case EXPR_OR: 00325 e->cval = expr1->cval | expr2->cval; 00326 break; 00327 case EXPR_AND: 00328 e->cval = expr1->cval & expr2->cval; 00329 break; 00330 case EXPR_SHL: 00331 e->cval = expr1->cval << expr2->cval; 00332 break; 00333 case EXPR_SHR: 00334 e->cval = expr1->cval >> expr2->cval; 00335 break; 00336 case EXPR_LOGOR: 00337 e->cval = expr1->cval || expr2->cval; 00338 break; 00339 case EXPR_LOGAND: 00340 e->cval = expr1->cval && expr2->cval; 00341 break; 00342 case EXPR_XOR: 00343 e->cval = expr1->cval ^ expr2->cval; 00344 break; 00345 case EXPR_EQUALITY: 00346 e->cval = expr1->cval == expr2->cval; 00347 break; 00348 case EXPR_INEQUALITY: 00349 e->cval = expr1->cval != expr2->cval; 00350 break; 00351 case EXPR_GTR: 00352 e->cval = expr1->cval > expr2->cval; 00353 break; 00354 case EXPR_LESS: 00355 e->cval = expr1->cval < expr2->cval; 00356 break; 00357 case EXPR_GTREQL: 00358 e->cval = expr1->cval >= expr2->cval; 00359 break; 00360 case EXPR_LESSEQL: 00361 e->cval = expr1->cval <= expr2->cval; 00362 break; 00363 default: 00364 e->is_const = FALSE; 00365 break; 00366 } 00367 } 00368 return e; 00369 } 00370 00371 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3) 00372 { 00373 expr_t *e; 00374 e = xmalloc(sizeof(expr_t)); 00375 e->type = type; 00376 e->ref = expr1; 00377 e->u.ext = expr2; 00378 e->ext2 = expr3; 00379 e->is_const = FALSE; 00380 /* check for compile-time optimization */ 00381 if (expr1->is_const && expr2->is_const && expr3->is_const) 00382 { 00383 e->is_const = TRUE; 00384 switch (type) 00385 { 00386 case EXPR_COND: 00387 e->cval = expr1->cval ? expr2->cval : expr3->cval; 00388 break; 00389 default: 00390 e->is_const = FALSE; 00391 break; 00392 } 00393 } 00394 return e; 00395 } 00396 00397 struct expression_type 00398 { 00399 int is_variable; /* is the expression resolved to a variable? */ 00400 int is_temporary; /* should the type be freed? */ 00401 type_t *type; 00402 }; 00403 00404 static void check_scalar_type(const struct expr_loc *expr_loc, 00405 const type_t *cont_type, const type_t *type) 00406 { 00407 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) && 00408 !is_float_type(type))) 00409 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n", 00410 expr_loc->attr ? " for attribute " : "", 00411 expr_loc->attr ? expr_loc->attr : ""); 00412 } 00413 00414 static void check_arithmetic_type(const struct expr_loc *expr_loc, 00415 const type_t *cont_type, const type_t *type) 00416 { 00417 if (!cont_type || (!is_integer_type(type) && !is_float_type(type))) 00418 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n", 00419 expr_loc->attr ? " for attribute " : "", 00420 expr_loc->attr ? expr_loc->attr : ""); 00421 } 00422 00423 static void check_integer_type(const struct expr_loc *expr_loc, 00424 const type_t *cont_type, const type_t *type) 00425 { 00426 if (!cont_type || !is_integer_type(type)) 00427 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n", 00428 expr_loc->attr ? " for attribute " : "", 00429 expr_loc->attr ? expr_loc->attr : ""); 00430 } 00431 00432 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type) 00433 { 00434 type_t *type = NULL; 00435 const var_t *field; 00436 const var_list_t *fields = NULL; 00437 00438 *found_in_cont_type = 0; 00439 00440 if (cont_type) 00441 { 00442 switch (type_get_type(cont_type)) 00443 { 00444 case TYPE_FUNCTION: 00445 fields = type_function_get_args(cont_type); 00446 break; 00447 case TYPE_STRUCT: 00448 fields = type_struct_get_fields(cont_type); 00449 break; 00450 case TYPE_UNION: 00451 case TYPE_ENCAPSULATED_UNION: 00452 fields = type_union_get_cases(cont_type); 00453 break; 00454 case TYPE_VOID: 00455 case TYPE_BASIC: 00456 case TYPE_ENUM: 00457 case TYPE_MODULE: 00458 case TYPE_COCLASS: 00459 case TYPE_INTERFACE: 00460 case TYPE_POINTER: 00461 case TYPE_ARRAY: 00462 case TYPE_BITFIELD: 00463 /* nothing to do */ 00464 break; 00465 case TYPE_ALIAS: 00466 /* shouldn't get here because of using type_get_type above */ 00467 assert(0); 00468 break; 00469 } 00470 } 00471 00472 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) 00473 if (field->name && !strcmp(identifier, field->name)) 00474 { 00475 type = field->type; 00476 *found_in_cont_type = 1; 00477 break; 00478 } 00479 00480 if (!type) 00481 { 00482 var_t *const_var = find_const(identifier, 0); 00483 if (const_var) type = const_var->type; 00484 } 00485 00486 return type; 00487 } 00488 00489 static int is_valid_member_operand(const type_t *type) 00490 { 00491 switch (type_get_type(type)) 00492 { 00493 case TYPE_STRUCT: 00494 case TYPE_UNION: 00495 case TYPE_ENUM: 00496 return TRUE; 00497 default: 00498 return FALSE; 00499 } 00500 } 00501 00502 static struct expression_type resolve_expression(const struct expr_loc *expr_loc, 00503 const type_t *cont_type, 00504 const expr_t *e) 00505 { 00506 struct expression_type result; 00507 result.is_variable = FALSE; 00508 result.is_temporary = FALSE; 00509 result.type = NULL; 00510 switch (e->type) 00511 { 00512 case EXPR_VOID: 00513 break; 00514 case EXPR_HEXNUM: 00515 case EXPR_NUM: 00516 case EXPR_TRUEFALSE: 00517 result.is_temporary = FALSE; 00518 result.type = type_new_int(TYPE_BASIC_INT, 0); 00519 break; 00520 case EXPR_STRLIT: 00521 result.is_temporary = TRUE; 00522 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL); 00523 break; 00524 case EXPR_WSTRLIT: 00525 result.is_temporary = TRUE; 00526 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL); 00527 break; 00528 case EXPR_CHARCONST: 00529 result.is_temporary = TRUE; 00530 result.type = type_new_int(TYPE_BASIC_CHAR, 0); 00531 break; 00532 case EXPR_DOUBLE: 00533 result.is_temporary = TRUE; 00534 result.type = type_new_basic(TYPE_BASIC_DOUBLE); 00535 break; 00536 case EXPR_IDENTIFIER: 00537 { 00538 int found_in_cont_type; 00539 result.is_variable = TRUE; 00540 result.is_temporary = FALSE; 00541 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type); 00542 if (!result.type) 00543 { 00544 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n", 00545 e->u.sval, expr_loc->attr ? " for attribute " : "", 00546 expr_loc->attr ? expr_loc->attr : ""); 00547 } 00548 break; 00549 } 00550 case EXPR_LOGNOT: 00551 result = resolve_expression(expr_loc, cont_type, e->ref); 00552 check_scalar_type(expr_loc, cont_type, result.type); 00553 result.is_variable = FALSE; 00554 result.is_temporary = FALSE; 00555 result.type = type_new_int(TYPE_BASIC_INT, 0); 00556 break; 00557 case EXPR_NOT: 00558 result = resolve_expression(expr_loc, cont_type, e->ref); 00559 check_integer_type(expr_loc, cont_type, result.type); 00560 result.is_variable = FALSE; 00561 break; 00562 case EXPR_POS: 00563 case EXPR_NEG: 00564 result = resolve_expression(expr_loc, cont_type, e->ref); 00565 check_arithmetic_type(expr_loc, cont_type, result.type); 00566 result.is_variable = FALSE; 00567 break; 00568 case EXPR_ADDRESSOF: 00569 result = resolve_expression(expr_loc, cont_type, e->ref); 00570 if (!result.is_variable) 00571 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n", 00572 expr_loc->attr ? " for attribute " : "", 00573 expr_loc->attr ? expr_loc->attr : ""); 00574 result.is_variable = FALSE; 00575 result.is_temporary = TRUE; 00576 result.type = type_new_pointer(RPC_FC_UP, result.type, NULL); 00577 break; 00578 case EXPR_PPTR: 00579 result = resolve_expression(expr_loc, cont_type, e->ref); 00580 if (result.type && is_ptr(result.type)) 00581 result.type = type_pointer_get_ref(result.type); 00582 else if(result.type && is_array(result.type) 00583 && type_array_is_decl_as_ptr(result.type)) 00584 result.type = type_array_get_element(result.type); 00585 else 00586 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n", 00587 expr_loc->attr ? " for attribute " : "", 00588 expr_loc->attr ? expr_loc->attr : ""); 00589 break; 00590 case EXPR_CAST: 00591 result = resolve_expression(expr_loc, cont_type, e->ref); 00592 result.type = e->u.tref; 00593 break; 00594 case EXPR_SIZEOF: 00595 result.is_temporary = FALSE; 00596 result.type = type_new_int(TYPE_BASIC_INT, 0); 00597 break; 00598 case EXPR_SHL: 00599 case EXPR_SHR: 00600 case EXPR_MOD: 00601 case EXPR_MUL: 00602 case EXPR_DIV: 00603 case EXPR_ADD: 00604 case EXPR_SUB: 00605 case EXPR_AND: 00606 case EXPR_OR: 00607 case EXPR_XOR: 00608 { 00609 struct expression_type result_right; 00610 result = resolve_expression(expr_loc, cont_type, e->ref); 00611 result.is_variable = FALSE; 00612 result_right = resolve_expression(expr_loc, cont_type, e->u.ext); 00613 /* FIXME: these checks aren't strict enough for some of the operators */ 00614 check_scalar_type(expr_loc, cont_type, result.type); 00615 check_scalar_type(expr_loc, cont_type, result_right.type); 00616 break; 00617 } 00618 case EXPR_LOGOR: 00619 case EXPR_LOGAND: 00620 case EXPR_EQUALITY: 00621 case EXPR_INEQUALITY: 00622 case EXPR_GTR: 00623 case EXPR_LESS: 00624 case EXPR_GTREQL: 00625 case EXPR_LESSEQL: 00626 { 00627 struct expression_type result_left, result_right; 00628 result_left = resolve_expression(expr_loc, cont_type, e->ref); 00629 result_right = resolve_expression(expr_loc, cont_type, e->u.ext); 00630 check_scalar_type(expr_loc, cont_type, result_left.type); 00631 check_scalar_type(expr_loc, cont_type, result_right.type); 00632 result.is_temporary = FALSE; 00633 result.type = type_new_int(TYPE_BASIC_INT, 0); 00634 break; 00635 } 00636 case EXPR_MEMBER: 00637 result = resolve_expression(expr_loc, cont_type, e->ref); 00638 if (result.type && is_valid_member_operand(result.type)) 00639 result = resolve_expression(expr_loc, result.type, e->u.ext); 00640 else 00641 error_loc_info(&expr_loc->v->loc_info, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n", 00642 expr_loc->attr ? " for attribute " : "", 00643 expr_loc->attr ? expr_loc->attr : ""); 00644 break; 00645 case EXPR_COND: 00646 { 00647 struct expression_type result_first, result_second, result_third; 00648 result_first = resolve_expression(expr_loc, cont_type, e->ref); 00649 check_scalar_type(expr_loc, cont_type, result_first.type); 00650 result_second = resolve_expression(expr_loc, cont_type, e->u.ext); 00651 result_third = resolve_expression(expr_loc, cont_type, e->ext2); 00652 check_scalar_type(expr_loc, cont_type, result_second.type); 00653 check_scalar_type(expr_loc, cont_type, result_third.type); 00654 if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type)) 00655 error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" ); 00656 /* FIXME: determine the correct return type */ 00657 result = result_second; 00658 result.is_variable = FALSE; 00659 break; 00660 } 00661 case EXPR_ARRAY: 00662 result = resolve_expression(expr_loc, cont_type, e->ref); 00663 if (result.type && is_array(result.type)) 00664 { 00665 struct expression_type index_result; 00666 result.type = type_array_get_element(result.type); 00667 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext); 00668 if (!index_result.type || !is_integer_type(index_result.type)) 00669 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n", 00670 expr_loc->attr ? " for attribute " : "", 00671 expr_loc->attr ? expr_loc->attr : ""); 00672 } 00673 else 00674 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n", 00675 expr_loc->attr ? " for attribute " : "", 00676 expr_loc->attr ? expr_loc->attr : ""); 00677 break; 00678 } 00679 return result; 00680 } 00681 00682 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr) 00683 { 00684 struct expression_type expr_type; 00685 expr_type = resolve_expression(expr_loc, cont_type, expr); 00686 return expr_type.type; 00687 } 00688 00689 void write_expr(FILE *h, const expr_t *e, int brackets, 00690 int toplevel, const char *toplevel_prefix, 00691 const type_t *cont_type, const char *local_var_prefix) 00692 { 00693 switch (e->type) 00694 { 00695 case EXPR_VOID: 00696 break; 00697 case EXPR_NUM: 00698 fprintf(h, "%u", e->u.lval); 00699 break; 00700 case EXPR_HEXNUM: 00701 fprintf(h, "0x%x", e->u.lval); 00702 break; 00703 case EXPR_DOUBLE: 00704 fprintf(h, "%#.15g", e->u.dval); 00705 break; 00706 case EXPR_TRUEFALSE: 00707 if (e->u.lval == 0) 00708 fprintf(h, "FALSE"); 00709 else 00710 fprintf(h, "TRUE"); 00711 break; 00712 case EXPR_IDENTIFIER: 00713 if (toplevel && toplevel_prefix && cont_type) 00714 { 00715 int found_in_cont_type; 00716 find_identifier(e->u.sval, cont_type, &found_in_cont_type); 00717 if (found_in_cont_type) 00718 { 00719 fprintf(h, "%s%s", toplevel_prefix, e->u.sval); 00720 break; 00721 } 00722 } 00723 fprintf(h, "%s%s", local_var_prefix, e->u.sval); 00724 break; 00725 case EXPR_STRLIT: 00726 fprintf(h, "\"%s\"", e->u.sval); 00727 break; 00728 case EXPR_WSTRLIT: 00729 fprintf(h, "L\"%s\"", e->u.sval); 00730 break; 00731 case EXPR_CHARCONST: 00732 fprintf(h, "'%s'", e->u.sval); 00733 break; 00734 case EXPR_LOGNOT: 00735 fprintf(h, "!"); 00736 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00737 break; 00738 case EXPR_NOT: 00739 fprintf(h, "~"); 00740 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00741 break; 00742 case EXPR_POS: 00743 fprintf(h, "+"); 00744 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00745 break; 00746 case EXPR_NEG: 00747 fprintf(h, "-"); 00748 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00749 break; 00750 case EXPR_ADDRESSOF: 00751 fprintf(h, "&"); 00752 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00753 break; 00754 case EXPR_PPTR: 00755 fprintf(h, "*"); 00756 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00757 break; 00758 case EXPR_CAST: 00759 fprintf(h, "("); 00760 write_type_decl(h, e->u.tref, NULL); 00761 fprintf(h, ")"); 00762 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00763 break; 00764 case EXPR_SIZEOF: 00765 fprintf(h, "sizeof("); 00766 write_type_decl(h, e->u.tref, NULL); 00767 fprintf(h, ")"); 00768 break; 00769 case EXPR_SHL: 00770 case EXPR_SHR: 00771 case EXPR_MOD: 00772 case EXPR_MUL: 00773 case EXPR_DIV: 00774 case EXPR_ADD: 00775 case EXPR_SUB: 00776 case EXPR_AND: 00777 case EXPR_OR: 00778 case EXPR_LOGOR: 00779 case EXPR_LOGAND: 00780 case EXPR_XOR: 00781 case EXPR_EQUALITY: 00782 case EXPR_INEQUALITY: 00783 case EXPR_GTR: 00784 case EXPR_LESS: 00785 case EXPR_GTREQL: 00786 case EXPR_LESSEQL: 00787 if (brackets) fprintf(h, "("); 00788 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00789 switch (e->type) 00790 { 00791 case EXPR_SHL: fprintf(h, " << "); break; 00792 case EXPR_SHR: fprintf(h, " >> "); break; 00793 case EXPR_MOD: fprintf(h, " %% "); break; 00794 case EXPR_MUL: fprintf(h, " * "); break; 00795 case EXPR_DIV: fprintf(h, " / "); break; 00796 case EXPR_ADD: fprintf(h, " + "); break; 00797 case EXPR_SUB: fprintf(h, " - "); break; 00798 case EXPR_AND: fprintf(h, " & "); break; 00799 case EXPR_OR: fprintf(h, " | "); break; 00800 case EXPR_LOGOR: fprintf(h, " || "); break; 00801 case EXPR_LOGAND: fprintf(h, " && "); break; 00802 case EXPR_XOR: fprintf(h, " ^ "); break; 00803 case EXPR_EQUALITY: fprintf(h, " == "); break; 00804 case EXPR_INEQUALITY: fprintf(h, " != "); break; 00805 case EXPR_GTR: fprintf(h, " > "); break; 00806 case EXPR_LESS: fprintf(h, " < "); break; 00807 case EXPR_GTREQL: fprintf(h, " >= "); break; 00808 case EXPR_LESSEQL: fprintf(h, " <= "); break; 00809 default: break; 00810 } 00811 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00812 if (brackets) fprintf(h, ")"); 00813 break; 00814 case EXPR_MEMBER: 00815 if (brackets) fprintf(h, "("); 00816 if (e->ref->type == EXPR_PPTR) 00817 { 00818 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00819 fprintf(h, "->"); 00820 } 00821 else 00822 { 00823 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00824 fprintf(h, "."); 00825 } 00826 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, ""); 00827 if (brackets) fprintf(h, ")"); 00828 break; 00829 case EXPR_COND: 00830 if (brackets) fprintf(h, "("); 00831 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00832 fprintf(h, " ? "); 00833 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00834 fprintf(h, " : "); 00835 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00836 if (brackets) fprintf(h, ")"); 00837 break; 00838 case EXPR_ARRAY: 00839 if (brackets) fprintf(h, "("); 00840 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix); 00841 fprintf(h, "["); 00842 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix); 00843 fprintf(h, "]"); 00844 if (brackets) fprintf(h, ")"); 00845 break; 00846 } 00847 } 00848 00849 /* This is actually fairly involved to implement precisely, due to the 00850 effects attributes may have and things like that. Right now this is 00851 only used for optimization, so just check for a very small set of 00852 criteria that guarantee the types are equivalent; assume every thing 00853 else is different. */ 00854 static int compare_type(const type_t *a, const type_t *b) 00855 { 00856 if (a == b 00857 || (a->name 00858 && b->name 00859 && strcmp(a->name, b->name) == 0)) 00860 return 0; 00861 /* Ordering doesn't need to be implemented yet. */ 00862 return 1; 00863 } 00864 00865 int compare_expr(const expr_t *a, const expr_t *b) 00866 { 00867 int ret; 00868 00869 if (a->type != b->type) 00870 return a->type - b->type; 00871 00872 switch (a->type) 00873 { 00874 case EXPR_NUM: 00875 case EXPR_HEXNUM: 00876 case EXPR_TRUEFALSE: 00877 return a->u.lval - b->u.lval; 00878 case EXPR_DOUBLE: 00879 return a->u.dval - b->u.dval; 00880 case EXPR_IDENTIFIER: 00881 case EXPR_STRLIT: 00882 case EXPR_WSTRLIT: 00883 case EXPR_CHARCONST: 00884 return strcmp(a->u.sval, b->u.sval); 00885 case EXPR_COND: 00886 ret = compare_expr(a->ref, b->ref); 00887 if (ret != 0) 00888 return ret; 00889 ret = compare_expr(a->u.ext, b->u.ext); 00890 if (ret != 0) 00891 return ret; 00892 return compare_expr(a->ext2, b->ext2); 00893 case EXPR_OR: 00894 case EXPR_AND: 00895 case EXPR_ADD: 00896 case EXPR_SUB: 00897 case EXPR_MOD: 00898 case EXPR_MUL: 00899 case EXPR_DIV: 00900 case EXPR_SHL: 00901 case EXPR_SHR: 00902 case EXPR_MEMBER: 00903 case EXPR_ARRAY: 00904 case EXPR_LOGOR: 00905 case EXPR_LOGAND: 00906 case EXPR_XOR: 00907 case EXPR_EQUALITY: 00908 case EXPR_INEQUALITY: 00909 case EXPR_GTR: 00910 case EXPR_LESS: 00911 case EXPR_GTREQL: 00912 case EXPR_LESSEQL: 00913 ret = compare_expr(a->ref, b->ref); 00914 if (ret != 0) 00915 return ret; 00916 return compare_expr(a->u.ext, b->u.ext); 00917 case EXPR_CAST: 00918 ret = compare_type(a->u.tref, b->u.tref); 00919 if (ret != 0) 00920 return ret; 00921 /* Fall through. */ 00922 case EXPR_NOT: 00923 case EXPR_NEG: 00924 case EXPR_PPTR: 00925 case EXPR_ADDRESSOF: 00926 case EXPR_LOGNOT: 00927 case EXPR_POS: 00928 return compare_expr(a->ref, b->ref); 00929 case EXPR_SIZEOF: 00930 return compare_type(a->u.tref, b->u.tref); 00931 case EXPR_VOID: 00932 return 0; 00933 } 00934 return -1; 00935 } Generated on Fri May 25 2012 04:36:13 for ReactOS by
1.7.6.1
|