windowscodecs: Silence fixme for IID_CMetaBitmapRenderTarget.
[wine.git] / tools / widl / expr.c
blobe0c56b81089a32b83ed532a511267d0e272c6d41
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 ) && !is_float_type( type )))
410 error_at( &expr_loc->v->where, "scalar type required in expression%s%s\n",
411 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
414 static void check_arithmetic_type(const struct expr_loc *expr_loc,
415 const type_t *cont_type, const type_t *type)
417 if (!cont_type || (!is_integer_type( type ) && !is_float_type( type )))
418 error_at( &expr_loc->v->where, "arithmetic type required in expression%s%s\n",
419 expr_loc->attr ? " for attribute " : "", 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_at( &expr_loc->v->where, "integer type required in expression%s%s\n",
427 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
430 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
432 type_t *type = NULL;
433 const var_t *field;
434 const var_list_t *fields = NULL;
436 *found_in_cont_type = 0;
438 if (cont_type)
440 switch (type_get_type(cont_type))
442 case TYPE_FUNCTION:
443 fields = type_function_get_args(cont_type);
444 break;
445 case TYPE_STRUCT:
446 fields = type_struct_get_fields(cont_type);
447 break;
448 case TYPE_UNION:
449 case TYPE_ENCAPSULATED_UNION:
450 fields = type_union_get_cases(cont_type);
451 break;
452 case TYPE_VOID:
453 case TYPE_BASIC:
454 case TYPE_ENUM:
455 case TYPE_MODULE:
456 case TYPE_COCLASS:
457 case TYPE_INTERFACE:
458 case TYPE_POINTER:
459 case TYPE_ARRAY:
460 case TYPE_BITFIELD:
461 case TYPE_APICONTRACT:
462 case TYPE_RUNTIMECLASS:
463 case TYPE_PARAMETERIZED_TYPE:
464 case TYPE_PARAMETER:
465 case TYPE_DELEGATE:
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)
546 error_at( &expr_loc->v->where, "identifier %s cannot be resolved in expression%s%s\n", e->u.sval,
547 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
548 break;
550 case EXPR_LOGNOT:
551 result = resolve_expression(expr_loc, cont_type, e->ref);
552 check_scalar_type(expr_loc, cont_type, result.type);
553 result.is_variable = FALSE;
554 result.is_temporary = FALSE;
555 result.type = type_new_int(TYPE_BASIC_INT, 0);
556 break;
557 case EXPR_NOT:
558 result = resolve_expression(expr_loc, cont_type, e->ref);
559 check_integer_type(expr_loc, cont_type, result.type);
560 result.is_variable = FALSE;
561 break;
562 case EXPR_POS:
563 case EXPR_NEG:
564 result = resolve_expression(expr_loc, cont_type, e->ref);
565 check_arithmetic_type(expr_loc, cont_type, result.type);
566 result.is_variable = FALSE;
567 break;
568 case EXPR_ADDRESSOF:
569 result = resolve_expression(expr_loc, cont_type, e->ref);
570 if (!result.is_variable)
571 error_at( &expr_loc->v->where, "address-of operator applied to non-variable type in expression%s%s\n",
572 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
573 result.is_variable = FALSE;
574 result.is_temporary = TRUE;
575 result.type = type_new_pointer(result.type);
576 break;
577 case EXPR_PPTR:
578 result = resolve_expression(expr_loc, cont_type, e->ref);
579 if (result.type && is_ptr(result.type))
580 result.type = type_pointer_get_ref_type(result.type);
581 else if(result.type && is_array(result.type)
582 && type_array_is_decl_as_ptr(result.type))
583 result.type = type_array_get_element_type(result.type);
584 else
585 error_at( &expr_loc->v->where, "dereference operator applied to non-pointer type in expression%s%s\n",
586 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
587 break;
588 case EXPR_CAST:
589 result = resolve_expression(expr_loc, cont_type, e->ref);
590 result.type = e->u.tref.type;
591 break;
592 case EXPR_SIZEOF:
593 result.is_temporary = FALSE;
594 result.type = type_new_int(TYPE_BASIC_INT, 0);
595 break;
596 case EXPR_SHL:
597 case EXPR_SHR:
598 case EXPR_MOD:
599 case EXPR_MUL:
600 case EXPR_DIV:
601 case EXPR_ADD:
602 case EXPR_SUB:
603 case EXPR_AND:
604 case EXPR_OR:
605 case EXPR_XOR:
607 struct expression_type result_right;
608 result = resolve_expression(expr_loc, cont_type, e->ref);
609 result.is_variable = FALSE;
610 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
611 /* FIXME: these checks aren't strict enough for some of the operators */
612 check_scalar_type(expr_loc, cont_type, result.type);
613 check_scalar_type(expr_loc, cont_type, result_right.type);
614 break;
616 case EXPR_LOGOR:
617 case EXPR_LOGAND:
618 case EXPR_EQUALITY:
619 case EXPR_INEQUALITY:
620 case EXPR_GTR:
621 case EXPR_LESS:
622 case EXPR_GTREQL:
623 case EXPR_LESSEQL:
625 struct expression_type result_left, result_right;
626 result_left = resolve_expression(expr_loc, cont_type, e->ref);
627 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
628 check_scalar_type(expr_loc, cont_type, result_left.type);
629 check_scalar_type(expr_loc, cont_type, result_right.type);
630 result.is_temporary = FALSE;
631 result.type = type_new_int(TYPE_BASIC_INT, 0);
632 break;
634 case EXPR_MEMBER:
635 result = resolve_expression(expr_loc, cont_type, e->ref);
636 if (result.type && is_valid_member_operand(result.type))
637 result = resolve_expression(expr_loc, result.type, e->u.ext);
638 else
639 error_at( &expr_loc->v->where, "'.' or '->' operator applied to a type that isn't a structure, union or enumeration in expression%s%s\n",
640 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
641 break;
642 case EXPR_COND:
644 struct expression_type result_first, result_second, result_third;
645 result_first = resolve_expression(expr_loc, cont_type, e->ref);
646 check_scalar_type(expr_loc, cont_type, result_first.type);
647 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
648 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
649 check_scalar_type(expr_loc, cont_type, result_second.type);
650 check_scalar_type(expr_loc, cont_type, result_third.type);
651 if (!is_ptr( result_second.type ) ^ !is_ptr( result_third.type ))
652 error_at( &expr_loc->v->where, "type mismatch in ?: expression\n" );
653 /* FIXME: determine the correct return type */
654 result = result_second;
655 result.is_variable = FALSE;
656 break;
658 case EXPR_ARRAY:
659 result = resolve_expression(expr_loc, cont_type, e->ref);
660 if (result.type && is_array(result.type))
662 struct expression_type index_result;
663 result.type = type_array_get_element_type(result.type);
664 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
665 if (!index_result.type || !is_integer_type( index_result.type ))
666 error_at( &expr_loc->v->where, "array subscript not of integral type in expression%s%s\n",
667 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
669 else
671 error_at( &expr_loc->v->where, "array subscript operator applied to non-array type in expression%s%s\n",
672 expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : "" );
674 break;
676 return result;
679 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
681 struct expression_type expr_type;
682 expr_type = resolve_expression(expr_loc, cont_type, expr);
683 return expr_type.type;
686 void write_expr(FILE *h, const expr_t *e, int brackets,
687 int toplevel, const char *toplevel_prefix,
688 const type_t *cont_type, const char *local_var_prefix)
690 switch (e->type)
692 case EXPR_VOID:
693 break;
694 case EXPR_NUM:
695 fprintf(h, "%u", e->u.lval);
696 break;
697 case EXPR_HEXNUM:
698 fprintf(h, "0x%x", e->u.lval);
699 break;
700 case EXPR_DOUBLE:
701 fprintf(h, "%#.15g", e->u.dval);
702 break;
703 case EXPR_TRUEFALSE:
704 if (e->u.lval == 0)
705 fprintf(h, "FALSE");
706 else
707 fprintf(h, "TRUE");
708 break;
709 case EXPR_IDENTIFIER:
710 if (toplevel && toplevel_prefix && cont_type)
712 int found_in_cont_type;
713 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
714 if (found_in_cont_type)
716 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
717 break;
720 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
721 break;
722 case EXPR_STRLIT:
723 fprintf(h, "\"%s\"", e->u.sval);
724 break;
725 case EXPR_WSTRLIT:
726 fprintf(h, "L\"%s\"", e->u.sval);
727 break;
728 case EXPR_CHARCONST:
729 fprintf(h, "'%s'", e->u.sval);
730 break;
731 case EXPR_LOGNOT:
732 fprintf(h, "!");
733 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
734 break;
735 case EXPR_NOT:
736 fprintf(h, "~");
737 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
738 break;
739 case EXPR_POS:
740 fprintf(h, "+");
741 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
742 break;
743 case EXPR_NEG:
744 fprintf(h, "-");
745 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
746 break;
747 case EXPR_ADDRESSOF:
748 fprintf(h, "&");
749 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
750 break;
751 case EXPR_PPTR:
752 fprintf(h, "*");
753 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
754 break;
755 case EXPR_CAST:
756 fprintf(h, "(");
757 write_type_decl(h, &e->u.tref, NULL);
758 fprintf(h, ")");
759 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
760 break;
761 case EXPR_SIZEOF:
762 fprintf(h, "sizeof(");
763 write_type_decl(h, &e->u.tref, NULL);
764 fprintf(h, ")");
765 break;
766 case EXPR_SHL:
767 case EXPR_SHR:
768 case EXPR_MOD:
769 case EXPR_MUL:
770 case EXPR_DIV:
771 case EXPR_ADD:
772 case EXPR_SUB:
773 case EXPR_AND:
774 case EXPR_OR:
775 case EXPR_LOGOR:
776 case EXPR_LOGAND:
777 case EXPR_XOR:
778 case EXPR_EQUALITY:
779 case EXPR_INEQUALITY:
780 case EXPR_GTR:
781 case EXPR_LESS:
782 case EXPR_GTREQL:
783 case EXPR_LESSEQL:
784 if (brackets) fprintf(h, "(");
785 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
786 switch (e->type)
788 case EXPR_SHL: fprintf(h, " << "); break;
789 case EXPR_SHR: fprintf(h, " >> "); break;
790 case EXPR_MOD: fprintf(h, " %% "); break;
791 case EXPR_MUL: fprintf(h, " * "); break;
792 case EXPR_DIV: fprintf(h, " / "); break;
793 case EXPR_ADD: fprintf(h, " + "); break;
794 case EXPR_SUB: fprintf(h, " - "); break;
795 case EXPR_AND: fprintf(h, " & "); break;
796 case EXPR_OR: fprintf(h, " | "); break;
797 case EXPR_LOGOR: fprintf(h, " || "); break;
798 case EXPR_LOGAND: fprintf(h, " && "); break;
799 case EXPR_XOR: fprintf(h, " ^ "); break;
800 case EXPR_EQUALITY: fprintf(h, " == "); break;
801 case EXPR_INEQUALITY: fprintf(h, " != "); break;
802 case EXPR_GTR: fprintf(h, " > "); break;
803 case EXPR_LESS: fprintf(h, " < "); break;
804 case EXPR_GTREQL: fprintf(h, " >= "); break;
805 case EXPR_LESSEQL: fprintf(h, " <= "); break;
806 default: break;
808 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
809 if (brackets) fprintf(h, ")");
810 break;
811 case EXPR_MEMBER:
812 if (brackets) fprintf(h, "(");
813 if (e->ref->type == EXPR_PPTR)
815 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
816 fprintf(h, "->");
818 else
820 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
821 fprintf(h, ".");
823 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
824 if (brackets) fprintf(h, ")");
825 break;
826 case EXPR_COND:
827 if (brackets) fprintf(h, "(");
828 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
829 fprintf(h, " ? ");
830 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
831 fprintf(h, " : ");
832 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
833 if (brackets) fprintf(h, ")");
834 break;
835 case EXPR_ARRAY:
836 if (brackets) fprintf(h, "(");
837 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
838 fprintf(h, "[");
839 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
840 fprintf(h, "]");
841 if (brackets) fprintf(h, ")");
842 break;
846 /* This is actually fairly involved to implement precisely, due to the
847 effects attributes may have and things like that. Right now this is
848 only used for optimization, so just check for a very small set of
849 criteria that guarantee the types are equivalent; assume every thing
850 else is different. */
851 static int compare_type(const type_t *a, const type_t *b)
853 if (a == b
854 || (a->name
855 && b->name
856 && strcmp(a->name, b->name) == 0))
857 return 0;
858 /* Ordering doesn't need to be implemented yet. */
859 return 1;
862 int compare_expr(const expr_t *a, const expr_t *b)
864 int ret;
866 if (a->type != b->type)
867 return a->type - b->type;
869 switch (a->type)
871 case EXPR_NUM:
872 case EXPR_HEXNUM:
873 case EXPR_TRUEFALSE:
874 return a->u.lval - b->u.lval;
875 case EXPR_DOUBLE:
876 return a->u.dval - b->u.dval;
877 case EXPR_IDENTIFIER:
878 case EXPR_STRLIT:
879 case EXPR_WSTRLIT:
880 case EXPR_CHARCONST:
881 return strcmp(a->u.sval, b->u.sval);
882 case EXPR_COND:
883 ret = compare_expr(a->ref, b->ref);
884 if (ret != 0)
885 return ret;
886 ret = compare_expr(a->u.ext, b->u.ext);
887 if (ret != 0)
888 return ret;
889 return compare_expr(a->ext2, b->ext2);
890 case EXPR_OR:
891 case EXPR_AND:
892 case EXPR_ADD:
893 case EXPR_SUB:
894 case EXPR_MOD:
895 case EXPR_MUL:
896 case EXPR_DIV:
897 case EXPR_SHL:
898 case EXPR_SHR:
899 case EXPR_MEMBER:
900 case EXPR_ARRAY:
901 case EXPR_LOGOR:
902 case EXPR_LOGAND:
903 case EXPR_XOR:
904 case EXPR_EQUALITY:
905 case EXPR_INEQUALITY:
906 case EXPR_GTR:
907 case EXPR_LESS:
908 case EXPR_GTREQL:
909 case EXPR_LESSEQL:
910 ret = compare_expr(a->ref, b->ref);
911 if (ret != 0)
912 return ret;
913 return compare_expr(a->u.ext, b->u.ext);
914 case EXPR_CAST:
915 ret = compare_type(a->u.tref.type, b->u.tref.type);
916 if (ret != 0)
917 return ret;
918 /* Fall through. */
919 case EXPR_NOT:
920 case EXPR_NEG:
921 case EXPR_PPTR:
922 case EXPR_ADDRESSOF:
923 case EXPR_LOGNOT:
924 case EXPR_POS:
925 return compare_expr(a->ref, b->ref);
926 case EXPR_SIZEOF:
927 return compare_type(a->u.tref.type, b->u.tref.type);
928 case EXPR_VOID:
929 return 0;
931 return -1;