ntdll: Use wide-char string literals in version.c.
[wine.git] / tools / widl / expr.c
blobbe8311cfb7f64158a9a9f5ab2fa4bf94ca51dc2d
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 /* nothing to do */
467 break;
468 case TYPE_ALIAS:
469 /* shouldn't get here because of using type_get_type above */
470 assert(0);
471 break;
475 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
476 if (field->name && !strcmp(identifier, field->name))
478 type = field->declspec.type;
479 *found_in_cont_type = 1;
480 break;
483 if (!type)
485 var_t *const_var = find_const(identifier, 0);
486 if (const_var) type = const_var->declspec.type;
489 return type;
492 static int is_valid_member_operand(const type_t *type)
494 switch (type_get_type(type))
496 case TYPE_STRUCT:
497 case TYPE_UNION:
498 case TYPE_ENUM:
499 return TRUE;
500 default:
501 return FALSE;
505 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
506 const type_t *cont_type,
507 const expr_t *e)
509 struct expression_type result;
510 result.is_variable = FALSE;
511 result.is_temporary = FALSE;
512 result.type = NULL;
513 switch (e->type)
515 case EXPR_VOID:
516 break;
517 case EXPR_HEXNUM:
518 case EXPR_NUM:
519 case EXPR_TRUEFALSE:
520 result.is_temporary = FALSE;
521 result.type = type_new_int(TYPE_BASIC_INT, 0);
522 break;
523 case EXPR_STRLIT:
524 result.is_temporary = TRUE;
525 result.type = type_new_pointer(type_new_int(TYPE_BASIC_CHAR, 0));
526 break;
527 case EXPR_WSTRLIT:
528 result.is_temporary = TRUE;
529 result.type = type_new_pointer(type_new_int(TYPE_BASIC_WCHAR, 0));
530 break;
531 case EXPR_CHARCONST:
532 result.is_temporary = TRUE;
533 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
534 break;
535 case EXPR_DOUBLE:
536 result.is_temporary = TRUE;
537 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
538 break;
539 case EXPR_IDENTIFIER:
541 int found_in_cont_type;
542 result.is_variable = TRUE;
543 result.is_temporary = FALSE;
544 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
545 if (!result.type)
547 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
548 e->u.sval, expr_loc->attr ? " for attribute " : "",
549 expr_loc->attr ? expr_loc->attr : "");
551 break;
553 case EXPR_LOGNOT:
554 result = resolve_expression(expr_loc, cont_type, e->ref);
555 check_scalar_type(expr_loc, cont_type, result.type);
556 result.is_variable = FALSE;
557 result.is_temporary = FALSE;
558 result.type = type_new_int(TYPE_BASIC_INT, 0);
559 break;
560 case EXPR_NOT:
561 result = resolve_expression(expr_loc, cont_type, e->ref);
562 check_integer_type(expr_loc, cont_type, result.type);
563 result.is_variable = FALSE;
564 break;
565 case EXPR_POS:
566 case EXPR_NEG:
567 result = resolve_expression(expr_loc, cont_type, e->ref);
568 check_arithmetic_type(expr_loc, cont_type, result.type);
569 result.is_variable = FALSE;
570 break;
571 case EXPR_ADDRESSOF:
572 result = resolve_expression(expr_loc, cont_type, e->ref);
573 if (!result.is_variable)
574 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
575 expr_loc->attr ? " for attribute " : "",
576 expr_loc->attr ? expr_loc->attr : "");
577 result.is_variable = FALSE;
578 result.is_temporary = TRUE;
579 result.type = type_new_pointer(result.type);
580 break;
581 case EXPR_PPTR:
582 result = resolve_expression(expr_loc, cont_type, e->ref);
583 if (result.type && is_ptr(result.type))
584 result.type = type_pointer_get_ref_type(result.type);
585 else if(result.type && is_array(result.type)
586 && type_array_is_decl_as_ptr(result.type))
587 result.type = type_array_get_element_type(result.type);
588 else
589 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
590 expr_loc->attr ? " for attribute " : "",
591 expr_loc->attr ? expr_loc->attr : "");
592 break;
593 case EXPR_CAST:
594 result = resolve_expression(expr_loc, cont_type, e->ref);
595 result.type = e->u.tref.type;
596 break;
597 case EXPR_SIZEOF:
598 result.is_temporary = FALSE;
599 result.type = type_new_int(TYPE_BASIC_INT, 0);
600 break;
601 case EXPR_SHL:
602 case EXPR_SHR:
603 case EXPR_MOD:
604 case EXPR_MUL:
605 case EXPR_DIV:
606 case EXPR_ADD:
607 case EXPR_SUB:
608 case EXPR_AND:
609 case EXPR_OR:
610 case EXPR_XOR:
612 struct expression_type result_right;
613 result = resolve_expression(expr_loc, cont_type, e->ref);
614 result.is_variable = FALSE;
615 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
616 /* FIXME: these checks aren't strict enough for some of the operators */
617 check_scalar_type(expr_loc, cont_type, result.type);
618 check_scalar_type(expr_loc, cont_type, result_right.type);
619 break;
621 case EXPR_LOGOR:
622 case EXPR_LOGAND:
623 case EXPR_EQUALITY:
624 case EXPR_INEQUALITY:
625 case EXPR_GTR:
626 case EXPR_LESS:
627 case EXPR_GTREQL:
628 case EXPR_LESSEQL:
630 struct expression_type result_left, result_right;
631 result_left = resolve_expression(expr_loc, cont_type, e->ref);
632 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
633 check_scalar_type(expr_loc, cont_type, result_left.type);
634 check_scalar_type(expr_loc, cont_type, result_right.type);
635 result.is_temporary = FALSE;
636 result.type = type_new_int(TYPE_BASIC_INT, 0);
637 break;
639 case EXPR_MEMBER:
640 result = resolve_expression(expr_loc, cont_type, e->ref);
641 if (result.type && is_valid_member_operand(result.type))
642 result = resolve_expression(expr_loc, result.type, e->u.ext);
643 else
644 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",
645 expr_loc->attr ? " for attribute " : "",
646 expr_loc->attr ? expr_loc->attr : "");
647 break;
648 case EXPR_COND:
650 struct expression_type result_first, result_second, result_third;
651 result_first = resolve_expression(expr_loc, cont_type, e->ref);
652 check_scalar_type(expr_loc, cont_type, result_first.type);
653 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
654 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
655 check_scalar_type(expr_loc, cont_type, result_second.type);
656 check_scalar_type(expr_loc, cont_type, result_third.type);
657 if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type))
658 error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" );
659 /* FIXME: determine the correct return type */
660 result = result_second;
661 result.is_variable = FALSE;
662 break;
664 case EXPR_ARRAY:
665 result = resolve_expression(expr_loc, cont_type, e->ref);
666 if (result.type && is_array(result.type))
668 struct expression_type index_result;
669 result.type = type_array_get_element_type(result.type);
670 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
671 if (!index_result.type || !is_integer_type(index_result.type))
672 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
673 expr_loc->attr ? " for attribute " : "",
674 expr_loc->attr ? expr_loc->attr : "");
676 else
677 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
678 expr_loc->attr ? " for attribute " : "",
679 expr_loc->attr ? expr_loc->attr : "");
680 break;
682 return result;
685 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
687 struct expression_type expr_type;
688 expr_type = resolve_expression(expr_loc, cont_type, expr);
689 return expr_type.type;
692 void write_expr(FILE *h, const expr_t *e, int brackets,
693 int toplevel, const char *toplevel_prefix,
694 const type_t *cont_type, const char *local_var_prefix)
696 switch (e->type)
698 case EXPR_VOID:
699 break;
700 case EXPR_NUM:
701 fprintf(h, "%u", e->u.lval);
702 break;
703 case EXPR_HEXNUM:
704 fprintf(h, "0x%x", e->u.lval);
705 break;
706 case EXPR_DOUBLE:
707 fprintf(h, "%#.15g", e->u.dval);
708 break;
709 case EXPR_TRUEFALSE:
710 if (e->u.lval == 0)
711 fprintf(h, "FALSE");
712 else
713 fprintf(h, "TRUE");
714 break;
715 case EXPR_IDENTIFIER:
716 if (toplevel && toplevel_prefix && cont_type)
718 int found_in_cont_type;
719 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
720 if (found_in_cont_type)
722 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
723 break;
726 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
727 break;
728 case EXPR_STRLIT:
729 fprintf(h, "\"%s\"", e->u.sval);
730 break;
731 case EXPR_WSTRLIT:
732 fprintf(h, "L\"%s\"", e->u.sval);
733 break;
734 case EXPR_CHARCONST:
735 fprintf(h, "'%s'", e->u.sval);
736 break;
737 case EXPR_LOGNOT:
738 fprintf(h, "!");
739 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
740 break;
741 case EXPR_NOT:
742 fprintf(h, "~");
743 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
744 break;
745 case EXPR_POS:
746 fprintf(h, "+");
747 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
748 break;
749 case EXPR_NEG:
750 fprintf(h, "-");
751 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
752 break;
753 case EXPR_ADDRESSOF:
754 fprintf(h, "&");
755 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
756 break;
757 case EXPR_PPTR:
758 fprintf(h, "*");
759 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
760 break;
761 case EXPR_CAST:
762 fprintf(h, "(");
763 write_type_decl(h, &e->u.tref, NULL);
764 fprintf(h, ")");
765 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
766 break;
767 case EXPR_SIZEOF:
768 fprintf(h, "sizeof(");
769 write_type_decl(h, &e->u.tref, NULL);
770 fprintf(h, ")");
771 break;
772 case EXPR_SHL:
773 case EXPR_SHR:
774 case EXPR_MOD:
775 case EXPR_MUL:
776 case EXPR_DIV:
777 case EXPR_ADD:
778 case EXPR_SUB:
779 case EXPR_AND:
780 case EXPR_OR:
781 case EXPR_LOGOR:
782 case EXPR_LOGAND:
783 case EXPR_XOR:
784 case EXPR_EQUALITY:
785 case EXPR_INEQUALITY:
786 case EXPR_GTR:
787 case EXPR_LESS:
788 case EXPR_GTREQL:
789 case EXPR_LESSEQL:
790 if (brackets) fprintf(h, "(");
791 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
792 switch (e->type)
794 case EXPR_SHL: fprintf(h, " << "); break;
795 case EXPR_SHR: fprintf(h, " >> "); break;
796 case EXPR_MOD: fprintf(h, " %% "); break;
797 case EXPR_MUL: fprintf(h, " * "); break;
798 case EXPR_DIV: fprintf(h, " / "); break;
799 case EXPR_ADD: fprintf(h, " + "); break;
800 case EXPR_SUB: fprintf(h, " - "); break;
801 case EXPR_AND: fprintf(h, " & "); break;
802 case EXPR_OR: fprintf(h, " | "); break;
803 case EXPR_LOGOR: fprintf(h, " || "); break;
804 case EXPR_LOGAND: fprintf(h, " && "); break;
805 case EXPR_XOR: fprintf(h, " ^ "); break;
806 case EXPR_EQUALITY: fprintf(h, " == "); break;
807 case EXPR_INEQUALITY: fprintf(h, " != "); break;
808 case EXPR_GTR: fprintf(h, " > "); break;
809 case EXPR_LESS: fprintf(h, " < "); break;
810 case EXPR_GTREQL: fprintf(h, " >= "); break;
811 case EXPR_LESSEQL: fprintf(h, " <= "); break;
812 default: break;
814 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
815 if (brackets) fprintf(h, ")");
816 break;
817 case EXPR_MEMBER:
818 if (brackets) fprintf(h, "(");
819 if (e->ref->type == EXPR_PPTR)
821 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
822 fprintf(h, "->");
824 else
826 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
827 fprintf(h, ".");
829 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
830 if (brackets) fprintf(h, ")");
831 break;
832 case EXPR_COND:
833 if (brackets) fprintf(h, "(");
834 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
835 fprintf(h, " ? ");
836 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
837 fprintf(h, " : ");
838 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
839 if (brackets) fprintf(h, ")");
840 break;
841 case EXPR_ARRAY:
842 if (brackets) fprintf(h, "(");
843 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
844 fprintf(h, "[");
845 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
846 fprintf(h, "]");
847 if (brackets) fprintf(h, ")");
848 break;
852 /* This is actually fairly involved to implement precisely, due to the
853 effects attributes may have and things like that. Right now this is
854 only used for optimization, so just check for a very small set of
855 criteria that guarantee the types are equivalent; assume every thing
856 else is different. */
857 static int compare_type(const type_t *a, const type_t *b)
859 if (a == b
860 || (a->name
861 && b->name
862 && strcmp(a->name, b->name) == 0))
863 return 0;
864 /* Ordering doesn't need to be implemented yet. */
865 return 1;
868 int compare_expr(const expr_t *a, const expr_t *b)
870 int ret;
872 if (a->type != b->type)
873 return a->type - b->type;
875 switch (a->type)
877 case EXPR_NUM:
878 case EXPR_HEXNUM:
879 case EXPR_TRUEFALSE:
880 return a->u.lval - b->u.lval;
881 case EXPR_DOUBLE:
882 return a->u.dval - b->u.dval;
883 case EXPR_IDENTIFIER:
884 case EXPR_STRLIT:
885 case EXPR_WSTRLIT:
886 case EXPR_CHARCONST:
887 return strcmp(a->u.sval, b->u.sval);
888 case EXPR_COND:
889 ret = compare_expr(a->ref, b->ref);
890 if (ret != 0)
891 return ret;
892 ret = compare_expr(a->u.ext, b->u.ext);
893 if (ret != 0)
894 return ret;
895 return compare_expr(a->ext2, b->ext2);
896 case EXPR_OR:
897 case EXPR_AND:
898 case EXPR_ADD:
899 case EXPR_SUB:
900 case EXPR_MOD:
901 case EXPR_MUL:
902 case EXPR_DIV:
903 case EXPR_SHL:
904 case EXPR_SHR:
905 case EXPR_MEMBER:
906 case EXPR_ARRAY:
907 case EXPR_LOGOR:
908 case EXPR_LOGAND:
909 case EXPR_XOR:
910 case EXPR_EQUALITY:
911 case EXPR_INEQUALITY:
912 case EXPR_GTR:
913 case EXPR_LESS:
914 case EXPR_GTREQL:
915 case EXPR_LESSEQL:
916 ret = compare_expr(a->ref, b->ref);
917 if (ret != 0)
918 return ret;
919 return compare_expr(a->u.ext, b->u.ext);
920 case EXPR_CAST:
921 ret = compare_type(a->u.tref.type, b->u.tref.type);
922 if (ret != 0)
923 return ret;
924 /* Fall through. */
925 case EXPR_NOT:
926 case EXPR_NEG:
927 case EXPR_PPTR:
928 case EXPR_ADDRESSOF:
929 case EXPR_LOGNOT:
930 case EXPR_POS:
931 return compare_expr(a->ref, b->ref);
932 case EXPR_SIZEOF:
933 return compare_type(a->u.tref.type, b->u.tref.type);
934 case EXPR_VOID:
935 return 0;
937 return -1;