1 /*
2 * Expression Abstract Syntax Tree Functions
3 *
4 * Copyright 2002 Ove Kaaven
5 * Copyright 2006-2008 Robert Shearman
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include "config.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <assert.h>
28 #include <ctype.h>
29 #include <string.h>
30
31 #include "widl.h"
32 #include "utils.h"
33 #include "expr.h"
34 #include "header.h"
35 #include "typetree.h"
36 #include "typegen.h"
37
is_integer_type(const type_t * type)38 static int is_integer_type(const type_t *type)
39 {
40 switch (type_get_type(type))
41 {
42 case TYPE_ENUM:
43 return TRUE;
44 case TYPE_BASIC:
45 switch (type_basic_get_type(type))
46 {
47 case TYPE_BASIC_INT8:
48 case TYPE_BASIC_INT16:
49 case TYPE_BASIC_INT32:
50 case TYPE_BASIC_INT64:
51 case TYPE_BASIC_INT:
52 case TYPE_BASIC_INT3264:
53 case TYPE_BASIC_LONG:
54 case TYPE_BASIC_CHAR:
55 case TYPE_BASIC_HYPER:
56 case TYPE_BASIC_BYTE:
57 case TYPE_BASIC_WCHAR:
58 case TYPE_BASIC_ERROR_STATUS_T:
59 return TRUE;
60 case TYPE_BASIC_FLOAT:
61 case TYPE_BASIC_DOUBLE:
62 case TYPE_BASIC_HANDLE:
63 return FALSE;
64 }
65 return FALSE;
66 default:
67 return FALSE;
68 }
69 }
70
is_signed_integer_type(const type_t * type)71 static int is_signed_integer_type(const type_t *type)
72 {
73 switch (type_get_type(type))
74 {
75 case TYPE_ENUM:
76 return FALSE;
77 case TYPE_BASIC:
78 switch (type_basic_get_type(type))
79 {
80 case TYPE_BASIC_INT8:
81 case TYPE_BASIC_INT16:
82 case TYPE_BASIC_INT32:
83 case TYPE_BASIC_INT64:
84 case TYPE_BASIC_INT:
85 case TYPE_BASIC_INT3264:
86 case TYPE_BASIC_LONG:
87 return type_basic_get_sign(type) < 0;
88 case TYPE_BASIC_CHAR:
89 return TRUE;
90 case TYPE_BASIC_HYPER:
91 case TYPE_BASIC_BYTE:
92 case TYPE_BASIC_WCHAR:
93 case TYPE_BASIC_ERROR_STATUS_T:
94 case TYPE_BASIC_FLOAT:
95 case TYPE_BASIC_DOUBLE:
96 case TYPE_BASIC_HANDLE:
97 return FALSE;
98 }
99 /* FALLTHROUGH */
100 default:
101 return FALSE;
102 }
103 }
104
is_float_type(const type_t * type)105 static int is_float_type(const type_t *type)
106 {
107 return (type_get_type(type) == TYPE_BASIC &&
108 (type_basic_get_type(type) == TYPE_BASIC_FLOAT ||
109 type_basic_get_type(type) == TYPE_BASIC_DOUBLE));
110 }
111
make_expr(enum expr_type type)112 expr_t *make_expr(enum expr_type type)
113 {
114 expr_t *e = xmalloc(sizeof(expr_t));
115 e->type = type;
116 e->ref = NULL;
117 e->u.lval = 0;
118 e->is_const = FALSE;
119 e->cval = 0;
120 return e;
121 }
122
make_exprl(enum expr_type type,int val)123 expr_t *make_exprl(enum expr_type type, int val)
124 {
125 expr_t *e = xmalloc(sizeof(expr_t));
126 e->type = type;
127 e->ref = NULL;
128 e->u.lval = val;
129 e->is_const = FALSE;
130 /* check for numeric constant */
131 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
132 {
133 /* make sure true/false value is valid */
134 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
135 e->is_const = TRUE;
136 e->cval = val;
137 }
138 return e;
139 }
140
make_exprd(enum expr_type type,double val)141 expr_t *make_exprd(enum expr_type type, double val)
142 {
143 expr_t *e = xmalloc(sizeof(expr_t));
144 e->type = type;
145 e->ref = NULL;
146 e->u.dval = val;
147 e->is_const = TRUE;
148 e->cval = val;
149 return e;
150 }
151
make_exprs(enum expr_type type,char * val)152 expr_t *make_exprs(enum expr_type type, char *val)
153 {
154 expr_t *e;
155 e = xmalloc(sizeof(expr_t));
156 e->type = type;
157 e->ref = NULL;
158 e->u.sval = val;
159 e->is_const = FALSE;
160 /* check for predefined constants */
161 switch (type)
162 {
163 case EXPR_IDENTIFIER:
164 {
165 var_t *c = find_const(val, 0);
166 if (c)
167 {
168 e->u.sval = c->name;
169 free(val);
170 e->is_const = TRUE;
171 e->cval = c->eval->cval;
172 }
173 break;
174 }
175 case EXPR_CHARCONST:
176 if (!val[0])
177 error_loc("empty character constant\n");
178 else if (val[1])
179 error_loc("multi-character constants are endian dependent\n");
180 else
181 {
182 e->is_const = TRUE;
183 e->cval = *val;
184 }
185 break;
186 default:
187 break;
188 }
189 return e;
190 }
191
make_exprt(enum expr_type type,var_t * var,expr_t * expr)192 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
193 {
194 expr_t *e;
195 type_t *tref;
196
197 if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
198 error_loc("invalid storage class for type expression\n");
199
200 tref = var->type;
201
202 e = xmalloc(sizeof(expr_t));
203 e->type = type;
204 e->ref = expr;
205 e->u.tref = tref;
206 e->is_const = FALSE;
207 if (type == EXPR_SIZEOF)
208 {
209 /* only do this for types that should be the same on all platforms */
210 if (is_integer_type(tref) || is_float_type(tref))
211 {
212 e->is_const = TRUE;
213 e->cval = type_memsize(tref);
214 }
215 }
216 /* check for cast of constant expression */
217 if (type == EXPR_CAST && expr->is_const)
218 {
219 if (is_integer_type(tref))
220 {
221 unsigned int cast_type_bits = type_memsize(tref) * 8;
222 unsigned int cast_mask;
223
224 e->is_const = TRUE;
225 if (is_signed_integer_type(tref))
226 {
227 cast_mask = (1u << (cast_type_bits - 1)) - 1;
228 if (expr->cval & (1u << (cast_type_bits - 1)))
229 e->cval = -((-expr->cval) & cast_mask);
230 else
231 e->cval = expr->cval & cast_mask;
232 }
233 else
234 {
235 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
236 cast_mask = ((1u << (cast_type_bits - 1)) - 1) |
237 1u << (cast_type_bits - 1);
238 e->cval = expr->cval & cast_mask;
239 }
240 }
241 else
242 {
243 e->is_const = TRUE;
244 e->cval = expr->cval;
245 }
246 }
247 free(var);
248 return e;
249 }
250
make_expr1(enum expr_type type,expr_t * expr)251 expr_t *make_expr1(enum expr_type type, expr_t *expr)
252 {
253 expr_t *e;
254 e = xmalloc(sizeof(expr_t));
255 e->type = type;
256 e->ref = expr;
257 e->u.lval = 0;
258 e->is_const = FALSE;
259 /* check for compile-time optimization */
260 if (expr->is_const)
261 {
262 e->is_const = TRUE;
263 switch (type)
264 {
265 case EXPR_LOGNOT:
266 e->cval = !expr->cval;
267 break;
268 case EXPR_POS:
269 e->cval = +expr->cval;
270 break;
271 case EXPR_NEG:
272 e->cval = -expr->cval;
273 break;
274 case EXPR_NOT:
275 e->cval = ~expr->cval;
276 break;
277 default:
278 e->is_const = FALSE;
279 break;
280 }
281 }
282 return e;
283 }
284
make_expr2(enum expr_type type,expr_t * expr1,expr_t * expr2)285 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
286 {
287 expr_t *e;
288 e = xmalloc(sizeof(expr_t));
289 e->type = type;
290 e->ref = expr1;
291 e->u.ext = expr2;
292 e->is_const = FALSE;
293 /* check for compile-time optimization */
294 if (expr1->is_const && expr2->is_const)
295 {
296 e->is_const = TRUE;
297 switch (type)
298 {
299 case EXPR_ADD:
300 e->cval = expr1->cval + expr2->cval;
301 break;
302 case EXPR_SUB:
303 e->cval = expr1->cval - expr2->cval;
304 break;
305 case EXPR_MOD:
306 if (expr2->cval == 0)
307 {
308 error_loc("divide by zero in expression\n");
309 e->cval = 0;
310 }
311 else
312 e->cval = expr1->cval % expr2->cval;
313 break;
314 case EXPR_MUL:
315 e->cval = expr1->cval * expr2->cval;
316 break;
317 case EXPR_DIV:
318 if (expr2->cval == 0)
319 {
320 error_loc("divide by zero in expression\n");
321 e->cval = 0;
322 }
323 else
324 e->cval = expr1->cval / expr2->cval;
325 break;
326 case EXPR_OR:
327 e->cval = expr1->cval | expr2->cval;
328 break;
329 case EXPR_AND:
330 e->cval = expr1->cval & expr2->cval;
331 break;
332 case EXPR_SHL:
333 e->cval = expr1->cval << expr2->cval;
334 break;
335 case EXPR_SHR:
336 e->cval = expr1->cval >> expr2->cval;
337 break;
338 case EXPR_LOGOR:
339 e->cval = expr1->cval || expr2->cval;
340 break;
341 case EXPR_LOGAND:
342 e->cval = expr1->cval && expr2->cval;
343 break;
344 case EXPR_XOR:
345 e->cval = expr1->cval ^ expr2->cval;
346 break;
347 case EXPR_EQUALITY:
348 e->cval = expr1->cval == expr2->cval;
349 break;
350 case EXPR_INEQUALITY:
351 e->cval = expr1->cval != expr2->cval;
352 break;
353 case EXPR_GTR:
354 e->cval = expr1->cval > expr2->cval;
355 break;
356 case EXPR_LESS:
357 e->cval = expr1->cval < expr2->cval;
358 break;
359 case EXPR_GTREQL:
360 e->cval = expr1->cval >= expr2->cval;
361 break;
362 case EXPR_LESSEQL:
363 e->cval = expr1->cval <= expr2->cval;
364 break;
365 default:
366 e->is_const = FALSE;
367 break;
368 }
369 }
370 return e;
371 }
372
make_expr3(enum expr_type type,expr_t * expr1,expr_t * expr2,expr_t * expr3)373 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
374 {
375 expr_t *e;
376 e = xmalloc(sizeof(expr_t));
377 e->type = type;
378 e->ref = expr1;
379 e->u.ext = expr2;
380 e->ext2 = expr3;
381 e->is_const = FALSE;
382 /* check for compile-time optimization */
383 if (expr1->is_const && expr2->is_const && expr3->is_const)
384 {
385 e->is_const = TRUE;
386 switch (type)
387 {
388 case EXPR_COND:
389 e->cval = expr1->cval ? expr2->cval : expr3->cval;
390 break;
391 default:
392 e->is_const = FALSE;
393 break;
394 }
395 }
396 return e;
397 }
398
399 struct expression_type
400 {
401 int is_variable; /* is the expression resolved to a variable? */
402 int is_temporary; /* should the type be freed? */
403 type_t *type;
404 };
405
check_scalar_type(const struct expr_loc * expr_loc,const type_t * cont_type,const type_t * type)406 static void check_scalar_type(const struct expr_loc *expr_loc,
407 const type_t *cont_type, const type_t *type)
408 {
409 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
410 !is_float_type(type)))
411 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
412 expr_loc->attr ? " for attribute " : "",
413 expr_loc->attr ? expr_loc->attr : "");
414 }
415
check_arithmetic_type(const struct expr_loc * expr_loc,const type_t * cont_type,const type_t * type)416 static void check_arithmetic_type(const struct expr_loc *expr_loc,
417 const type_t *cont_type, const type_t *type)
418 {
419 if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
420 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
421 expr_loc->attr ? " for attribute " : "",
422 expr_loc->attr ? expr_loc->attr : "");
423 }
424
check_integer_type(const struct expr_loc * expr_loc,const type_t * cont_type,const type_t * type)425 static void check_integer_type(const struct expr_loc *expr_loc,
426 const type_t *cont_type, const type_t *type)
427 {
428 if (!cont_type || !is_integer_type(type))
429 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
430 expr_loc->attr ? " for attribute " : "",
431 expr_loc->attr ? expr_loc->attr : "");
432 }
433
find_identifier(const char * identifier,const type_t * cont_type,int * found_in_cont_type)434 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
435 {
436 type_t *type = NULL;
437 const var_t *field;
438 const var_list_t *fields = NULL;
439
440 *found_in_cont_type = 0;
441
442 if (cont_type)
443 {
444 switch (type_get_type(cont_type))
445 {
446 case TYPE_FUNCTION:
447 fields = type_function_get_args(cont_type);
448 break;
449 case TYPE_STRUCT:
450 fields = type_struct_get_fields(cont_type);
451 break;
452 case TYPE_UNION:
453 case TYPE_ENCAPSULATED_UNION:
454 fields = type_union_get_cases(cont_type);
455 break;
456 case TYPE_VOID:
457 case TYPE_BASIC:
458 case TYPE_ENUM:
459 case TYPE_MODULE:
460 case TYPE_COCLASS:
461 case TYPE_INTERFACE:
462 case TYPE_POINTER:
463 case TYPE_ARRAY:
464 case TYPE_BITFIELD:
465 /* nothing to do */
466 break;
467 case TYPE_ALIAS:
468 /* shouldn't get here because of using type_get_type above */
469 assert(0);
470 break;
471 }
472 }
473
474 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
475 if (field->name && !strcmp(identifier, field->name))
476 {
477 type = field->type;
478 *found_in_cont_type = 1;
479 break;
480 }
481
482 if (!type)
483 {
484 var_t *const_var = find_const(identifier, 0);
485 if (const_var) type = const_var->type;
486 }
487
488 return type;
489 }
490
is_valid_member_operand(const type_t * type)491 static int is_valid_member_operand(const type_t *type)
492 {
493 switch (type_get_type(type))
494 {
495 case TYPE_STRUCT:
496 case TYPE_UNION:
497 case TYPE_ENUM:
498 return TRUE;
499 default:
500 return FALSE;
501 }
502 }
503
resolve_expression(const struct expr_loc * expr_loc,const type_t * cont_type,const expr_t * e)504 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
505 const type_t *cont_type,
506 const expr_t *e)
507 {
508 struct expression_type result;
509 result.is_variable = FALSE;
510 result.is_temporary = FALSE;
511 result.type = NULL;
512 switch (e->type)
513 {
514 case EXPR_VOID:
515 break;
516 case EXPR_HEXNUM:
517 case EXPR_NUM:
518 case EXPR_TRUEFALSE:
519 result.is_temporary = FALSE;
520 result.type = type_new_int(TYPE_BASIC_INT, 0);
521 break;
522 case EXPR_STRLIT:
523 result.is_temporary = TRUE;
524 result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
525 break;
526 case EXPR_WSTRLIT:
527 result.is_temporary = TRUE;
528 result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
529 break;
530 case EXPR_CHARCONST:
531 result.is_temporary = TRUE;
532 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
533 break;
534 case EXPR_DOUBLE:
535 result.is_temporary = TRUE;
536 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
537 break;
538 case EXPR_IDENTIFIER:
539 {
540 int found_in_cont_type;
541 result.is_variable = TRUE;
542 result.is_temporary = FALSE;
543 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
544 if (!result.type)
545 {
546 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
547 e->u.sval, expr_loc->attr ? " for attribute " : "",
548 expr_loc->attr ? expr_loc->attr : "");
549 }
550 break;
551 }
552 case EXPR_LOGNOT:
553 result = resolve_expression(expr_loc, cont_type, e->ref);
554 check_scalar_type(expr_loc, cont_type, result.type);
555 result.is_variable = FALSE;
556 result.is_temporary = FALSE;
557 result.type = type_new_int(TYPE_BASIC_INT, 0);
558 break;
559 case EXPR_NOT:
560 result = resolve_expression(expr_loc, cont_type, e->ref);
561 check_integer_type(expr_loc, cont_type, result.type);
562 result.is_variable = FALSE;
563 break;
564 case EXPR_POS:
565 case EXPR_NEG:
566 result = resolve_expression(expr_loc, cont_type, e->ref);
567 check_arithmetic_type(expr_loc, cont_type, result.type);
568 result.is_variable = FALSE;
569 break;
570 case EXPR_ADDRESSOF:
571 result = resolve_expression(expr_loc, cont_type, e->ref);
572 if (!result.is_variable)
573 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
574 expr_loc->attr ? " for attribute " : "",
575 expr_loc->attr ? expr_loc->attr : "");
576 result.is_variable = FALSE;
577 result.is_temporary = TRUE;
578 result.type = type_new_pointer(FC_UP, result.type, NULL);
579 break;
580 case EXPR_PPTR:
581 result = resolve_expression(expr_loc, cont_type, e->ref);
582 if (result.type && is_ptr(result.type))
583 result.type = type_pointer_get_ref(result.type);
584 else if(result.type && is_array(result.type)
585 && type_array_is_decl_as_ptr(result.type))
586 result.type = type_array_get_element(result.type);
587 else
588 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
589 expr_loc->attr ? " for attribute " : "",
590 expr_loc->attr ? expr_loc->attr : "");
591 break;
592 case EXPR_CAST:
593 result = resolve_expression(expr_loc, cont_type, e->ref);
594 result.type = e->u.tref;
595 break;
596 case EXPR_SIZEOF:
597 result.is_temporary = FALSE;
598 result.type = type_new_int(TYPE_BASIC_INT, 0);
599 break;
600 case EXPR_SHL:
601 case EXPR_SHR:
602 case EXPR_MOD:
603 case EXPR_MUL:
604 case EXPR_DIV:
605 case EXPR_ADD:
606 case EXPR_SUB:
607 case EXPR_AND:
608 case EXPR_OR:
609 case EXPR_XOR:
610 {
611 struct expression_type result_right;
612 result = resolve_expression(expr_loc, cont_type, e->ref);
613 result.is_variable = FALSE;
614 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
615 /* FIXME: these checks aren't strict enough for some of the operators */
616 check_scalar_type(expr_loc, cont_type, result.type);
617 check_scalar_type(expr_loc, cont_type, result_right.type);
618 break;
619 }
620 case EXPR_LOGOR:
621 case EXPR_LOGAND:
622 case EXPR_EQUALITY:
623 case EXPR_INEQUALITY:
624 case EXPR_GTR:
625 case EXPR_LESS:
626 case EXPR_GTREQL:
627 case EXPR_LESSEQL:
628 {
629 struct expression_type result_left, result_right;
630 result_left = resolve_expression(expr_loc, cont_type, e->ref);
631 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
632 check_scalar_type(expr_loc, cont_type, result_left.type);
633 check_scalar_type(expr_loc, cont_type, result_right.type);
634 result.is_temporary = FALSE;
635 result.type = type_new_int(TYPE_BASIC_INT, 0);
636 break;
637 }
638 case EXPR_MEMBER:
639 result = resolve_expression(expr_loc, cont_type, e->ref);
640 if (result.type && is_valid_member_operand(result.type))
641 result = resolve_expression(expr_loc, result.type, e->u.ext);
642 else
643 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",
644 expr_loc->attr ? " for attribute " : "",
645 expr_loc->attr ? expr_loc->attr : "");
646 break;
647 case EXPR_COND:
648 {
649 struct expression_type result_first, result_second, result_third;
650 result_first = resolve_expression(expr_loc, cont_type, e->ref);
651 check_scalar_type(expr_loc, cont_type, result_first.type);
652 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
653 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
654 check_scalar_type(expr_loc, cont_type, result_second.type);
655 check_scalar_type(expr_loc, cont_type, result_third.type);
656 if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type))
657 error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" );
658 /* FIXME: determine the correct return type */
659 result = result_second;
660 result.is_variable = FALSE;
661 break;
662 }
663 case EXPR_ARRAY:
664 result = resolve_expression(expr_loc, cont_type, e->ref);
665 if (result.type && is_array(result.type))
666 {
667 struct expression_type index_result;
668 result.type = type_array_get_element(result.type);
669 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
670 if (!index_result.type || !is_integer_type(index_result.type))
671 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
672 expr_loc->attr ? " for attribute " : "",
673 expr_loc->attr ? expr_loc->attr : "");
674 }
675 else
676 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
677 expr_loc->attr ? " for attribute " : "",
678 expr_loc->attr ? expr_loc->attr : "");
679 break;
680 }
681 return result;
682 }
683
expr_resolve_type(const struct expr_loc * expr_loc,const type_t * cont_type,const expr_t * expr)684 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
685 {
686 struct expression_type expr_type;
687 expr_type = resolve_expression(expr_loc, cont_type, expr);
688 return expr_type.type;
689 }
690
write_expr(FILE * h,const expr_t * e,int brackets,int toplevel,const char * toplevel_prefix,const type_t * cont_type,const char * local_var_prefix)691 void write_expr(FILE *h, const expr_t *e, int brackets,
692 int toplevel, const char *toplevel_prefix,
693 const type_t *cont_type, const char *local_var_prefix)
694 {
695 switch (e->type)
696 {
697 case EXPR_VOID:
698 break;
699 case EXPR_NUM:
700 fprintf(h, "%u", e->u.lval);
701 break;
702 case EXPR_HEXNUM:
703 fprintf(h, "0x%x", e->u.lval);
704 break;
705 case EXPR_DOUBLE:
706 fprintf(h, "%#.15g", e->u.dval);
707 break;
708 case EXPR_TRUEFALSE:
709 if (e->u.lval == 0)
710 fprintf(h, "FALSE");
711 else
712 fprintf(h, "TRUE");
713 break;
714 case EXPR_IDENTIFIER:
715 if (toplevel && toplevel_prefix && cont_type)
716 {
717 int found_in_cont_type;
718 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
719 if (found_in_cont_type)
720 {
721 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
722 break;
723 }
724 }
725 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
726 break;
727 case EXPR_STRLIT:
728 fprintf(h, "\"%s\"", e->u.sval);
729 break;
730 case EXPR_WSTRLIT:
731 fprintf(h, "L\"%s\"", e->u.sval);
732 break;
733 case EXPR_CHARCONST:
734 fprintf(h, "'%s'", e->u.sval);
735 break;
736 case EXPR_LOGNOT:
737 fprintf(h, "!");
738 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
739 break;
740 case EXPR_NOT:
741 fprintf(h, "~");
742 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
743 break;
744 case EXPR_POS:
745 fprintf(h, "+");
746 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
747 break;
748 case EXPR_NEG:
749 fprintf(h, "-");
750 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
751 break;
752 case EXPR_ADDRESSOF:
753 fprintf(h, "&");
754 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
755 break;
756 case EXPR_PPTR:
757 fprintf(h, "*");
758 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
759 break;
760 case EXPR_CAST:
761 fprintf(h, "(");
762 write_type_decl(h, e->u.tref, NULL);
763 fprintf(h, ")");
764 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
765 break;
766 case EXPR_SIZEOF:
767 fprintf(h, "sizeof(");
768 write_type_decl(h, e->u.tref, NULL);
769 fprintf(h, ")");
770 break;
771 case EXPR_SHL:
772 case EXPR_SHR:
773 case EXPR_MOD:
774 case EXPR_MUL:
775 case EXPR_DIV:
776 case EXPR_ADD:
777 case EXPR_SUB:
778 case EXPR_AND:
779 case EXPR_OR:
780 case EXPR_LOGOR:
781 case EXPR_LOGAND:
782 case EXPR_XOR:
783 case EXPR_EQUALITY:
784 case EXPR_INEQUALITY:
785 case EXPR_GTR:
786 case EXPR_LESS:
787 case EXPR_GTREQL:
788 case EXPR_LESSEQL:
789 if (brackets) fprintf(h, "(");
790 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
791 switch (e->type)
792 {
793 case EXPR_SHL: fprintf(h, " << "); break;
794 case EXPR_SHR: fprintf(h, " >> "); break;
795 case EXPR_MOD: fprintf(h, " %% "); break;
796 case EXPR_MUL: fprintf(h, " * "); break;
797 case EXPR_DIV: fprintf(h, " / "); break;
798 case EXPR_ADD: fprintf(h, " + "); break;
799 case EXPR_SUB: fprintf(h, " - "); break;
800 case EXPR_AND: fprintf(h, " & "); break;
801 case EXPR_OR: fprintf(h, " | "); break;
802 case EXPR_LOGOR: fprintf(h, " || "); break;
803 case EXPR_LOGAND: fprintf(h, " && "); break;
804 case EXPR_XOR: fprintf(h, " ^ "); break;
805 case EXPR_EQUALITY: fprintf(h, " == "); break;
806 case EXPR_INEQUALITY: fprintf(h, " != "); break;
807 case EXPR_GTR: fprintf(h, " > "); break;
808 case EXPR_LESS: fprintf(h, " < "); break;
809 case EXPR_GTREQL: fprintf(h, " >= "); break;
810 case EXPR_LESSEQL: fprintf(h, " <= "); break;
811 default: break;
812 }
813 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
814 if (brackets) fprintf(h, ")");
815 break;
816 case EXPR_MEMBER:
817 if (brackets) fprintf(h, "(");
818 if (e->ref->type == EXPR_PPTR)
819 {
820 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
821 fprintf(h, "->");
822 }
823 else
824 {
825 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
826 fprintf(h, ".");
827 }
828 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
829 if (brackets) fprintf(h, ")");
830 break;
831 case EXPR_COND:
832 if (brackets) fprintf(h, "(");
833 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
834 fprintf(h, " ? ");
835 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
836 fprintf(h, " : ");
837 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
838 if (brackets) fprintf(h, ")");
839 break;
840 case EXPR_ARRAY:
841 if (brackets) fprintf(h, "(");
842 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
843 fprintf(h, "[");
844 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
845 fprintf(h, "]");
846 if (brackets) fprintf(h, ")");
847 break;
848 }
849 }
850
851 /* This is actually fairly involved to implement precisely, due to the
852 effects attributes may have and things like that. Right now this is
853 only used for optimization, so just check for a very small set of
854 criteria that guarantee the types are equivalent; assume every thing
855 else is different. */
compare_type(const type_t * a,const type_t * b)856 static int compare_type(const type_t *a, const type_t *b)
857 {
858 if (a == b
859 || (a->name
860 && b->name
861 && strcmp(a->name, b->name) == 0))
862 return 0;
863 /* Ordering doesn't need to be implemented yet. */
864 return 1;
865 }
866
compare_expr(const expr_t * a,const expr_t * b)867 int compare_expr(const expr_t *a, const expr_t *b)
868 {
869 int ret;
870
871 if (a->type != b->type)
872 return a->type - b->type;
873
874 switch (a->type)
875 {
876 case EXPR_NUM:
877 case EXPR_HEXNUM:
878 case EXPR_TRUEFALSE:
879 return a->u.lval - b->u.lval;
880 case EXPR_DOUBLE:
881 return a->u.dval - b->u.dval;
882 case EXPR_IDENTIFIER:
883 case EXPR_STRLIT:
884 case EXPR_WSTRLIT:
885 case EXPR_CHARCONST:
886 return strcmp(a->u.sval, b->u.sval);
887 case EXPR_COND:
888 ret = compare_expr(a->ref, b->ref);
889 if (ret != 0)
890 return ret;
891 ret = compare_expr(a->u.ext, b->u.ext);
892 if (ret != 0)
893 return ret;
894 return compare_expr(a->ext2, b->ext2);
895 case EXPR_OR:
896 case EXPR_AND:
897 case EXPR_ADD:
898 case EXPR_SUB:
899 case EXPR_MOD:
900 case EXPR_MUL:
901 case EXPR_DIV:
902 case EXPR_SHL:
903 case EXPR_SHR:
904 case EXPR_MEMBER:
905 case EXPR_ARRAY:
906 case EXPR_LOGOR:
907 case EXPR_LOGAND:
908 case EXPR_XOR:
909 case EXPR_EQUALITY:
910 case EXPR_INEQUALITY:
911 case EXPR_GTR:
912 case EXPR_LESS:
913 case EXPR_GTREQL:
914 case EXPR_LESSEQL:
915 ret = compare_expr(a->ref, b->ref);
916 if (ret != 0)
917 return ret;
918 return compare_expr(a->u.ext, b->u.ext);
919 case EXPR_CAST:
920 ret = compare_type(a->u.tref, b->u.tref);
921 if (ret != 0)
922 return ret;
923 /* Fall through. */
924 case EXPR_NOT:
925 case EXPR_NEG:
926 case EXPR_PPTR:
927 case EXPR_ADDRESSOF:
928 case EXPR_LOGNOT:
929 case EXPR_POS:
930 return compare_expr(a->ref, b->ref);
931 case EXPR_SIZEOF:
932 return compare_type(a->u.tref, b->u.tref);
933 case EXPR_VOID:
934 return 0;
935 }
936 return -1;
937 }
938