widl: Add support for bit-fields in non-remote structures.
[wine/testsucceed.git] / tools / widl / expr.c
blobcfe672d713fe1ae0df7e78d627003c360e13dca2
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);
39 static int is_float_type(const type_t *type);
41 expr_t *make_expr(enum expr_type type)
43 expr_t *e = xmalloc(sizeof(expr_t));
44 e->type = type;
45 e->ref = NULL;
46 e->u.lval = 0;
47 e->is_const = FALSE;
48 e->cval = 0;
49 return e;
52 expr_t *make_exprl(enum expr_type type, long val)
54 expr_t *e = xmalloc(sizeof(expr_t));
55 e->type = type;
56 e->ref = NULL;
57 e->u.lval = val;
58 e->is_const = FALSE;
59 /* check for numeric constant */
60 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
62 /* make sure true/false value is valid */
63 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
64 e->is_const = TRUE;
65 e->cval = val;
67 return e;
70 expr_t *make_exprd(enum expr_type type, double val)
72 expr_t *e = xmalloc(sizeof(expr_t));
73 e->type = type;
74 e->ref = NULL;
75 e->u.dval = val;
76 e->is_const = TRUE;
77 e->cval = val;
78 return e;
81 expr_t *make_exprs(enum expr_type type, char *val)
83 expr_t *e;
84 e = xmalloc(sizeof(expr_t));
85 e->type = type;
86 e->ref = NULL;
87 e->u.sval = val;
88 e->is_const = FALSE;
89 /* check for predefined constants */
90 if (type == EXPR_IDENTIFIER)
92 var_t *c = find_const(val, 0);
93 if (c)
95 e->u.sval = c->name;
96 free(val);
97 e->is_const = TRUE;
98 e->cval = c->eval->cval;
101 return e;
104 expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr)
106 expr_t *e;
107 e = xmalloc(sizeof(expr_t));
108 e->type = type;
109 e->ref = expr;
110 e->u.tref = tref;
111 e->is_const = FALSE;
112 if (type == EXPR_SIZEOF)
114 /* only do this for types that should be the same on all platforms */
115 if (is_integer_type(tref) || is_float_type(tref))
117 unsigned int align = 0;
118 e->is_const = TRUE;
119 e->cval = type_memsize(tref, &align);
122 /* check for cast of constant expression */
123 if (type == EXPR_CAST && expr->is_const)
125 e->is_const = TRUE;
126 e->cval = expr->cval;
128 return e;
131 expr_t *make_expr1(enum expr_type type, expr_t *expr)
133 expr_t *e;
134 e = xmalloc(sizeof(expr_t));
135 e->type = type;
136 e->ref = expr;
137 e->u.lval = 0;
138 e->is_const = FALSE;
139 /* check for compile-time optimization */
140 if (expr->is_const)
142 e->is_const = TRUE;
143 switch (type)
145 case EXPR_LOGNOT:
146 e->cval = !expr->cval;
147 break;
148 case EXPR_POS:
149 e->cval = +expr->cval;
150 break;
151 case EXPR_NEG:
152 e->cval = -expr->cval;
153 break;
154 case EXPR_NOT:
155 e->cval = ~expr->cval;
156 break;
157 default:
158 e->is_const = FALSE;
159 break;
162 return e;
165 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
167 expr_t *e;
168 e = xmalloc(sizeof(expr_t));
169 e->type = type;
170 e->ref = expr1;
171 e->u.ext = expr2;
172 e->is_const = FALSE;
173 /* check for compile-time optimization */
174 if (expr1->is_const && expr2->is_const)
176 e->is_const = TRUE;
177 switch (type)
179 case EXPR_ADD:
180 e->cval = expr1->cval + expr2->cval;
181 break;
182 case EXPR_SUB:
183 e->cval = expr1->cval - expr2->cval;
184 break;
185 case EXPR_MOD:
186 if (expr2->cval == 0)
188 error_loc("divide by zero in expression\n");
189 e->cval = 0;
191 else
192 e->cval = expr1->cval % expr2->cval;
193 break;
194 case EXPR_MUL:
195 e->cval = expr1->cval * expr2->cval;
196 break;
197 case EXPR_DIV:
198 if (expr2->cval == 0)
200 error_loc("divide by zero in expression\n");
201 e->cval = 0;
203 else
204 e->cval = expr1->cval / expr2->cval;
205 break;
206 case EXPR_OR:
207 e->cval = expr1->cval | expr2->cval;
208 break;
209 case EXPR_AND:
210 e->cval = expr1->cval & expr2->cval;
211 break;
212 case EXPR_SHL:
213 e->cval = expr1->cval << expr2->cval;
214 break;
215 case EXPR_SHR:
216 e->cval = expr1->cval >> expr2->cval;
217 break;
218 case EXPR_LOGOR:
219 e->cval = expr1->cval || expr2->cval;
220 break;
221 case EXPR_LOGAND:
222 e->cval = expr1->cval && expr2->cval;
223 break;
224 case EXPR_XOR:
225 e->cval = expr1->cval ^ expr2->cval;
226 break;
227 case EXPR_EQUALITY:
228 e->cval = expr1->cval == expr2->cval;
229 break;
230 case EXPR_INEQUALITY:
231 e->cval = expr1->cval != expr2->cval;
232 break;
233 case EXPR_GTR:
234 e->cval = expr1->cval > expr2->cval;
235 break;
236 case EXPR_LESS:
237 e->cval = expr1->cval < expr2->cval;
238 break;
239 case EXPR_GTREQL:
240 e->cval = expr1->cval >= expr2->cval;
241 break;
242 case EXPR_LESSEQL:
243 e->cval = expr1->cval <= expr2->cval;
244 break;
245 default:
246 e->is_const = FALSE;
247 break;
250 return e;
253 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
255 expr_t *e;
256 e = xmalloc(sizeof(expr_t));
257 e->type = type;
258 e->ref = expr1;
259 e->u.ext = expr2;
260 e->ext2 = expr3;
261 e->is_const = FALSE;
262 /* check for compile-time optimization */
263 if (expr1->is_const && expr2->is_const && expr3->is_const)
265 e->is_const = TRUE;
266 switch (type)
268 case EXPR_COND:
269 e->cval = expr1->cval ? expr2->cval : expr3->cval;
270 break;
271 default:
272 e->is_const = FALSE;
273 break;
276 return e;
279 struct expression_type
281 int is_variable; /* is the expression resolved to a variable? */
282 int is_temporary; /* should the type be freed? */
283 type_t *type;
286 static int is_integer_type(const type_t *type)
288 switch (type_get_type(type))
290 case TYPE_ENUM:
291 return TRUE;
292 case TYPE_BASIC:
293 switch (type_basic_get_type(type))
295 case TYPE_BASIC_INT8:
296 case TYPE_BASIC_INT16:
297 case TYPE_BASIC_INT32:
298 case TYPE_BASIC_INT64:
299 case TYPE_BASIC_INT:
300 case TYPE_BASIC_INT3264:
301 case TYPE_BASIC_CHAR:
302 case TYPE_BASIC_HYPER:
303 case TYPE_BASIC_BYTE:
304 case TYPE_BASIC_WCHAR:
305 case TYPE_BASIC_ERROR_STATUS_T:
306 return TRUE;
307 case TYPE_BASIC_FLOAT:
308 case TYPE_BASIC_DOUBLE:
309 case TYPE_BASIC_HANDLE:
310 return FALSE;
312 return FALSE;
313 default:
314 return FALSE;
318 static int is_float_type(const type_t *type)
320 return (type_get_type(type) == TYPE_BASIC &&
321 (type_basic_get_type(type) == TYPE_BASIC_FLOAT ||
322 type_basic_get_type(type) == TYPE_BASIC_DOUBLE));
325 static void check_scalar_type(const struct expr_loc *expr_loc,
326 const type_t *cont_type, const type_t *type)
328 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
329 !is_float_type(type)))
330 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
331 expr_loc->attr ? " for attribute " : "",
332 expr_loc->attr ? expr_loc->attr : "");
335 static void check_arithmetic_type(const struct expr_loc *expr_loc,
336 const type_t *cont_type, const type_t *type)
338 if (!cont_type || (!is_integer_type(type) && !is_float_type(type)))
339 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
340 expr_loc->attr ? " for attribute " : "",
341 expr_loc->attr ? expr_loc->attr : "");
344 static void check_integer_type(const struct expr_loc *expr_loc,
345 const type_t *cont_type, const type_t *type)
347 if (!cont_type || !is_integer_type(type))
348 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
349 expr_loc->attr ? " for attribute " : "",
350 expr_loc->attr ? expr_loc->attr : "");
353 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
355 type_t *type = NULL;
356 const var_t *field;
357 const var_list_t *fields = NULL;
359 *found_in_cont_type = 0;
361 if (cont_type)
363 switch (type_get_type(cont_type))
365 case TYPE_FUNCTION:
366 fields = type_function_get_args(cont_type);
367 break;
368 case TYPE_STRUCT:
369 fields = type_struct_get_fields(cont_type);
370 break;
371 case TYPE_UNION:
372 case TYPE_ENCAPSULATED_UNION:
373 fields = type_union_get_cases(cont_type);
374 break;
375 case TYPE_VOID:
376 case TYPE_BASIC:
377 case TYPE_ENUM:
378 case TYPE_MODULE:
379 case TYPE_COCLASS:
380 case TYPE_INTERFACE:
381 case TYPE_POINTER:
382 case TYPE_ARRAY:
383 case TYPE_BITFIELD:
384 /* nothing to do */
385 break;
386 case TYPE_ALIAS:
387 /* shouldn't get here because of using type_get_type above */
388 assert(0);
389 break;
393 if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
394 if (field->name && !strcmp(identifier, field->name))
396 type = field->type;
397 *found_in_cont_type = 1;
398 break;
401 if (!type)
403 var_t *const_var = find_const(identifier, 0);
404 if (const_var) type = const_var->type;
407 return type;
410 static int is_valid_member_operand(const type_t *type)
412 switch (type_get_type(type))
414 case TYPE_STRUCT:
415 case TYPE_UNION:
416 case TYPE_ENUM:
417 return TRUE;
418 default:
419 return FALSE;
423 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
424 const type_t *cont_type,
425 const expr_t *e)
427 struct expression_type result;
428 result.is_variable = FALSE;
429 result.is_temporary = FALSE;
430 result.type = NULL;
431 switch (e->type)
433 case EXPR_VOID:
434 break;
435 case EXPR_HEXNUM:
436 case EXPR_NUM:
437 case EXPR_TRUEFALSE:
438 result.is_variable = FALSE;
439 result.is_temporary = FALSE;
440 result.type = type_new_int(TYPE_BASIC_INT, 0);
441 break;
442 case EXPR_STRLIT:
443 result.is_variable = FALSE;
444 result.is_temporary = TRUE;
445 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
446 break;
447 case EXPR_WSTRLIT:
448 result.is_variable = FALSE;
449 result.is_temporary = TRUE;
450 result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
451 break;
452 case EXPR_DOUBLE:
453 result.is_variable = FALSE;
454 result.is_temporary = TRUE;
455 result.type = type_new_basic(TYPE_BASIC_DOUBLE);
456 break;
457 case EXPR_IDENTIFIER:
459 int found_in_cont_type;
460 result.is_variable = TRUE;
461 result.is_temporary = FALSE;
462 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
463 if (!result.type)
465 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
466 e->u.sval, expr_loc->attr ? " for attribute " : "",
467 expr_loc->attr ? expr_loc->attr : "");
469 break;
471 case EXPR_LOGNOT:
472 result = resolve_expression(expr_loc, cont_type, e->ref);
473 check_scalar_type(expr_loc, cont_type, result.type);
474 result.is_variable = FALSE;
475 result.is_temporary = FALSE;
476 result.type = type_new_int(TYPE_BASIC_INT, 0);
477 break;
478 case EXPR_NOT:
479 result = resolve_expression(expr_loc, cont_type, e->ref);
480 check_integer_type(expr_loc, cont_type, result.type);
481 result.is_variable = FALSE;
482 break;
483 case EXPR_POS:
484 case EXPR_NEG:
485 result = resolve_expression(expr_loc, cont_type, e->ref);
486 check_arithmetic_type(expr_loc, cont_type, result.type);
487 result.is_variable = FALSE;
488 break;
489 case EXPR_ADDRESSOF:
490 result = resolve_expression(expr_loc, cont_type, e->ref);
491 if (!result.is_variable)
492 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
493 expr_loc->attr ? " for attribute " : "",
494 expr_loc->attr ? expr_loc->attr : "");
495 result.is_variable = FALSE;
496 result.is_temporary = TRUE;
497 result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
498 break;
499 case EXPR_PPTR:
500 result = resolve_expression(expr_loc, cont_type, e->ref);
501 if (result.type && is_ptr(result.type))
502 result.type = type_pointer_get_ref(result.type);
503 else if(result.type && is_array(result.type)
504 && type_array_is_decl_as_ptr(result.type))
505 result.type = type_array_get_element(result.type);
506 else
507 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
508 expr_loc->attr ? " for attribute " : "",
509 expr_loc->attr ? expr_loc->attr : "");
510 break;
511 case EXPR_CAST:
512 result = resolve_expression(expr_loc, cont_type, e->ref);
513 result.type = e->u.tref;
514 break;
515 case EXPR_SIZEOF:
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_SHL:
521 case EXPR_SHR:
522 case EXPR_MOD:
523 case EXPR_MUL:
524 case EXPR_DIV:
525 case EXPR_ADD:
526 case EXPR_SUB:
527 case EXPR_AND:
528 case EXPR_OR:
529 case EXPR_XOR:
531 struct expression_type result_right;
532 result = resolve_expression(expr_loc, cont_type, e->ref);
533 result.is_variable = FALSE;
534 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
535 /* FIXME: these checks aren't strict enough for some of the operators */
536 check_scalar_type(expr_loc, cont_type, result.type);
537 check_scalar_type(expr_loc, cont_type, result_right.type);
538 break;
540 case EXPR_LOGOR:
541 case EXPR_LOGAND:
542 case EXPR_EQUALITY:
543 case EXPR_INEQUALITY:
544 case EXPR_GTR:
545 case EXPR_LESS:
546 case EXPR_GTREQL:
547 case EXPR_LESSEQL:
549 struct expression_type result_left, result_right;
550 result_left = resolve_expression(expr_loc, cont_type, e->ref);
551 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
552 check_scalar_type(expr_loc, cont_type, result_left.type);
553 check_scalar_type(expr_loc, cont_type, result_right.type);
554 result.is_variable = FALSE;
555 result.is_temporary = FALSE;
556 result.type = type_new_int(TYPE_BASIC_INT, 0);
557 break;
559 case EXPR_MEMBER:
560 result = resolve_expression(expr_loc, cont_type, e->ref);
561 if (result.type && is_valid_member_operand(result.type))
562 result = resolve_expression(expr_loc, result.type, e->u.ext);
563 else
564 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",
565 expr_loc->attr ? " for attribute " : "",
566 expr_loc->attr ? expr_loc->attr : "");
567 break;
568 case EXPR_COND:
570 struct expression_type result_first, result_second, result_third;
571 result_first = resolve_expression(expr_loc, cont_type, e->ref);
572 check_scalar_type(expr_loc, cont_type, result_first.type);
573 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
574 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
575 /* FIXME: determine the correct return type */
576 result = result_second;
577 result.is_variable = FALSE;
578 break;
580 case EXPR_ARRAY:
581 result = resolve_expression(expr_loc, cont_type, e->ref);
582 if (result.type && is_array(result.type))
584 struct expression_type index_result;
585 result.type = type_array_get_element(result.type);
586 index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
587 if (!index_result.type || !is_integer_type(index_result.type))
588 error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
589 expr_loc->attr ? " for attribute " : "",
590 expr_loc->attr ? expr_loc->attr : "");
592 else
593 error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n",
594 expr_loc->attr ? " for attribute " : "",
595 expr_loc->attr ? expr_loc->attr : "");
596 break;
598 return result;
601 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
603 struct expression_type expr_type;
604 expr_type = resolve_expression(expr_loc, cont_type, expr);
605 return expr_type.type;
608 void write_expr(FILE *h, const expr_t *e, int brackets,
609 int toplevel, const char *toplevel_prefix,
610 const type_t *cont_type, const char *local_var_prefix)
612 switch (e->type)
614 case EXPR_VOID:
615 break;
616 case EXPR_NUM:
617 fprintf(h, "%lu", e->u.lval);
618 break;
619 case EXPR_HEXNUM:
620 fprintf(h, "0x%lx", e->u.lval);
621 break;
622 case EXPR_DOUBLE:
623 fprintf(h, "%#.15g", e->u.dval);
624 break;
625 case EXPR_TRUEFALSE:
626 if (e->u.lval == 0)
627 fprintf(h, "FALSE");
628 else
629 fprintf(h, "TRUE");
630 break;
631 case EXPR_IDENTIFIER:
632 if (toplevel && toplevel_prefix && cont_type)
634 int found_in_cont_type;
635 find_identifier(e->u.sval, cont_type, &found_in_cont_type);
636 if (found_in_cont_type)
638 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
639 break;
642 fprintf(h, "%s%s", local_var_prefix, e->u.sval);
643 break;
644 case EXPR_STRLIT:
645 fprintf(h, "\"%s\"", e->u.sval);
646 break;
647 case EXPR_WSTRLIT:
648 fprintf(h, "L\"%s\"", e->u.sval);
649 break;
650 case EXPR_LOGNOT:
651 fprintf(h, "!");
652 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
653 break;
654 case EXPR_NOT:
655 fprintf(h, "~");
656 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
657 break;
658 case EXPR_POS:
659 fprintf(h, "+");
660 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
661 break;
662 case EXPR_NEG:
663 fprintf(h, "-");
664 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
665 break;
666 case EXPR_ADDRESSOF:
667 fprintf(h, "&");
668 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
669 break;
670 case EXPR_PPTR:
671 fprintf(h, "*");
672 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
673 break;
674 case EXPR_CAST:
675 fprintf(h, "(");
676 write_type_decl(h, e->u.tref, NULL);
677 fprintf(h, ")");
678 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
679 break;
680 case EXPR_SIZEOF:
681 fprintf(h, "sizeof(");
682 write_type_decl(h, e->u.tref, NULL);
683 fprintf(h, ")");
684 break;
685 case EXPR_SHL:
686 case EXPR_SHR:
687 case EXPR_MOD:
688 case EXPR_MUL:
689 case EXPR_DIV:
690 case EXPR_ADD:
691 case EXPR_SUB:
692 case EXPR_AND:
693 case EXPR_OR:
694 case EXPR_LOGOR:
695 case EXPR_LOGAND:
696 case EXPR_XOR:
697 case EXPR_EQUALITY:
698 case EXPR_INEQUALITY:
699 case EXPR_GTR:
700 case EXPR_LESS:
701 case EXPR_GTREQL:
702 case EXPR_LESSEQL:
703 if (brackets) fprintf(h, "(");
704 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
705 switch (e->type)
707 case EXPR_SHL: fprintf(h, " << "); break;
708 case EXPR_SHR: fprintf(h, " >> "); break;
709 case EXPR_MOD: fprintf(h, " %% "); break;
710 case EXPR_MUL: fprintf(h, " * "); break;
711 case EXPR_DIV: fprintf(h, " / "); break;
712 case EXPR_ADD: fprintf(h, " + "); break;
713 case EXPR_SUB: fprintf(h, " - "); break;
714 case EXPR_AND: fprintf(h, " & "); break;
715 case EXPR_OR: fprintf(h, " | "); break;
716 case EXPR_LOGOR: fprintf(h, " || "); break;
717 case EXPR_LOGAND: fprintf(h, " && "); break;
718 case EXPR_XOR: fprintf(h, " ^ "); break;
719 case EXPR_EQUALITY: fprintf(h, " == "); break;
720 case EXPR_INEQUALITY: fprintf(h, " != "); break;
721 case EXPR_GTR: fprintf(h, " > "); break;
722 case EXPR_LESS: fprintf(h, " < "); break;
723 case EXPR_GTREQL: fprintf(h, " >= "); break;
724 case EXPR_LESSEQL: fprintf(h, " <= "); break;
725 default: break;
727 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
728 if (brackets) fprintf(h, ")");
729 break;
730 case EXPR_MEMBER:
731 if (brackets) fprintf(h, "(");
732 if (e->ref->type == EXPR_PPTR)
734 write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
735 fprintf(h, "->");
737 else
739 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
740 fprintf(h, ".");
742 write_expr(h, e->u.ext, 1, 0, toplevel_prefix, cont_type, "");
743 if (brackets) fprintf(h, ")");
744 break;
745 case EXPR_COND:
746 if (brackets) fprintf(h, "(");
747 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
748 fprintf(h, " ? ");
749 write_expr(h, e->u.ext, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
750 fprintf(h, " : ");
751 write_expr(h, e->ext2, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
752 if (brackets) fprintf(h, ")");
753 break;
754 case EXPR_ARRAY:
755 if (brackets) fprintf(h, "(");
756 write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
757 fprintf(h, "[");
758 write_expr(h, e->u.ext, 1, 1, toplevel_prefix, cont_type, local_var_prefix);
759 fprintf(h, "]");
760 if (brackets) fprintf(h, ")");
761 break;
765 /* This is actually fairly involved to implement precisely, due to the
766 effects attributes may have and things like that. Right now this is
767 only used for optimization, so just check for a very small set of
768 criteria that guarantee the types are equivalent; assume every thing
769 else is different. */
770 static int compare_type(const type_t *a, const type_t *b)
772 if (a == b
773 || (a->name
774 && b->name
775 && strcmp(a->name, b->name) == 0))
776 return 0;
777 /* Ordering doesn't need to be implemented yet. */
778 return 1;
781 int compare_expr(const expr_t *a, const expr_t *b)
783 int ret;
785 if (a->type != b->type)
786 return a->type - b->type;
788 switch (a->type)
790 case EXPR_NUM:
791 case EXPR_HEXNUM:
792 case EXPR_TRUEFALSE:
793 return a->u.lval - b->u.lval;
794 case EXPR_DOUBLE:
795 return a->u.dval - b->u.dval;
796 case EXPR_IDENTIFIER:
797 case EXPR_STRLIT:
798 case EXPR_WSTRLIT:
799 return strcmp(a->u.sval, b->u.sval);
800 case EXPR_COND:
801 ret = compare_expr(a->ref, b->ref);
802 if (ret != 0)
803 return ret;
804 ret = compare_expr(a->u.ext, b->u.ext);
805 if (ret != 0)
806 return ret;
807 return compare_expr(a->ext2, b->ext2);
808 case EXPR_OR:
809 case EXPR_AND:
810 case EXPR_ADD:
811 case EXPR_SUB:
812 case EXPR_MOD:
813 case EXPR_MUL:
814 case EXPR_DIV:
815 case EXPR_SHL:
816 case EXPR_SHR:
817 case EXPR_MEMBER:
818 case EXPR_ARRAY:
819 case EXPR_LOGOR:
820 case EXPR_LOGAND:
821 case EXPR_XOR:
822 case EXPR_EQUALITY:
823 case EXPR_INEQUALITY:
824 case EXPR_GTR:
825 case EXPR_LESS:
826 case EXPR_GTREQL:
827 case EXPR_LESSEQL:
828 ret = compare_expr(a->ref, b->ref);
829 if (ret != 0)
830 return ret;
831 return compare_expr(a->u.ext, b->u.ext);
832 case EXPR_CAST:
833 ret = compare_type(a->u.tref, b->u.tref);
834 if (ret != 0)
835 return ret;
836 /* Fall through. */
837 case EXPR_NOT:
838 case EXPR_NEG:
839 case EXPR_PPTR:
840 case EXPR_ADDRESSOF:
841 case EXPR_LOGNOT:
842 case EXPR_POS:
843 return compare_expr(a->ref, b->ref);
844 case EXPR_SIZEOF:
845 return compare_type(a->u.tref, b->u.tref);
846 case EXPR_VOID:
847 return 0;
849 return -1;