msvcrt/tests: Add more tests for setlocale().
[wine/hacks.git] / tools / widl / expr.c
blob8511ce56613a02152355bd521c99b5ce17bb48d5
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 e->is_const = TRUE;
210 e->cval = type_memsize(tref);
213 /* check for cast of constant expression */
214 if (type == EXPR_CAST && expr->is_const)
216 if (is_integer_type(tref))
218 unsigned int cast_type_bits = type_memsize(tref) * 8;
219 unsigned int cast_mask;
221 e->is_const = TRUE;
222 if (is_signed_integer_type(tref))
224 cast_mask = (1 << (cast_type_bits - 1)) - 1;
225 if (expr->cval & (1 << (cast_type_bits - 1)))
226 e->cval = -((-expr->cval) & cast_mask);
227 else
228 e->cval = expr->cval & cast_mask;
230 else
232 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
233 cast_mask = ((1 << (cast_type_bits - 1)) - 1) |
234 1 << (cast_type_bits - 1);
235 e->cval = expr->cval & cast_mask;
238 else
240 e->is_const = TRUE;
241 e->cval = expr->cval;
244 free(var);
245 return e;
248 expr_t *make_expr1(enum expr_type type, expr_t *expr)
250 expr_t *e;
251 e = xmalloc(sizeof(expr_t));
252 e->type = type;
253 e->ref = expr;
254 e->u.lval = 0;
255 e->is_const = FALSE;
256 /* check for compile-time optimization */
257 if (expr->is_const)
259 e->is_const = TRUE;
260 switch (type)
262 case EXPR_LOGNOT:
263 e->cval = !expr->cval;
264 break;
265 case EXPR_POS:
266 e->cval = +expr->cval;
267 break;
268 case EXPR_NEG:
269 e->cval = -expr->cval;
270 break;
271 case EXPR_NOT:
272 e->cval = ~expr->cval;
273 break;
274 default:
275 e->is_const = FALSE;
276 break;
279 return e;
282 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
284 expr_t *e;
285 e = xmalloc(sizeof(expr_t));
286 e->type = type;
287 e->ref = expr1;
288 e->u.ext = expr2;
289 e->is_const = FALSE;
290 /* check for compile-time optimization */
291 if (expr1->is_const && expr2->is_const)
293 e->is_const = TRUE;
294 switch (type)
296 case EXPR_ADD:
297 e->cval = expr1->cval + expr2->cval;
298 break;
299 case EXPR_SUB:
300 e->cval = expr1->cval - expr2->cval;
301 break;
302 case EXPR_MOD:
303 if (expr2->cval == 0)
305 error_loc("divide by zero in expression\n");
306 e->cval = 0;
308 else
309 e->cval = expr1->cval % expr2->cval;
310 break;
311 case EXPR_MUL:
312 e->cval = expr1->cval * expr2->cval;
313 break;
314 case EXPR_DIV:
315 if (expr2->cval == 0)
317 error_loc("divide by zero in expression\n");
318 e->cval = 0;
320 else
321 e->cval = expr1->cval / expr2->cval;
322 break;
323 case EXPR_OR:
324 e->cval = expr1->cval | expr2->cval;
325 break;
326 case EXPR_AND:
327 e->cval = expr1->cval & expr2->cval;
328 break;
329 case EXPR_SHL:
330 e->cval = expr1->cval << expr2->cval;
331 break;
332 case EXPR_SHR:
333 e->cval = expr1->cval >> expr2->cval;
334 break;
335 case EXPR_LOGOR:
336 e->cval = expr1->cval || expr2->cval;
337 break;
338 case EXPR_LOGAND:
339 e->cval = expr1->cval && expr2->cval;
340 break;
341 case EXPR_XOR:
342 e->cval = expr1->cval ^ expr2->cval;
343 break;
344 case EXPR_EQUALITY:
345 e->cval = expr1->cval == expr2->cval;
346 break;
347 case EXPR_INEQUALITY:
348 e->cval = expr1->cval != expr2->cval;
349 break;
350 case EXPR_GTR:
351 e->cval = expr1->cval > expr2->cval;
352 break;
353 case EXPR_LESS:
354 e->cval = expr1->cval < expr2->cval;
355 break;
356 case EXPR_GTREQL:
357 e->cval = expr1->cval >= expr2->cval;
358 break;
359 case EXPR_LESSEQL:
360 e->cval = expr1->cval <= expr2->cval;
361 break;
362 default:
363 e->is_const = FALSE;
364 break;
367 return e;
370 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
372 expr_t *e;
373 e = xmalloc(sizeof(expr_t));
374 e->type = type;
375 e->ref = expr1;
376 e->u.ext = expr2;
377 e->ext2 = expr3;
378 e->is_const = FALSE;
379 /* check for compile-time optimization */
380 if (expr1->is_const && expr2->is_const && expr3->is_const)
382 e->is_const = TRUE;
383 switch (type)
385 case EXPR_COND:
386 e->cval = expr1->cval ? expr2->cval : expr3->cval;
387 break;
388 default:
389 e->is_const = FALSE;
390 break;
393 return e;
396 struct expression_type
398 int is_variable; /* is the expression resolved to a variable? */
399 int is_temporary; /* should the type be freed? */
400 type_t *type;
403 static void check_scalar_type(const struct expr_loc *expr_loc,
404 const type_t *cont_type, const type_t *type)
406 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
407 !is_float_type(type)))
408 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
409 expr_loc->attr ? " for attribute " : "",
410 expr_loc->attr ? expr_loc->attr : "");
413 static void check_arithmetic_type(const struct expr_loc *expr_loc,
414 const type_t *cont_type, const type_t *type)
416 if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
417 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
418 expr_loc->attr ? " for attribute " : "",
419 expr_loc->attr ? expr_loc->attr : "");
422 static void check_integer_type(const struct expr_loc *expr_loc,
423 const type_t *cont_type, const type_t *type)
425 if (!cont_type || !is_integer_type(type))
426 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
427 expr_loc->attr ? " for attribute " : "",
428 expr_loc->attr ? expr_loc->attr : "");
431 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
433 type_t *type = NULL;
434 const var_t *field;
435 const var_list_t *fields = NULL;
437 *found_in_cont_type = 0;
439 if (cont_type)
441 switch (type_get_type(cont_type))
443 case TYPE_FUNCTION:
444 fields = type_function_get_args(cont_type);
445 break;
446 case TYPE_STRUCT:
447 fields = type_struct_get_fields(cont_type);
448 break;
449 case TYPE_UNION:
450 case TYPE_ENCAPSULATED_UNION:
451 fields = type_union_get_cases(cont_type);
452 break;
453 case TYPE_VOID:
454 case TYPE_BASIC:
455 case TYPE_ENUM:
456 case TYPE_MODULE:
457 case TYPE_COCLASS:
458 case TYPE_INTERFACE:
459 case TYPE_POINTER:
460 case TYPE_ARRAY:
461 case TYPE_BITFIELD:
462 /* nothing to do */
463 break;
464 case TYPE_ALIAS:
465 /* shouldn't get here because of using type_get_type above */
466 assert(0);
467 break;
471 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
472 if (field->name && !strcmp(identifier, field->name))
474 type = field->type;
475 *found_in_cont_type = 1;
476 break;
479 if (!type)
481 var_t *const_var = find_const(identifier, 0);
482 if (const_var) type = const_var->type;
485 return type;
488 static int is_valid_member_operand(const type_t *type)
490 switch (type_get_type(type))
492 case TYPE_STRUCT:
493 case TYPE_UNION:
494 case TYPE_ENUM:
495 return TRUE;
496 default:
497 return FALSE;
501 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
502 const type_t *cont_type,
503 const expr_t *e)
505 struct expression_type result;
506 result.is_variable = FALSE;
507 result.is_temporary = FALSE;
508 result.type = NULL;
509 switch (e->type)
511 case EXPR_VOID:
512 break;
513 case EXPR_HEXNUM:
514 case EXPR_NUM:
515 case EXPR_TRUEFALSE:
516 result.is_variable = FALSE;
517 result.is_temporary = FALSE;
518 result.type = type_new_int(TYPE_BASIC_INT, 0);
519 break;
520 case EXPR_STRLIT:
521 result.is_variable = FALSE;
522 result.is_temporary = TRUE;
523 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
524 break;
525 case EXPR_WSTRLIT:
526 result.is_variable = FALSE;
527 result.is_temporary = TRUE;
528 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
529 break;
530 case EXPR_CHARCONST:
531 result.is_variable = FALSE;
532 result.is_temporary = TRUE;
533 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
534 break;
535 case EXPR_DOUBLE:
536 result.is_variable = FALSE;
537 result.is_temporary = TRUE;
538 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
539 break;
540 case EXPR_IDENTIFIER:
542 int found_in_cont_type;
543 result.is_variable = TRUE;
544 result.is_temporary = FALSE;
545 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
546 if (!result.type)
548 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
549 e->u.sval, expr_loc->attr ? " for attribute " : "",
550 expr_loc->attr ? expr_loc->attr : "");
552 break;
554 case EXPR_LOGNOT:
555 result = resolve_expression(expr_loc, cont_type, e->ref);
556 check_scalar_type(expr_loc, cont_type, result.type);
557 result.is_variable = FALSE;
558 result.is_temporary = FALSE;
559 result.type = type_new_int(TYPE_BASIC_INT, 0);
560 break;
561 case EXPR_NOT:
562 result = resolve_expression(expr_loc, cont_type, e->ref);
563 check_integer_type(expr_loc, cont_type, result.type);
564 result.is_variable = FALSE;
565 break;
566 case EXPR_POS:
567 case EXPR_NEG:
568 result = resolve_expression(expr_loc, cont_type, e->ref);
569 check_arithmetic_type(expr_loc, cont_type, result.type);
570 result.is_variable = FALSE;
571 break;
572 case EXPR_ADDRESSOF:
573 result = resolve_expression(expr_loc, cont_type, e->ref);
574 if (!result.is_variable)
575 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
576 expr_loc->attr ? " for attribute " : "",
577 expr_loc->attr ? expr_loc->attr : "");
578 result.is_variable = FALSE;
579 result.is_temporary = TRUE;
580 result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
581 break;
582 case EXPR_PPTR:
583 result = resolve_expression(expr_loc, cont_type, e->ref);
584 if (result.type && is_ptr(result.type))
585 result.type = type_pointer_get_ref(result.type);
586 else if(result.type && is_array(result.type)
587 && type_array_is_decl_as_ptr(result.type))
588 result.type = type_array_get_element(result.type);
589 else
590 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
591 expr_loc->attr ? " for attribute " : "",
592 expr_loc->attr ? expr_loc->attr : "");
593 break;
594 case EXPR_CAST:
595 result = resolve_expression(expr_loc, cont_type, e->ref);
596 result.type = e->u.tref;
597 break;
598 case EXPR_SIZEOF:
599 result.is_variable = FALSE;
600 result.is_temporary = FALSE;
601 result.type = type_new_int(TYPE_BASIC_INT, 0);
602 break;
603 case EXPR_SHL:
604 case EXPR_SHR:
605 case EXPR_MOD:
606 case EXPR_MUL:
607 case EXPR_DIV:
608 case EXPR_ADD:
609 case EXPR_SUB:
610 case EXPR_AND:
611 case EXPR_OR:
612 case EXPR_XOR:
614 struct expression_type result_right;
615 result = resolve_expression(expr_loc, cont_type, e->ref);
616 result.is_variable = FALSE;
617 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
618 /* FIXME: these checks aren't strict enough for some of the operators */
619 check_scalar_type(expr_loc, cont_type, result.type);
620 check_scalar_type(expr_loc, cont_type, result_right.type);
621 break;
623 case EXPR_LOGOR:
624 case EXPR_LOGAND:
625 case EXPR_EQUALITY:
626 case EXPR_INEQUALITY:
627 case EXPR_GTR:
628 case EXPR_LESS:
629 case EXPR_GTREQL:
630 case EXPR_LESSEQL:
632 struct expression_type result_left, result_right;
633 result_left = resolve_expression(expr_loc, cont_type, e->ref);
634 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
635 check_scalar_type(expr_loc, cont_type, result_left.type);
636 check_scalar_type(expr_loc, cont_type, result_right.type);
637 result.is_variable = FALSE;
638 result.is_temporary = FALSE;
639 result.type = type_new_int(TYPE_BASIC_INT, 0);
640 break;
642 case EXPR_MEMBER:
643 result = resolve_expression(expr_loc, cont_type, e->ref);
644 if (result.type && is_valid_member_operand(result.type))
645 result = resolve_expression(expr_loc, result.type, e->u.ext);
646 else
647 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",
648 expr_loc->attr ? " for attribute " : "",
649 expr_loc->attr ? expr_loc->attr : "");
650 break;
651 case EXPR_COND:
653 struct expression_type result_first, result_second, result_third;
654 result_first = resolve_expression(expr_loc, cont_type, e->ref);
655 check_scalar_type(expr_loc, cont_type, result_first.type);
656 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
657 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
658 /* FIXME: determine the correct return type */
659 result = result_second;
660 result.is_variable = FALSE;
661 break;
663 case EXPR_ARRAY:
664 result = resolve_expression(expr_loc, cont_type, e->ref);
665 if (result.type && is_array(result.type))
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 : "");
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;
681 return result;
684 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
686 struct expression_type expr_type;
687 expr_type = resolve_expression(expr_loc, cont_type, expr);
688 return expr_type.type;
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)
695 switch (e->type)
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)
717 int found_in_cont_type;
718 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
719 if (found_in_cont_type)
721 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
722 break;
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)
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;
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)
820 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
821 fprintf(h, "->");
823 else
825 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
826 fprintf(h, ".");
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;
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. */
856 static int compare_type(const type_t *a, const type_t *b)
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;
867 int compare_expr(const expr_t *a, const expr_t *b)
869 int ret;
871 if (a->type != b->type)
872 return a->type - b->type;
874 switch (a->type)
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;
936 return -1;