widl: Long constants must be 32-bit on all platforms.
[wine/hacks.git] / tools / widl / expr.c
blob0b3b5a84758129754b59e5e47ff42700f6330b25
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_CHAR:
54 case TYPE_BASIC_HYPER:
55 case TYPE_BASIC_BYTE:
56 case TYPE_BASIC_WCHAR:
57 case TYPE_BASIC_ERROR_STATUS_T:
58 return TRUE;
59 case TYPE_BASIC_FLOAT:
60 case TYPE_BASIC_DOUBLE:
61 case TYPE_BASIC_HANDLE:
62 return FALSE;
64 return FALSE;
65 default:
66 return FALSE;
70 static int is_signed_integer_type(const type_t *type)
72 switch (type_get_type(type))
74 case TYPE_ENUM:
75 return FALSE;
76 case TYPE_BASIC:
77 switch (type_basic_get_type(type))
79 case TYPE_BASIC_INT8:
80 case TYPE_BASIC_INT16:
81 case TYPE_BASIC_INT32:
82 case TYPE_BASIC_INT64:
83 case TYPE_BASIC_INT:
84 case TYPE_BASIC_INT3264:
85 return type_basic_get_sign(type) < 0;
86 case TYPE_BASIC_CHAR:
87 return TRUE;
88 case TYPE_BASIC_HYPER:
89 case TYPE_BASIC_BYTE:
90 case TYPE_BASIC_WCHAR:
91 case TYPE_BASIC_ERROR_STATUS_T:
92 case TYPE_BASIC_FLOAT:
93 case TYPE_BASIC_DOUBLE:
94 case TYPE_BASIC_HANDLE:
95 return FALSE;
97 default:
98 return FALSE;
102 static int is_float_type(const type_t *type)
104 return (type_get_type(type) == TYPE_BASIC &&
105 (type_basic_get_type(type) == TYPE_BASIC_FLOAT ||
106 type_basic_get_type(type) == TYPE_BASIC_DOUBLE));
109 expr_t *make_expr(enum expr_type type)
111 expr_t *e = xmalloc(sizeof(expr_t));
112 e->type = type;
113 e->ref = NULL;
114 e->u.lval = 0;
115 e->is_const = FALSE;
116 e->cval = 0;
117 return e;
120 expr_t *make_exprl(enum expr_type type, int val)
122 expr_t *e = xmalloc(sizeof(expr_t));
123 e->type = type;
124 e->ref = NULL;
125 e->u.lval = val;
126 e->is_const = FALSE;
127 /* check for numeric constant */
128 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
130 /* make sure true/false value is valid */
131 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
132 e->is_const = TRUE;
133 e->cval = val;
135 return e;
138 expr_t *make_exprd(enum expr_type type, double val)
140 expr_t *e = xmalloc(sizeof(expr_t));
141 e->type = type;
142 e->ref = NULL;
143 e->u.dval = val;
144 e->is_const = TRUE;
145 e->cval = val;
146 return e;
149 expr_t *make_exprs(enum expr_type type, char *val)
151 expr_t *e;
152 e = xmalloc(sizeof(expr_t));
153 e->type = type;
154 e->ref = NULL;
155 e->u.sval = val;
156 e->is_const = FALSE;
157 /* check for predefined constants */
158 switch (type)
160 case EXPR_IDENTIFIER:
162 var_t *c = find_const(val, 0);
163 if (c)
165 e->u.sval = c->name;
166 free(val);
167 e->is_const = TRUE;
168 e->cval = c->eval->cval;
170 break;
172 case EXPR_CHARCONST:
173 if (!val[0])
174 error_loc("empty character constant\n");
175 else if (val[1])
176 error_loc("multi-character constants are endian dependent\n");
177 else
179 e->is_const = TRUE;
180 e->cval = *val;
182 break;
183 default:
184 break;
186 return e;
189 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
191 expr_t *e;
192 type_t *tref;
194 if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
195 error_loc("invalid storage class for type expression\n");
197 tref = var->type;
199 e = xmalloc(sizeof(expr_t));
200 e->type = type;
201 e->ref = expr;
202 e->u.tref = tref;
203 e->is_const = FALSE;
204 if (type == EXPR_SIZEOF)
206 /* only do this for types that should be the same on all platforms */
207 if (is_integer_type(tref) || is_float_type(tref))
209 unsigned int align = 0;
210 e->is_const = TRUE;
211 e->cval = type_memsize(tref, &align);
214 /* check for cast of constant expression */
215 if (type == EXPR_CAST && expr->is_const)
217 if (is_integer_type(tref))
219 unsigned int align = 0;
220 unsigned int cast_type_bits = type_memsize(tref, &align) * 8;
221 unsigned int cast_mask;
223 e->is_const = TRUE;
224 if (is_signed_integer_type(tref))
226 cast_mask = (1 << (cast_type_bits - 1)) - 1;
227 if (expr->cval & (1 << (cast_type_bits - 1)))
228 e->cval = -((-expr->cval) & cast_mask);
229 else
230 e->cval = expr->cval & cast_mask;
232 else
234 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
235 cast_mask = ((1 << (cast_type_bits - 1)) - 1) |
236 1 << (cast_type_bits - 1);
237 e->cval = expr->cval & cast_mask;
240 else
242 e->is_const = TRUE;
243 e->cval = expr->cval;
246 free(var);
247 return e;
250 expr_t *make_expr1(enum expr_type type, expr_t *expr)
252 expr_t *e;
253 e = xmalloc(sizeof(expr_t));
254 e->type = type;
255 e->ref = expr;
256 e->u.lval = 0;
257 e->is_const = FALSE;
258 /* check for compile-time optimization */
259 if (expr->is_const)
261 e->is_const = TRUE;
262 switch (type)
264 case EXPR_LOGNOT:
265 e->cval = !expr->cval;
266 break;
267 case EXPR_POS:
268 e->cval = +expr->cval;
269 break;
270 case EXPR_NEG:
271 e->cval = -expr->cval;
272 break;
273 case EXPR_NOT:
274 e->cval = ~expr->cval;
275 break;
276 default:
277 e->is_const = FALSE;
278 break;
281 return e;
284 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
286 expr_t *e;
287 e = xmalloc(sizeof(expr_t));
288 e->type = type;
289 e->ref = expr1;
290 e->u.ext = expr2;
291 e->is_const = FALSE;
292 /* check for compile-time optimization */
293 if (expr1->is_const && expr2->is_const)
295 e->is_const = TRUE;
296 switch (type)
298 case EXPR_ADD:
299 e->cval = expr1->cval + expr2->cval;
300 break;
301 case EXPR_SUB:
302 e->cval = expr1->cval - expr2->cval;
303 break;
304 case EXPR_MOD:
305 if (expr2->cval == 0)
307 error_loc("divide by zero in expression\n");
308 e->cval = 0;
310 else
311 e->cval = expr1->cval % expr2->cval;
312 break;
313 case EXPR_MUL:
314 e->cval = expr1->cval * expr2->cval;
315 break;
316 case EXPR_DIV:
317 if (expr2->cval == 0)
319 error_loc("divide by zero in expression\n");
320 e->cval = 0;
322 else
323 e->cval = expr1->cval / expr2->cval;
324 break;
325 case EXPR_OR:
326 e->cval = expr1->cval | expr2->cval;
327 break;
328 case EXPR_AND:
329 e->cval = expr1->cval & expr2->cval;
330 break;
331 case EXPR_SHL:
332 e->cval = expr1->cval << expr2->cval;
333 break;
334 case EXPR_SHR:
335 e->cval = expr1->cval >> expr2->cval;
336 break;
337 case EXPR_LOGOR:
338 e->cval = expr1->cval || expr2->cval;
339 break;
340 case EXPR_LOGAND:
341 e->cval = expr1->cval && expr2->cval;
342 break;
343 case EXPR_XOR:
344 e->cval = expr1->cval ^ expr2->cval;
345 break;
346 case EXPR_EQUALITY:
347 e->cval = expr1->cval == expr2->cval;
348 break;
349 case EXPR_INEQUALITY:
350 e->cval = expr1->cval != expr2->cval;
351 break;
352 case EXPR_GTR:
353 e->cval = expr1->cval > expr2->cval;
354 break;
355 case EXPR_LESS:
356 e->cval = expr1->cval < expr2->cval;
357 break;
358 case EXPR_GTREQL:
359 e->cval = expr1->cval >= expr2->cval;
360 break;
361 case EXPR_LESSEQL:
362 e->cval = expr1->cval <= expr2->cval;
363 break;
364 default:
365 e->is_const = FALSE;
366 break;
369 return e;
372 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
374 expr_t *e;
375 e = xmalloc(sizeof(expr_t));
376 e->type = type;
377 e->ref = expr1;
378 e->u.ext = expr2;
379 e->ext2 = expr3;
380 e->is_const = FALSE;
381 /* check for compile-time optimization */
382 if (expr1->is_const && expr2->is_const && expr3->is_const)
384 e->is_const = TRUE;
385 switch (type)
387 case EXPR_COND:
388 e->cval = expr1->cval ? expr2->cval : expr3->cval;
389 break;
390 default:
391 e->is_const = FALSE;
392 break;
395 return e;
398 struct expression_type
400 int is_variable; /* is the expression resolved to a variable? */
401 int is_temporary; /* should the type be freed? */
402 type_t *type;
405 static void check_scalar_type(const struct expr_loc *expr_loc,
406 const type_t *cont_type, const type_t *type)
408 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
409 !is_float_type(type)))
410 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
411 expr_loc->attr ? " for attribute " : "",
412 expr_loc->attr ? expr_loc->attr : "");
415 static void check_arithmetic_type(const struct expr_loc *expr_loc,
416 const type_t *cont_type, const type_t *type)
418 if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
419 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
420 expr_loc->attr ? " for attribute " : "",
421 expr_loc->attr ? expr_loc->attr : "");
424 static void check_integer_type(const struct expr_loc *expr_loc,
425 const type_t *cont_type, const type_t *type)
427 if (!cont_type || !is_integer_type(type))
428 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
429 expr_loc->attr ? " for attribute " : "",
430 expr_loc->attr ? expr_loc->attr : "");
433 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
435 type_t *type = NULL;
436 const var_t *field;
437 const var_list_t *fields = NULL;
439 *found_in_cont_type = 0;
441 if (cont_type)
443 switch (type_get_type(cont_type))
445 case TYPE_FUNCTION:
446 fields = type_function_get_args(cont_type);
447 break;
448 case TYPE_STRUCT:
449 fields = type_struct_get_fields(cont_type);
450 break;
451 case TYPE_UNION:
452 case TYPE_ENCAPSULATED_UNION:
453 fields = type_union_get_cases(cont_type);
454 break;
455 case TYPE_VOID:
456 case TYPE_BASIC:
457 case TYPE_ENUM:
458 case TYPE_MODULE:
459 case TYPE_COCLASS:
460 case TYPE_INTERFACE:
461 case TYPE_POINTER:
462 case TYPE_ARRAY:
463 case TYPE_BITFIELD:
464 /* nothing to do */
465 break;
466 case TYPE_ALIAS:
467 /* shouldn't get here because of using type_get_type above */
468 assert(0);
469 break;
473 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
474 if (field->name && !strcmp(identifier, field->name))
476 type = field->type;
477 *found_in_cont_type = 1;
478 break;
481 if (!type)
483 var_t *const_var = find_const(identifier, 0);
484 if (const_var) type = const_var->type;
487 return type;
490 static int is_valid_member_operand(const type_t *type)
492 switch (type_get_type(type))
494 case TYPE_STRUCT:
495 case TYPE_UNION:
496 case TYPE_ENUM:
497 return TRUE;
498 default:
499 return FALSE;
503 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
504 const type_t *cont_type,
505 const expr_t *e)
507 struct expression_type result;
508 result.is_variable = FALSE;
509 result.is_temporary = FALSE;
510 result.type = NULL;
511 switch (e->type)
513 case EXPR_VOID:
514 break;
515 case EXPR_HEXNUM:
516 case EXPR_NUM:
517 case EXPR_TRUEFALSE:
518 result.is_variable = FALSE;
519 result.is_temporary = FALSE;
520 result.type = type_new_int(TYPE_BASIC_INT, 0);
521 break;
522 case EXPR_STRLIT:
523 result.is_variable = FALSE;
524 result.is_temporary = TRUE;
525 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
526 break;
527 case EXPR_WSTRLIT:
528 result.is_variable = FALSE;
529 result.is_temporary = TRUE;
530 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
531 break;
532 case EXPR_CHARCONST:
533 result.is_variable = FALSE;
534 result.is_temporary = TRUE;
535 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
536 break;
537 case EXPR_DOUBLE:
538 result.is_variable = FALSE;
539 result.is_temporary = TRUE;
540 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
541 break;
542 case EXPR_IDENTIFIER:
544 int found_in_cont_type;
545 result.is_variable = TRUE;
546 result.is_temporary = FALSE;
547 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
548 if (!result.type)
550 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
551 e->u.sval, expr_loc->attr ? " for attribute " : "",
552 expr_loc->attr ? expr_loc->attr : "");
554 break;
556 case EXPR_LOGNOT:
557 result = resolve_expression(expr_loc, cont_type, e->ref);
558 check_scalar_type(expr_loc, cont_type, result.type);
559 result.is_variable = FALSE;
560 result.is_temporary = FALSE;
561 result.type = type_new_int(TYPE_BASIC_INT, 0);
562 break;
563 case EXPR_NOT:
564 result = resolve_expression(expr_loc, cont_type, e->ref);
565 check_integer_type(expr_loc, cont_type, result.type);
566 result.is_variable = FALSE;
567 break;
568 case EXPR_POS:
569 case EXPR_NEG:
570 result = resolve_expression(expr_loc, cont_type, e->ref);
571 check_arithmetic_type(expr_loc, cont_type, result.type);
572 result.is_variable = FALSE;
573 break;
574 case EXPR_ADDRESSOF:
575 result = resolve_expression(expr_loc, cont_type, e->ref);
576 if (!result.is_variable)
577 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
578 expr_loc->attr ? " for attribute " : "",
579 expr_loc->attr ? expr_loc->attr : "");
580 result.is_variable = FALSE;
581 result.is_temporary = TRUE;
582 result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
583 break;
584 case EXPR_PPTR:
585 result = resolve_expression(expr_loc, cont_type, e->ref);
586 if (result.type && is_ptr(result.type))
587 result.type = type_pointer_get_ref(result.type);
588 else if(result.type && is_array(result.type)
589 && type_array_is_decl_as_ptr(result.type))
590 result.type = type_array_get_element(result.type);
591 else
592 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
593 expr_loc->attr ? " for attribute " : "",
594 expr_loc->attr ? expr_loc->attr : "");
595 break;
596 case EXPR_CAST:
597 result = resolve_expression(expr_loc, cont_type, e->ref);
598 result.type = e->u.tref;
599 break;
600 case EXPR_SIZEOF:
601 result.is_variable = FALSE;
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_variable = FALSE;
640 result.is_temporary = FALSE;
641 result.type = type_new_int(TYPE_BASIC_INT, 0);
642 break;
644 case EXPR_MEMBER:
645 result = resolve_expression(expr_loc, cont_type, e->ref);
646 if (result.type && is_valid_member_operand(result.type))
647 result = resolve_expression(expr_loc, result.type, e->u.ext);
648 else
649 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",
650 expr_loc->attr ? " for attribute " : "",
651 expr_loc->attr ? expr_loc->attr : "");
652 break;
653 case EXPR_COND:
655 struct expression_type result_first, result_second, result_third;
656 result_first = resolve_expression(expr_loc, cont_type, e->ref);
657 check_scalar_type(expr_loc, cont_type, result_first.type);
658 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
659 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
660 /* FIXME: determine the correct return type */
661 result = result_second;
662 result.is_variable = FALSE;
663 break;
665 case EXPR_ARRAY:
666 result = resolve_expression(expr_loc, cont_type, e->ref);
667 if (result.type && is_array(result.type))
669 struct expression_type index_result;
670 result.type = type_array_get_element(result.type);
671 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
672 if (!index_result.type || !is_integer_type(index_result.type))
673 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
674 expr_loc->attr ? " for attribute " : "",
675 expr_loc->attr ? expr_loc->attr : "");
677 else
678 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
679 expr_loc->attr ? " for attribute " : "",
680 expr_loc->attr ? expr_loc->attr : "");
681 break;
683 return result;
686 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
688 struct expression_type expr_type;
689 expr_type = resolve_expression(expr_loc, cont_type, expr);
690 return expr_type.type;
693 void write_expr(FILE *h, const expr_t *e, int brackets,
694 int toplevel, const char *toplevel_prefix,
695 const type_t *cont_type, const char *local_var_prefix)
697 switch (e->type)
699 case EXPR_VOID:
700 break;
701 case EXPR_NUM:
702 fprintf(h, "%u", e->u.lval);
703 break;
704 case EXPR_HEXNUM:
705 fprintf(h, "0x%x", e->u.lval);
706 break;
707 case EXPR_DOUBLE:
708 fprintf(h, "%#.15g", e->u.dval);
709 break;
710 case EXPR_TRUEFALSE:
711 if (e->u.lval == 0)
712 fprintf(h, "FALSE");
713 else
714 fprintf(h, "TRUE");
715 break;
716 case EXPR_IDENTIFIER:
717 if (toplevel && toplevel_prefix && cont_type)
719 int found_in_cont_type;
720 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
721 if (found_in_cont_type)
723 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
724 break;
727 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
728 break;
729 case EXPR_STRLIT:
730 fprintf(h, "\"%s\"", e->u.sval);
731 break;
732 case EXPR_WSTRLIT:
733 fprintf(h, "L\"%s\"", e->u.sval);
734 break;
735 case EXPR_CHARCONST:
736 fprintf(h, "'%s'", e->u.sval);
737 break;
738 case EXPR_LOGNOT:
739 fprintf(h, "!");
740 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
741 break;
742 case EXPR_NOT:
743 fprintf(h, "~");
744 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
745 break;
746 case EXPR_POS:
747 fprintf(h, "+");
748 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
749 break;
750 case EXPR_NEG:
751 fprintf(h, "-");
752 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
753 break;
754 case EXPR_ADDRESSOF:
755 fprintf(h, "&");
756 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
757 break;
758 case EXPR_PPTR:
759 fprintf(h, "*");
760 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
761 break;
762 case EXPR_CAST:
763 fprintf(h, "(");
764 write_type_decl(h, e->u.tref, NULL);
765 fprintf(h, ")");
766 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
767 break;
768 case EXPR_SIZEOF:
769 fprintf(h, "sizeof(");
770 write_type_decl(h, e->u.tref, NULL);
771 fprintf(h, ")");
772 break;
773 case EXPR_SHL:
774 case EXPR_SHR:
775 case EXPR_MOD:
776 case EXPR_MUL:
777 case EXPR_DIV:
778 case EXPR_ADD:
779 case EXPR_SUB:
780 case EXPR_AND:
781 case EXPR_OR:
782 case EXPR_LOGOR:
783 case EXPR_LOGAND:
784 case EXPR_XOR:
785 case EXPR_EQUALITY:
786 case EXPR_INEQUALITY:
787 case EXPR_GTR:
788 case EXPR_LESS:
789 case EXPR_GTREQL:
790 case EXPR_LESSEQL:
791 if (brackets) fprintf(h, "(");
792 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
793 switch (e->type)
795 case EXPR_SHL: fprintf(h, " << "); break;
796 case EXPR_SHR: fprintf(h, " >> "); break;
797 case EXPR_MOD: fprintf(h, " %% "); break;
798 case EXPR_MUL: fprintf(h, " * "); break;
799 case EXPR_DIV: fprintf(h, " / "); break;
800 case EXPR_ADD: fprintf(h, " + "); break;
801 case EXPR_SUB: fprintf(h, " - "); break;
802 case EXPR_AND: fprintf(h, " & "); break;
803 case EXPR_OR: fprintf(h, " | "); break;
804 case EXPR_LOGOR: fprintf(h, " || "); break;
805 case EXPR_LOGAND: fprintf(h, " && "); break;
806 case EXPR_XOR: fprintf(h, " ^ "); break;
807 case EXPR_EQUALITY: fprintf(h, " == "); break;
808 case EXPR_INEQUALITY: fprintf(h, " != "); break;
809 case EXPR_GTR: fprintf(h, " > "); break;
810 case EXPR_LESS: fprintf(h, " < "); break;
811 case EXPR_GTREQL: fprintf(h, " >= "); break;
812 case EXPR_LESSEQL: fprintf(h, " <= "); break;
813 default: break;
815 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
816 if (brackets) fprintf(h, ")");
817 break;
818 case EXPR_MEMBER:
819 if (brackets) fprintf(h, "(");
820 if (e->ref->type == EXPR_PPTR)
822 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
823 fprintf(h, "->");
825 else
827 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
828 fprintf(h, ".");
830 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
831 if (brackets) fprintf(h, ")");
832 break;
833 case EXPR_COND:
834 if (brackets) fprintf(h, "(");
835 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
836 fprintf(h, " ? ");
837 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
838 fprintf(h, " : ");
839 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
840 if (brackets) fprintf(h, ")");
841 break;
842 case EXPR_ARRAY:
843 if (brackets) fprintf(h, "(");
844 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
845 fprintf(h, "[");
846 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
847 fprintf(h, "]");
848 if (brackets) fprintf(h, ")");
849 break;
853 /* This is actually fairly involved to implement precisely, due to the
854 effects attributes may have and things like that. Right now this is
855 only used for optimization, so just check for a very small set of
856 criteria that guarantee the types are equivalent; assume every thing
857 else is different. */
858 static int compare_type(const type_t *a, const type_t *b)
860 if (a == b
861 || (a->name
862 && b->name
863 && strcmp(a->name, b->name) == 0))
864 return 0;
865 /* Ordering doesn't need to be implemented yet. */
866 return 1;
869 int compare_expr(const expr_t *a, const expr_t *b)
871 int ret;
873 if (a->type != b->type)
874 return a->type - b->type;
876 switch (a->type)
878 case EXPR_NUM:
879 case EXPR_HEXNUM:
880 case EXPR_TRUEFALSE:
881 return a->u.lval - b->u.lval;
882 case EXPR_DOUBLE:
883 return a->u.dval - b->u.dval;
884 case EXPR_IDENTIFIER:
885 case EXPR_STRLIT:
886 case EXPR_WSTRLIT:
887 case EXPR_CHARCONST:
888 return strcmp(a->u.sval, b->u.sval);
889 case EXPR_COND:
890 ret = compare_expr(a->ref, b->ref);
891 if (ret != 0)
892 return ret;
893 ret = compare_expr(a->u.ext, b->u.ext);
894 if (ret != 0)
895 return ret;
896 return compare_expr(a->ext2, b->ext2);
897 case EXPR_OR:
898 case EXPR_AND:
899 case EXPR_ADD:
900 case EXPR_SUB:
901 case EXPR_MOD:
902 case EXPR_MUL:
903 case EXPR_DIV:
904 case EXPR_SHL:
905 case EXPR_SHR:
906 case EXPR_MEMBER:
907 case EXPR_ARRAY:
908 case EXPR_LOGOR:
909 case EXPR_LOGAND:
910 case EXPR_XOR:
911 case EXPR_EQUALITY:
912 case EXPR_INEQUALITY:
913 case EXPR_GTR:
914 case EXPR_LESS:
915 case EXPR_GTREQL:
916 case EXPR_LESSEQL:
917 ret = compare_expr(a->ref, b->ref);
918 if (ret != 0)
919 return ret;
920 return compare_expr(a->u.ext, b->u.ext);
921 case EXPR_CAST:
922 ret = compare_type(a->u.tref, b->u.tref);
923 if (ret != 0)
924 return ret;
925 /* Fall through. */
926 case EXPR_NOT:
927 case EXPR_NEG:
928 case EXPR_PPTR:
929 case EXPR_ADDRESSOF:
930 case EXPR_LOGNOT:
931 case EXPR_POS:
932 return compare_expr(a->ref, b->ref);
933 case EXPR_SIZEOF:
934 return compare_type(a->u.tref, b->u.tref);
935 case EXPR_VOID:
936 return 0;
938 return -1;