d3dx9: Start effect parameter parsing.
[wine.git] / tools / widl / expr.c
blob60e3a50444b6a080b84102af9dde2b3f42f8c41e
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 /* FALLTHROUGH */
98 default:
99 return FALSE;
103 static int is_float_type(const type_t *type)
105 return (type_get_type(type) == TYPE_BASIC &&
106 (type_basic_get_type(type) == TYPE_BASIC_FLOAT ||
107 type_basic_get_type(type) == TYPE_BASIC_DOUBLE));
110 expr_t *make_expr(enum expr_type type)
112 expr_t *e = xmalloc(sizeof(expr_t));
113 e->type = type;
114 e->ref = NULL;
115 e->u.lval = 0;
116 e->is_const = FALSE;
117 e->cval = 0;
118 return e;
121 expr_t *make_exprl(enum expr_type type, int val)
123 expr_t *e = xmalloc(sizeof(expr_t));
124 e->type = type;
125 e->ref = NULL;
126 e->u.lval = val;
127 e->is_const = FALSE;
128 /* check for numeric constant */
129 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
131 /* make sure true/false value is valid */
132 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
133 e->is_const = TRUE;
134 e->cval = val;
136 return e;
139 expr_t *make_exprd(enum expr_type type, double val)
141 expr_t *e = xmalloc(sizeof(expr_t));
142 e->type = type;
143 e->ref = NULL;
144 e->u.dval = val;
145 e->is_const = TRUE;
146 e->cval = val;
147 return e;
150 expr_t *make_exprs(enum expr_type type, char *val)
152 expr_t *e;
153 e = xmalloc(sizeof(expr_t));
154 e->type = type;
155 e->ref = NULL;
156 e->u.sval = val;
157 e->is_const = FALSE;
158 /* check for predefined constants */
159 switch (type)
161 case EXPR_IDENTIFIER:
163 var_t *c = find_const(val, 0);
164 if (c)
166 e->u.sval = c->name;
167 free(val);
168 e->is_const = TRUE;
169 e->cval = c->eval->cval;
171 break;
173 case EXPR_CHARCONST:
174 if (!val[0])
175 error_loc("empty character constant\n");
176 else if (val[1])
177 error_loc("multi-character constants are endian dependent\n");
178 else
180 e->is_const = TRUE;
181 e->cval = *val;
183 break;
184 default:
185 break;
187 return e;
190 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
192 expr_t *e;
193 type_t *tref;
195 if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
196 error_loc("invalid storage class for type expression\n");
198 tref = var->type;
200 e = xmalloc(sizeof(expr_t));
201 e->type = type;
202 e->ref = expr;
203 e->u.tref = tref;
204 e->is_const = FALSE;
205 if (type == EXPR_SIZEOF)
207 /* only do this for types that should be the same on all platforms */
208 if (is_integer_type(tref) || is_float_type(tref))
210 e->is_const = TRUE;
211 e->cval = type_memsize(tref);
214 /* check for cast of constant expression */
215 if (type == EXPR_CAST && expr->is_const)
217 if (is_integer_type(tref))
219 unsigned int cast_type_bits = type_memsize(tref) * 8;
220 unsigned int cast_mask;
222 e->is_const = TRUE;
223 if (is_signed_integer_type(tref))
225 cast_mask = (1 << (cast_type_bits - 1)) - 1;
226 if (expr->cval & (1 << (cast_type_bits - 1)))
227 e->cval = -((-expr->cval) & cast_mask);
228 else
229 e->cval = expr->cval & cast_mask;
231 else
233 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
234 cast_mask = ((1 << (cast_type_bits - 1)) - 1) |
235 1 << (cast_type_bits - 1);
236 e->cval = expr->cval & cast_mask;
239 else
241 e->is_const = TRUE;
242 e->cval = expr->cval;
245 free(var);
246 return e;
249 expr_t *make_expr1(enum expr_type type, expr_t *expr)
251 expr_t *e;
252 e = xmalloc(sizeof(expr_t));
253 e->type = type;
254 e->ref = expr;
255 e->u.lval = 0;
256 e->is_const = FALSE;
257 /* check for compile-time optimization */
258 if (expr->is_const)
260 e->is_const = TRUE;
261 switch (type)
263 case EXPR_LOGNOT:
264 e->cval = !expr->cval;
265 break;
266 case EXPR_POS:
267 e->cval = +expr->cval;
268 break;
269 case EXPR_NEG:
270 e->cval = -expr->cval;
271 break;
272 case EXPR_NOT:
273 e->cval = ~expr->cval;
274 break;
275 default:
276 e->is_const = FALSE;
277 break;
280 return e;
283 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
285 expr_t *e;
286 e = xmalloc(sizeof(expr_t));
287 e->type = type;
288 e->ref = expr1;
289 e->u.ext = expr2;
290 e->is_const = FALSE;
291 /* check for compile-time optimization */
292 if (expr1->is_const && expr2->is_const)
294 e->is_const = TRUE;
295 switch (type)
297 case EXPR_ADD:
298 e->cval = expr1->cval + expr2->cval;
299 break;
300 case EXPR_SUB:
301 e->cval = expr1->cval - expr2->cval;
302 break;
303 case EXPR_MOD:
304 if (expr2->cval == 0)
306 error_loc("divide by zero in expression\n");
307 e->cval = 0;
309 else
310 e->cval = expr1->cval % expr2->cval;
311 break;
312 case EXPR_MUL:
313 e->cval = expr1->cval * expr2->cval;
314 break;
315 case EXPR_DIV:
316 if (expr2->cval == 0)
318 error_loc("divide by zero in expression\n");
319 e->cval = 0;
321 else
322 e->cval = expr1->cval / expr2->cval;
323 break;
324 case EXPR_OR:
325 e->cval = expr1->cval | expr2->cval;
326 break;
327 case EXPR_AND:
328 e->cval = expr1->cval & expr2->cval;
329 break;
330 case EXPR_SHL:
331 e->cval = expr1->cval << expr2->cval;
332 break;
333 case EXPR_SHR:
334 e->cval = expr1->cval >> expr2->cval;
335 break;
336 case EXPR_LOGOR:
337 e->cval = expr1->cval || expr2->cval;
338 break;
339 case EXPR_LOGAND:
340 e->cval = expr1->cval && expr2->cval;
341 break;
342 case EXPR_XOR:
343 e->cval = expr1->cval ^ expr2->cval;
344 break;
345 case EXPR_EQUALITY:
346 e->cval = expr1->cval == expr2->cval;
347 break;
348 case EXPR_INEQUALITY:
349 e->cval = expr1->cval != expr2->cval;
350 break;
351 case EXPR_GTR:
352 e->cval = expr1->cval > expr2->cval;
353 break;
354 case EXPR_LESS:
355 e->cval = expr1->cval < expr2->cval;
356 break;
357 case EXPR_GTREQL:
358 e->cval = expr1->cval >= expr2->cval;
359 break;
360 case EXPR_LESSEQL:
361 e->cval = expr1->cval <= expr2->cval;
362 break;
363 default:
364 e->is_const = FALSE;
365 break;
368 return e;
371 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
373 expr_t *e;
374 e = xmalloc(sizeof(expr_t));
375 e->type = type;
376 e->ref = expr1;
377 e->u.ext = expr2;
378 e->ext2 = expr3;
379 e->is_const = FALSE;
380 /* check for compile-time optimization */
381 if (expr1->is_const && expr2->is_const && expr3->is_const)
383 e->is_const = TRUE;
384 switch (type)
386 case EXPR_COND:
387 e->cval = expr1->cval ? expr2->cval : expr3->cval;
388 break;
389 default:
390 e->is_const = FALSE;
391 break;
394 return e;
397 struct expression_type
399 int is_variable; /* is the expression resolved to a variable? */
400 int is_temporary; /* should the type be freed? */
401 type_t *type;
404 static void check_scalar_type(const struct expr_loc *expr_loc,
405 const type_t *cont_type, const type_t *type)
407 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
408 !is_float_type(type)))
409 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
410 expr_loc->attr ? " for attribute " : "",
411 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_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
419 expr_loc->attr ? " for attribute " : "",
420 expr_loc->attr ? expr_loc->attr : "");
423 static void check_integer_type(const struct expr_loc *expr_loc,
424 const type_t *cont_type, const type_t *type)
426 if (!cont_type || !is_integer_type(type))
427 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
428 expr_loc->attr ? " for attribute " : "",
429 expr_loc->attr ? expr_loc->attr : "");
432 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
434 type_t *type = NULL;
435 const var_t *field;
436 const var_list_t *fields = NULL;
438 *found_in_cont_type = 0;
440 if (cont_type)
442 switch (type_get_type(cont_type))
444 case TYPE_FUNCTION:
445 fields = type_function_get_args(cont_type);
446 break;
447 case TYPE_STRUCT:
448 fields = type_struct_get_fields(cont_type);
449 break;
450 case TYPE_UNION:
451 case TYPE_ENCAPSULATED_UNION:
452 fields = type_union_get_cases(cont_type);
453 break;
454 case TYPE_VOID:
455 case TYPE_BASIC:
456 case TYPE_ENUM:
457 case TYPE_MODULE:
458 case TYPE_COCLASS:
459 case TYPE_INTERFACE:
460 case TYPE_POINTER:
461 case TYPE_ARRAY:
462 case TYPE_BITFIELD:
463 /* nothing to do */
464 break;
465 case TYPE_ALIAS:
466 /* shouldn't get here because of using type_get_type above */
467 assert(0);
468 break;
472 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
473 if (field->name && !strcmp(identifier, field->name))
475 type = field->type;
476 *found_in_cont_type = 1;
477 break;
480 if (!type)
482 var_t *const_var = find_const(identifier, 0);
483 if (const_var) type = const_var->type;
486 return type;
489 static int is_valid_member_operand(const type_t *type)
491 switch (type_get_type(type))
493 case TYPE_STRUCT:
494 case TYPE_UNION:
495 case TYPE_ENUM:
496 return TRUE;
497 default:
498 return FALSE;
502 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
503 const type_t *cont_type,
504 const expr_t *e)
506 struct expression_type result;
507 result.is_variable = FALSE;
508 result.is_temporary = FALSE;
509 result.type = NULL;
510 switch (e->type)
512 case EXPR_VOID:
513 break;
514 case EXPR_HEXNUM:
515 case EXPR_NUM:
516 case EXPR_TRUEFALSE:
517 result.is_temporary = FALSE;
518 result.type = type_new_int(TYPE_BASIC_INT, 0);
519 break;
520 case EXPR_STRLIT:
521 result.is_temporary = TRUE;
522 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
523 break;
524 case EXPR_WSTRLIT:
525 result.is_temporary = TRUE;
526 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
527 break;
528 case EXPR_CHARCONST:
529 result.is_temporary = TRUE;
530 result.type = type_new_int(TYPE_BASIC_CHAR, 0);
531 break;
532 case EXPR_DOUBLE:
533 result.is_temporary = TRUE;
534 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
535 break;
536 case EXPR_IDENTIFIER:
538 int found_in_cont_type;
539 result.is_variable = TRUE;
540 result.is_temporary = FALSE;
541 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
542 if (!result.type)
544 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
545 e->u.sval, expr_loc->attr ? " for attribute " : "",
546 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_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
572 expr_loc->attr ? " for attribute " : "",
573 expr_loc->attr ? expr_loc->attr : "");
574 result.is_variable = FALSE;
575 result.is_temporary = TRUE;
576 result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
577 break;
578 case EXPR_PPTR:
579 result = resolve_expression(expr_loc, cont_type, e->ref);
580 if (result.type && is_ptr(result.type))
581 result.type = type_pointer_get_ref(result.type);
582 else if(result.type && is_array(result.type)
583 && type_array_is_decl_as_ptr(result.type))
584 result.type = type_array_get_element(result.type);
585 else
586 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
587 expr_loc->attr ? " for attribute " : "",
588 expr_loc->attr ? expr_loc->attr : "");
589 break;
590 case EXPR_CAST:
591 result = resolve_expression(expr_loc, cont_type, e->ref);
592 result.type = e->u.tref;
593 break;
594 case EXPR_SIZEOF:
595 result.is_temporary = FALSE;
596 result.type = type_new_int(TYPE_BASIC_INT, 0);
597 break;
598 case EXPR_SHL:
599 case EXPR_SHR:
600 case EXPR_MOD:
601 case EXPR_MUL:
602 case EXPR_DIV:
603 case EXPR_ADD:
604 case EXPR_SUB:
605 case EXPR_AND:
606 case EXPR_OR:
607 case EXPR_XOR:
609 struct expression_type result_right;
610 result = resolve_expression(expr_loc, cont_type, e->ref);
611 result.is_variable = FALSE;
612 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
613 /* FIXME: these checks aren't strict enough for some of the operators */
614 check_scalar_type(expr_loc, cont_type, result.type);
615 check_scalar_type(expr_loc, cont_type, result_right.type);
616 break;
618 case EXPR_LOGOR:
619 case EXPR_LOGAND:
620 case EXPR_EQUALITY:
621 case EXPR_INEQUALITY:
622 case EXPR_GTR:
623 case EXPR_LESS:
624 case EXPR_GTREQL:
625 case EXPR_LESSEQL:
627 struct expression_type result_left, result_right;
628 result_left = resolve_expression(expr_loc, cont_type, e->ref);
629 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
630 check_scalar_type(expr_loc, cont_type, result_left.type);
631 check_scalar_type(expr_loc, cont_type, result_right.type);
632 result.is_temporary = FALSE;
633 result.type = type_new_int(TYPE_BASIC_INT, 0);
634 break;
636 case EXPR_MEMBER:
637 result = resolve_expression(expr_loc, cont_type, e->ref);
638 if (result.type && is_valid_member_operand(result.type))
639 result = resolve_expression(expr_loc, result.type, e->u.ext);
640 else
641 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",
642 expr_loc->attr ? " for attribute " : "",
643 expr_loc->attr ? expr_loc->attr : "");
644 break;
645 case EXPR_COND:
647 struct expression_type result_first, result_second, result_third;
648 result_first = resolve_expression(expr_loc, cont_type, e->ref);
649 check_scalar_type(expr_loc, cont_type, result_first.type);
650 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
651 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
652 /* FIXME: determine the correct return type */
653 result = result_second;
654 result.is_variable = FALSE;
655 break;
657 case EXPR_ARRAY:
658 result = resolve_expression(expr_loc, cont_type, e->ref);
659 if (result.type && is_array(result.type))
661 struct expression_type index_result;
662 result.type = type_array_get_element(result.type);
663 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
664 if (!index_result.type || !is_integer_type(index_result.type))
665 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
666 expr_loc->attr ? " for attribute " : "",
667 expr_loc->attr ? expr_loc->attr : "");
669 else
670 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
671 expr_loc->attr ? " for attribute " : "",
672 expr_loc->attr ? expr_loc->attr : "");
673 break;
675 return result;
678 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
680 struct expression_type expr_type;
681 expr_type = resolve_expression(expr_loc, cont_type, expr);
682 return expr_type.type;
685 void write_expr(FILE *h, const expr_t *e, int brackets,
686 int toplevel, const char *toplevel_prefix,
687 const type_t *cont_type, const char *local_var_prefix)
689 switch (e->type)
691 case EXPR_VOID:
692 break;
693 case EXPR_NUM:
694 fprintf(h, "%u", e->u.lval);
695 break;
696 case EXPR_HEXNUM:
697 fprintf(h, "0x%x", e->u.lval);
698 break;
699 case EXPR_DOUBLE:
700 fprintf(h, "%#.15g", e->u.dval);
701 break;
702 case EXPR_TRUEFALSE:
703 if (e->u.lval == 0)
704 fprintf(h, "FALSE");
705 else
706 fprintf(h, "TRUE");
707 break;
708 case EXPR_IDENTIFIER:
709 if (toplevel && toplevel_prefix && cont_type)
711 int found_in_cont_type;
712 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
713 if (found_in_cont_type)
715 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
716 break;
719 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
720 break;
721 case EXPR_STRLIT:
722 fprintf(h, "\"%s\"", e->u.sval);
723 break;
724 case EXPR_WSTRLIT:
725 fprintf(h, "L\"%s\"", e->u.sval);
726 break;
727 case EXPR_CHARCONST:
728 fprintf(h, "'%s'", e->u.sval);
729 break;
730 case EXPR_LOGNOT:
731 fprintf(h, "!");
732 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
733 break;
734 case EXPR_NOT:
735 fprintf(h, "~");
736 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
737 break;
738 case EXPR_POS:
739 fprintf(h, "+");
740 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
741 break;
742 case EXPR_NEG:
743 fprintf(h, "-");
744 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
745 break;
746 case EXPR_ADDRESSOF:
747 fprintf(h, "&");
748 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
749 break;
750 case EXPR_PPTR:
751 fprintf(h, "*");
752 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
753 break;
754 case EXPR_CAST:
755 fprintf(h, "(");
756 write_type_decl(h, e->u.tref, NULL);
757 fprintf(h, ")");
758 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
759 break;
760 case EXPR_SIZEOF:
761 fprintf(h, "sizeof(");
762 write_type_decl(h, e->u.tref, NULL);
763 fprintf(h, ")");
764 break;
765 case EXPR_SHL:
766 case EXPR_SHR:
767 case EXPR_MOD:
768 case EXPR_MUL:
769 case EXPR_DIV:
770 case EXPR_ADD:
771 case EXPR_SUB:
772 case EXPR_AND:
773 case EXPR_OR:
774 case EXPR_LOGOR:
775 case EXPR_LOGAND:
776 case EXPR_XOR:
777 case EXPR_EQUALITY:
778 case EXPR_INEQUALITY:
779 case EXPR_GTR:
780 case EXPR_LESS:
781 case EXPR_GTREQL:
782 case EXPR_LESSEQL:
783 if (brackets) fprintf(h, "(");
784 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
785 switch (e->type)
787 case EXPR_SHL: fprintf(h, " << "); break;
788 case EXPR_SHR: fprintf(h, " >> "); break;
789 case EXPR_MOD: fprintf(h, " %% "); break;
790 case EXPR_MUL: fprintf(h, " * "); break;
791 case EXPR_DIV: fprintf(h, " / "); break;
792 case EXPR_ADD: fprintf(h, " + "); break;
793 case EXPR_SUB: fprintf(h, " - "); break;
794 case EXPR_AND: fprintf(h, " & "); break;
795 case EXPR_OR: fprintf(h, " | "); break;
796 case EXPR_LOGOR: fprintf(h, " || "); break;
797 case EXPR_LOGAND: fprintf(h, " && "); break;
798 case EXPR_XOR: fprintf(h, " ^ "); break;
799 case EXPR_EQUALITY: fprintf(h, " == "); break;
800 case EXPR_INEQUALITY: fprintf(h, " != "); break;
801 case EXPR_GTR: fprintf(h, " > "); break;
802 case EXPR_LESS: fprintf(h, " < "); break;
803 case EXPR_GTREQL: fprintf(h, " >= "); break;
804 case EXPR_LESSEQL: fprintf(h, " <= "); break;
805 default: break;
807 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
808 if (brackets) fprintf(h, ")");
809 break;
810 case EXPR_MEMBER:
811 if (brackets) fprintf(h, "(");
812 if (e->ref->type == EXPR_PPTR)
814 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
815 fprintf(h, "->");
817 else
819 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
820 fprintf(h, ".");
822 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
823 if (brackets) fprintf(h, ")");
824 break;
825 case EXPR_COND:
826 if (brackets) fprintf(h, "(");
827 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
828 fprintf(h, " ? ");
829 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
830 fprintf(h, " : ");
831 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
832 if (brackets) fprintf(h, ")");
833 break;
834 case EXPR_ARRAY:
835 if (brackets) fprintf(h, "(");
836 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
837 fprintf(h, "[");
838 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
839 fprintf(h, "]");
840 if (brackets) fprintf(h, ")");
841 break;
845 /* This is actually fairly involved to implement precisely, due to the
846 effects attributes may have and things like that. Right now this is
847 only used for optimization, so just check for a very small set of
848 criteria that guarantee the types are equivalent; assume every thing
849 else is different. */
850 static int compare_type(const type_t *a, const type_t *b)
852 if (a == b
853 || (a->name
854 && b->name
855 && strcmp(a->name, b->name) == 0))
856 return 0;
857 /* Ordering doesn't need to be implemented yet. */
858 return 1;
861 int compare_expr(const expr_t *a, const expr_t *b)
863 int ret;
865 if (a->type != b->type)
866 return a->type - b->type;
868 switch (a->type)
870 case EXPR_NUM:
871 case EXPR_HEXNUM:
872 case EXPR_TRUEFALSE:
873 return a->u.lval - b->u.lval;
874 case EXPR_DOUBLE:
875 return a->u.dval - b->u.dval;
876 case EXPR_IDENTIFIER:
877 case EXPR_STRLIT:
878 case EXPR_WSTRLIT:
879 case EXPR_CHARCONST:
880 return strcmp(a->u.sval, b->u.sval);
881 case EXPR_COND:
882 ret = compare_expr(a->ref, b->ref);
883 if (ret != 0)
884 return ret;
885 ret = compare_expr(a->u.ext, b->u.ext);
886 if (ret != 0)
887 return ret;
888 return compare_expr(a->ext2, b->ext2);
889 case EXPR_OR:
890 case EXPR_AND:
891 case EXPR_ADD:
892 case EXPR_SUB:
893 case EXPR_MOD:
894 case EXPR_MUL:
895 case EXPR_DIV:
896 case EXPR_SHL:
897 case EXPR_SHR:
898 case EXPR_MEMBER:
899 case EXPR_ARRAY:
900 case EXPR_LOGOR:
901 case EXPR_LOGAND:
902 case EXPR_XOR:
903 case EXPR_EQUALITY:
904 case EXPR_INEQUALITY:
905 case EXPR_GTR:
906 case EXPR_LESS:
907 case EXPR_GTREQL:
908 case EXPR_LESSEQL:
909 ret = compare_expr(a->ref, b->ref);
910 if (ret != 0)
911 return ret;
912 return compare_expr(a->u.ext, b->u.ext);
913 case EXPR_CAST:
914 ret = compare_type(a->u.tref, b->u.tref);
915 if (ret != 0)
916 return ret;
917 /* Fall through. */
918 case EXPR_NOT:
919 case EXPR_NEG:
920 case EXPR_PPTR:
921 case EXPR_ADDRESSOF:
922 case EXPR_LOGNOT:
923 case EXPR_POS:
924 return compare_expr(a->ref, b->ref);
925 case EXPR_SIZEOF:
926 return compare_type(a->u.tref, b->u.tref);
927 case EXPR_VOID:
928 return 0;
930 return -1;