makedep: Don't add dependencies for tests of disabled dlls.
[wine.git] / tools / widl / expr.c
blob88d59290d6b3bf48ce7b943189377b69fd834dc4
1 /*
2 * Expression Abstract Syntax Tree Functions
4 * Copyright 2002 Ove Kaaven
5 * Copyright 2006-2008 Robert Shearman
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.
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.
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
22 #include "config.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <assert.h>
28 #include <ctype.h>
29 #include <string.h>
31 #include "widl.h"
32 #include "utils.h"
33 #include "expr.h"
34 #include "header.h"
35 #include "typetree.h"
36 #include "typegen.h"
38 static int is_integer_type(const type_t *type)
40 switch (type_get_type(type))
42 case TYPE_ENUM:
43 return TRUE;
44 case TYPE_BASIC:
45 switch (type_basic_get_type(type))
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;
65 return FALSE;
66 default:
67 return FALSE;
71 static int is_signed_integer_type(const type_t *type)
73 switch (type_get_type(type))
75 case TYPE_ENUM:
76 return FALSE;
77 case TYPE_BASIC:
78 switch (type_basic_get_type(type))
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;
99 /* FALLTHROUGH */
100 default:
101 return FALSE;
105 static int is_float_type(const type_t *type)
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));
112 expr_t *make_expr(enum expr_type type)
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;
123 expr_t *make_exprl(enum expr_type type, int val)
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)
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;
138 return e;
141 expr_t *make_exprd(enum expr_type type, double val)
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;
152 expr_t *make_exprs(enum expr_type type, char *val)
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)
163 case EXPR_IDENTIFIER:
165 var_t *c = find_const(val, 0);
166 if (c)
168 e->u.sval = c->name;
169 free(val);
170 e->is_const = TRUE;
171 e->cval = c->eval->cval;
173 break;
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
182 e->is_const = TRUE;
183 e->cval = *val;
185 break;
186 default:
187 break;
189 return e;
192 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
194 expr_t *e;
195 type_t *tref;
197 if (var->declspec.stgclass != STG_NONE && var->declspec.stgclass != STG_REGISTER)
198 error_loc("invalid storage class for type expression\n");
200 tref = var->declspec.type;
202 e = xmalloc(sizeof(expr_t));
203 e->type = type;
204 e->ref = expr;
205 e->u.tref = var->declspec;
206 e->is_const = FALSE;
207 if (type == EXPR_SIZEOF)
209 /* only do this for types that should be the same on all platforms */
210 if (is_integer_type(tref) || is_float_type(tref))
212 e->is_const = TRUE;
213 e->cval = type_memsize(tref);
216 /* check for cast of constant expression */
217 if (type == EXPR_CAST && expr->is_const)
219 if (is_integer_type(tref))
221 unsigned int cast_type_bits = type_memsize(tref) * 8;
222 unsigned int cast_mask;
224 e->is_const = TRUE;
225 if (is_signed_integer_type(tref))
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;
233 else
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;
241 else
243 e->is_const = TRUE;
244 e->cval = expr->cval;
247 free(var);
248 return e;
251 expr_t *make_expr1(enum expr_type type, expr_t *expr)
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)
262 e->is_const = TRUE;
263 switch (type)
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;
282 return e;
285 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
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)
296 e->is_const = TRUE;
297 switch (type)
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)
308 error_loc("divide by zero in expression\n");
309 e->cval = 0;
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)
320 error_loc("divide by zero in expression\n");
321 e->cval = 0;
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;
370 return e;
373 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
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)
385 e->is_const = TRUE;
386 switch (type)
388 case EXPR_COND:
389 e->cval = expr1->cval ? expr2->cval : expr3->cval;
390 break;
391 default:
392 e->is_const = FALSE;
393 break;
396 return e;
399 struct expression_type
401 int is_variable; /* is the expression resolved to a variable? */
402 int is_temporary; /* should the type be freed? */
403 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)
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 : "");
416 static void check_arithmetic_type(const struct expr_loc *expr_loc,
417 const type_t *cont_type, const type_t *type)
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 : "");
425 static void check_integer_type(const struct expr_loc *expr_loc,
426 const type_t *cont_type, const type_t *type)
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 : "");
434 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
436 type_t *type = NULL;
437 const var_t *field;
438 const var_list_t *fields = NULL;
440 *found_in_cont_type = 0;
442 if (cont_type)
444 switch (type_get_type(cont_type))
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 case TYPE_APICONTRACT:
466 case TYPE_RUNTIMECLASS:
467 case TYPE_PARAMETERIZED_TYPE:
468 case TYPE_PARAMETER:
469 case TYPE_DELEGATE:
470 /* nothing to do */
471 break;
472 case TYPE_ALIAS:
473 /* shouldn't get here because of using type_get_type above */
474 assert(0);
475 break;
479 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
480 if (field->name && !strcmp(identifier, field->name))
482 type = field->declspec.type;
483 *found_in_cont_type = 1;
484 break;
487 if (!type)
489 var_t *const_var = find_const(identifier, 0);
490 if (const_var) type = const_var->declspec.type;
493 return type;
496 static int is_valid_member_operand(const type_t *type)
498 switch (type_get_type(type))
500 case TYPE_STRUCT:
501 case TYPE_UNION:
502 case TYPE_ENUM:
503 return TRUE;
504 default:
505 return FALSE;
509 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
510 const type_t *cont_type,
511 const expr_t *e)
513 struct expression_type result;
514 result.is_variable = FALSE;
515 result.is_temporary = FALSE;
516 result.type = NULL;
517 switch (e->type)
519 case EXPR_VOID:
520 break;
521 case EXPR_HEXNUM:
522 case EXPR_NUM:
523 case EXPR_TRUEFALSE:
524 result.is_temporary = FALSE;
525 result.type = type_new_int(TYPE_BASIC_INT, 0);
526 break;
527 case EXPR_STRLIT:
528 result.is_temporary = TRUE;
529 result.type = type_new_pointer(type_new_int(TYPE_BASIC_CHAR, 0));
530 break;
531 case EXPR_WSTRLIT:
532 result.is_temporary = TRUE;
533 result.type = type_new_pointer(type_new_int(TYPE_BASIC_WCHAR, 0));
534 break;
535 case EXPR_CHARCONST:
536 result.is_temporary = TRUE;
537 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
538 break;
539 case EXPR_DOUBLE:
540 result.is_temporary = TRUE;
541 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
542 break;
543 case EXPR_IDENTIFIER:
545 int found_in_cont_type;
546 result.is_variable = TRUE;
547 result.is_temporary = FALSE;
548 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
549 if (!result.type)
551 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
552 e->u.sval, expr_loc->attr ? " for attribute " : "",
553 expr_loc->attr ? expr_loc->attr : "");
555 break;
557 case EXPR_LOGNOT:
558 result = resolve_expression(expr_loc, cont_type, e->ref);
559 check_scalar_type(expr_loc, cont_type, result.type);
560 result.is_variable = FALSE;
561 result.is_temporary = FALSE;
562 result.type = type_new_int(TYPE_BASIC_INT, 0);
563 break;
564 case EXPR_NOT:
565 result = resolve_expression(expr_loc, cont_type, e->ref);
566 check_integer_type(expr_loc, cont_type, result.type);
567 result.is_variable = FALSE;
568 break;
569 case EXPR_POS:
570 case EXPR_NEG:
571 result = resolve_expression(expr_loc, cont_type, e->ref);
572 check_arithmetic_type(expr_loc, cont_type, result.type);
573 result.is_variable = FALSE;
574 break;
575 case EXPR_ADDRESSOF:
576 result = resolve_expression(expr_loc, cont_type, e->ref);
577 if (!result.is_variable)
578 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
579 expr_loc->attr ? " for attribute " : "",
580 expr_loc->attr ? expr_loc->attr : "");
581 result.is_variable = FALSE;
582 result.is_temporary = TRUE;
583 result.type = type_new_pointer(result.type);
584 break;
585 case EXPR_PPTR:
586 result = resolve_expression(expr_loc, cont_type, e->ref);
587 if (result.type && is_ptr(result.type))
588 result.type = type_pointer_get_ref_type(result.type);
589 else if(result.type && is_array(result.type)
590 && type_array_is_decl_as_ptr(result.type))
591 result.type = type_array_get_element_type(result.type);
592 else
593 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
594 expr_loc->attr ? " for attribute " : "",
595 expr_loc->attr ? expr_loc->attr : "");
596 break;
597 case EXPR_CAST:
598 result = resolve_expression(expr_loc, cont_type, e->ref);
599 result.type = e->u.tref.type;
600 break;
601 case EXPR_SIZEOF:
602 result.is_temporary = FALSE;
603 result.type = type_new_int(TYPE_BASIC_INT, 0);
604 break;
605 case EXPR_SHL:
606 case EXPR_SHR:
607 case EXPR_MOD:
608 case EXPR_MUL:
609 case EXPR_DIV:
610 case EXPR_ADD:
611 case EXPR_SUB:
612 case EXPR_AND:
613 case EXPR_OR:
614 case EXPR_XOR:
616 struct expression_type result_right;
617 result = resolve_expression(expr_loc, cont_type, e->ref);
618 result.is_variable = FALSE;
619 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
620 /* FIXME: these checks aren't strict enough for some of the operators */
621 check_scalar_type(expr_loc, cont_type, result.type);
622 check_scalar_type(expr_loc, cont_type, result_right.type);
623 break;
625 case EXPR_LOGOR:
626 case EXPR_LOGAND:
627 case EXPR_EQUALITY:
628 case EXPR_INEQUALITY:
629 case EXPR_GTR:
630 case EXPR_LESS:
631 case EXPR_GTREQL:
632 case EXPR_LESSEQL:
634 struct expression_type result_left, result_right;
635 result_left = resolve_expression(expr_loc, cont_type, e->ref);
636 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
637 check_scalar_type(expr_loc, cont_type, result_left.type);
638 check_scalar_type(expr_loc, cont_type, result_right.type);
639 result.is_temporary = FALSE;
640 result.type = type_new_int(TYPE_BASIC_INT, 0);
641 break;
643 case EXPR_MEMBER:
644 result = resolve_expression(expr_loc, cont_type, e->ref);
645 if (result.type && is_valid_member_operand(result.type))
646 result = resolve_expression(expr_loc, result.type, e->u.ext);
647 else
648 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",
649 expr_loc->attr ? " for attribute " : "",
650 expr_loc->attr ? expr_loc->attr : "");
651 break;
652 case EXPR_COND:
654 struct expression_type result_first, result_second, result_third;
655 result_first = resolve_expression(expr_loc, cont_type, e->ref);
656 check_scalar_type(expr_loc, cont_type, result_first.type);
657 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
658 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
659 check_scalar_type(expr_loc, cont_type, result_second.type);
660 check_scalar_type(expr_loc, cont_type, result_third.type);
661 if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type))
662 error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" );
663 /* FIXME: determine the correct return type */
664 result = result_second;
665 result.is_variable = FALSE;
666 break;
668 case EXPR_ARRAY:
669 result = resolve_expression(expr_loc, cont_type, e->ref);
670 if (result.type && is_array(result.type))
672 struct expression_type index_result;
673 result.type = type_array_get_element_type(result.type);
674 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
675 if (!index_result.type || !is_integer_type(index_result.type))
676 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
677 expr_loc->attr ? " for attribute " : "",
678 expr_loc->attr ? expr_loc->attr : "");
680 else
681 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
682 expr_loc->attr ? " for attribute " : "",
683 expr_loc->attr ? expr_loc->attr : "");
684 break;
686 return result;
689 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
691 struct expression_type expr_type;
692 expr_type = resolve_expression(expr_loc, cont_type, expr);
693 return expr_type.type;
696 void write_expr(FILE *h, const expr_t *e, int brackets,
697 int toplevel, const char *toplevel_prefix,
698 const type_t *cont_type, const char *local_var_prefix)
700 switch (e->type)
702 case EXPR_VOID:
703 break;
704 case EXPR_NUM:
705 fprintf(h, "%u", e->u.lval);
706 break;
707 case EXPR_HEXNUM:
708 fprintf(h, "0x%x", e->u.lval);
709 break;
710 case EXPR_DOUBLE:
711 fprintf(h, "%#.15g", e->u.dval);
712 break;
713 case EXPR_TRUEFALSE:
714 if (e->u.lval == 0)
715 fprintf(h, "FALSE");
716 else
717 fprintf(h, "TRUE");
718 break;
719 case EXPR_IDENTIFIER:
720 if (toplevel && toplevel_prefix && cont_type)
722 int found_in_cont_type;
723 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
724 if (found_in_cont_type)
726 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
727 break;
730 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
731 break;
732 case EXPR_STRLIT:
733 fprintf(h, "\"%s\"", e->u.sval);
734 break;
735 case EXPR_WSTRLIT:
736 fprintf(h, "L\"%s\"", e->u.sval);
737 break;
738 case EXPR_CHARCONST:
739 fprintf(h, "'%s'", e->u.sval);
740 break;
741 case EXPR_LOGNOT:
742 fprintf(h, "!");
743 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
744 break;
745 case EXPR_NOT:
746 fprintf(h, "~");
747 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
748 break;
749 case EXPR_POS:
750 fprintf(h, "+");
751 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
752 break;
753 case EXPR_NEG:
754 fprintf(h, "-");
755 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
756 break;
757 case EXPR_ADDRESSOF:
758 fprintf(h, "&");
759 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
760 break;
761 case EXPR_PPTR:
762 fprintf(h, "*");
763 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
764 break;
765 case EXPR_CAST:
766 fprintf(h, "(");
767 write_type_decl(h, &e->u.tref, NULL);
768 fprintf(h, ")");
769 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
770 break;
771 case EXPR_SIZEOF:
772 fprintf(h, "sizeof(");
773 write_type_decl(h, &e->u.tref, NULL);
774 fprintf(h, ")");
775 break;
776 case EXPR_SHL:
777 case EXPR_SHR:
778 case EXPR_MOD:
779 case EXPR_MUL:
780 case EXPR_DIV:
781 case EXPR_ADD:
782 case EXPR_SUB:
783 case EXPR_AND:
784 case EXPR_OR:
785 case EXPR_LOGOR:
786 case EXPR_LOGAND:
787 case EXPR_XOR:
788 case EXPR_EQUALITY:
789 case EXPR_INEQUALITY:
790 case EXPR_GTR:
791 case EXPR_LESS:
792 case EXPR_GTREQL:
793 case EXPR_LESSEQL:
794 if (brackets) fprintf(h, "(");
795 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
796 switch (e->type)
798 case EXPR_SHL: fprintf(h, " << "); break;
799 case EXPR_SHR: fprintf(h, " >> "); break;
800 case EXPR_MOD: fprintf(h, " %% "); break;
801 case EXPR_MUL: fprintf(h, " * "); break;
802 case EXPR_DIV: fprintf(h, " / "); break;
803 case EXPR_ADD: fprintf(h, " + "); break;
804 case EXPR_SUB: fprintf(h, " - "); break;
805 case EXPR_AND: fprintf(h, " & "); break;
806 case EXPR_OR: fprintf(h, " | "); break;
807 case EXPR_LOGOR: fprintf(h, " || "); break;
808 case EXPR_LOGAND: fprintf(h, " && "); break;
809 case EXPR_XOR: fprintf(h, " ^ "); break;
810 case EXPR_EQUALITY: fprintf(h, " == "); break;
811 case EXPR_INEQUALITY: fprintf(h, " != "); break;
812 case EXPR_GTR: fprintf(h, " > "); break;
813 case EXPR_LESS: fprintf(h, " < "); break;
814 case EXPR_GTREQL: fprintf(h, " >= "); break;
815 case EXPR_LESSEQL: fprintf(h, " <= "); break;
816 default: break;
818 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
819 if (brackets) fprintf(h, ")");
820 break;
821 case EXPR_MEMBER:
822 if (brackets) fprintf(h, "(");
823 if (e->ref->type == EXPR_PPTR)
825 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
826 fprintf(h, "->");
828 else
830 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
831 fprintf(h, ".");
833 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
834 if (brackets) fprintf(h, ")");
835 break;
836 case EXPR_COND:
837 if (brackets) fprintf(h, "(");
838 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
839 fprintf(h, " ? ");
840 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
841 fprintf(h, " : ");
842 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
843 if (brackets) fprintf(h, ")");
844 break;
845 case EXPR_ARRAY:
846 if (brackets) fprintf(h, "(");
847 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
848 fprintf(h, "[");
849 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
850 fprintf(h, "]");
851 if (brackets) fprintf(h, ")");
852 break;
856 /* This is actually fairly involved to implement precisely, due to the
857 effects attributes may have and things like that. Right now this is
858 only used for optimization, so just check for a very small set of
859 criteria that guarantee the types are equivalent; assume every thing
860 else is different. */
861 static int compare_type(const type_t *a, const type_t *b)
863 if (a == b
864 || (a->name
865 && b->name
866 && strcmp(a->name, b->name) == 0))
867 return 0;
868 /* Ordering doesn't need to be implemented yet. */
869 return 1;
872 int compare_expr(const expr_t *a, const expr_t *b)
874 int ret;
876 if (a->type != b->type)
877 return a->type - b->type;
879 switch (a->type)
881 case EXPR_NUM:
882 case EXPR_HEXNUM:
883 case EXPR_TRUEFALSE:
884 return a->u.lval - b->u.lval;
885 case EXPR_DOUBLE:
886 return a->u.dval - b->u.dval;
887 case EXPR_IDENTIFIER:
888 case EXPR_STRLIT:
889 case EXPR_WSTRLIT:
890 case EXPR_CHARCONST:
891 return strcmp(a->u.sval, b->u.sval);
892 case EXPR_COND:
893 ret = compare_expr(a->ref, b->ref);
894 if (ret != 0)
895 return ret;
896 ret = compare_expr(a->u.ext, b->u.ext);
897 if (ret != 0)
898 return ret;
899 return compare_expr(a->ext2, b->ext2);
900 case EXPR_OR:
901 case EXPR_AND:
902 case EXPR_ADD:
903 case EXPR_SUB:
904 case EXPR_MOD:
905 case EXPR_MUL:
906 case EXPR_DIV:
907 case EXPR_SHL:
908 case EXPR_SHR:
909 case EXPR_MEMBER:
910 case EXPR_ARRAY:
911 case EXPR_LOGOR:
912 case EXPR_LOGAND:
913 case EXPR_XOR:
914 case EXPR_EQUALITY:
915 case EXPR_INEQUALITY:
916 case EXPR_GTR:
917 case EXPR_LESS:
918 case EXPR_GTREQL:
919 case EXPR_LESSEQL:
920 ret = compare_expr(a->ref, b->ref);
921 if (ret != 0)
922 return ret;
923 return compare_expr(a->u.ext, b->u.ext);
924 case EXPR_CAST:
925 ret = compare_type(a->u.tref.type, b->u.tref.type);
926 if (ret != 0)
927 return ret;
928 /* Fall through. */
929 case EXPR_NOT:
930 case EXPR_NEG:
931 case EXPR_PPTR:
932 case EXPR_ADDRESSOF:
933 case EXPR_LOGNOT:
934 case EXPR_POS:
935 return compare_expr(a->ref, b->ref);
936 case EXPR_SIZEOF:
937 return compare_type(a->u.tref.type, b->u.tref.type);
938 case EXPR_VOID:
939 return 0;
941 return -1;