widl: Insert standard windows.h and ole2.h includes to generated headers.
[wine] / tools / widl / expr.c
1 /*
2  * Expression Abstract Syntax Tree Functions
3  *
4  * Copyright 2002 Ove Kaaven
5  * Copyright 2006-2008 Robert Shearman
6  *
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.
11  *
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.
16  *
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
20  */
21
22 #include "config.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <assert.h>
28 #include <ctype.h>
29 #include <string.h>
30
31 #include "widl.h"
32 #include "utils.h"
33 #include "expr.h"
34 #include "header.h"
35 #include "typetree.h"
36 #include "typegen.h"
37
38 static int is_integer_type(const type_t *type)
39 {
40     switch (type_get_type(type))
41     {
42     case TYPE_ENUM:
43         return TRUE;
44     case TYPE_BASIC:
45         switch (type_basic_get_type(type))
46         {
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;
63         }
64         return FALSE;
65     default:
66         return FALSE;
67     }
68 }
69
70 static int is_signed_integer_type(const type_t *type)
71 {
72     switch (type_get_type(type))
73     {
74     case TYPE_ENUM:
75         return FALSE;
76     case TYPE_BASIC:
77         switch (type_basic_get_type(type))
78         {
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;
96         }
97         /* FALLTHROUGH */
98     default:
99         return FALSE;
100     }
101 }
102
103 static int is_float_type(const type_t *type)
104 {
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));
108 }
109
110 expr_t *make_expr(enum expr_type type)
111 {
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;
119 }
120
121 expr_t *make_exprl(enum expr_type type, int val)
122 {
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)
130     {
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;
135     }
136     return e;
137 }
138
139 expr_t *make_exprd(enum expr_type type, double val)
140 {
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;
148 }
149
150 expr_t *make_exprs(enum expr_type type, char *val)
151 {
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)
160     {
161     case EXPR_IDENTIFIER:
162     {
163         var_t *c = find_const(val, 0);
164         if (c)
165         {
166             e->u.sval = c->name;
167             free(val);
168             e->is_const = TRUE;
169             e->cval = c->eval->cval;
170         }
171         break;
172     }
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
179         {
180             e->is_const = TRUE;
181             e->cval = *val;
182         }
183         break;
184     default:
185         break;
186     }
187     return e;
188 }
189
190 expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
191 {
192     expr_t *e;
193     type_t *tref;
194
195     if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
196         error_loc("invalid storage class for type expression\n");
197
198     tref = var->type;
199
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)
206     {
207         /* only do this for types that should be the same on all platforms */
208         if (is_integer_type(tref) || is_float_type(tref))
209         {
210             e->is_const = TRUE;
211             e->cval = type_memsize(tref);
212         }
213     }
214     /* check for cast of constant expression */
215     if (type == EXPR_CAST && expr->is_const)
216     {
217         if (is_integer_type(tref))
218         {
219             unsigned int cast_type_bits = type_memsize(tref) * 8;
220             unsigned int cast_mask;
221
222             e->is_const = TRUE;
223             if (is_signed_integer_type(tref))
224             {
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;
230             }
231             else
232             {
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;
237             }
238         }
239         else
240         {
241             e->is_const = TRUE;
242             e->cval = expr->cval;
243         }
244     }
245     free(var);
246     return e;
247 }
248
249 expr_t *make_expr1(enum expr_type type, expr_t *expr)
250 {
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)
259     {
260         e->is_const = TRUE;
261         switch (type)
262         {
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;
278         }
279     }
280     return e;
281 }
282
283 expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
284 {
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)
293     {
294         e->is_const = TRUE;
295         switch (type)
296         {
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)
305             {
306                 error_loc("divide by zero in expression\n");
307                 e->cval = 0;
308             }
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)
317             {
318                 error_loc("divide by zero in expression\n");
319                 e->cval = 0;
320             }
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;
366         }
367     }
368     return e;
369 }
370
371 expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
372 {
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)
382     {
383         e->is_const = TRUE;
384         switch (type)
385         {
386         case EXPR_COND:
387             e->cval = expr1->cval ? expr2->cval : expr3->cval;
388             break;
389         default:
390             e->is_const = FALSE;
391             break;
392         }
393     }
394     return e;
395 }
396
397 struct expression_type
398 {
399     int is_variable; /* is the expression resolved to a variable? */
400     int is_temporary; /* should the type be freed? */
401     type_t *type;
402 };
403
404 static void check_scalar_type(const struct expr_loc *expr_loc,
405                               const type_t *cont_type, const type_t *type)
406 {
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 : "");
412 }
413
414 static void check_arithmetic_type(const struct expr_loc *expr_loc,
415                                   const type_t *cont_type, const type_t *type)
416 {
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 : "");
421 }
422
423 static void check_integer_type(const struct expr_loc *expr_loc,
424                                const type_t *cont_type, const type_t *type)
425 {
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 : "");
430 }
431
432 static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
433 {
434     type_t *type = NULL;
435     const var_t *field;
436     const var_list_t *fields = NULL;
437
438     *found_in_cont_type = 0;
439
440     if (cont_type)
441     {
442         switch (type_get_type(cont_type))
443         {
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;
469         }
470     }
471
472     if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
473         if (field->name && !strcmp(identifier, field->name))
474         {
475             type = field->type;
476             *found_in_cont_type = 1;
477             break;
478         }
479
480     if (!type)
481     {
482         var_t *const_var = find_const(identifier, 0);
483         if (const_var) type = const_var->type;
484     }
485
486     return type;
487 }
488
489 static int is_valid_member_operand(const type_t *type)
490 {
491     switch (type_get_type(type))
492     {
493     case TYPE_STRUCT:
494     case TYPE_UNION:
495     case TYPE_ENUM:
496         return TRUE;
497     default:
498         return FALSE;
499     }
500 }
501
502 static struct expression_type resolve_expression(const struct expr_loc *expr_loc,
503                                                  const type_t *cont_type,
504                                                  const expr_t *e)
505 {
506     struct expression_type result;
507     result.is_variable = FALSE;
508     result.is_temporary = FALSE;
509     result.type = NULL;
510     switch (e->type)
511     {
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:
537     {
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)
543         {
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 : "");
547         }
548         break;
549     }
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:
608     {
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;
617     }
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:
626     {
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;
635     }
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:
646     {
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;
656     }
657     case EXPR_ARRAY:
658         result = resolve_expression(expr_loc, cont_type, e->ref);
659         if (result.type && is_array(result.type))
660         {
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 : "");
668         }
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;
674     }
675     return result;
676 }
677
678 const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
679 {
680     struct expression_type expr_type;
681     expr_type = resolve_expression(expr_loc, cont_type, expr);
682     return expr_type.type;
683 }
684
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)
688 {
689     switch (e->type)
690     {
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)
710         {
711             int found_in_cont_type;
712             find_identifier(e->u.sval, cont_type, &found_in_cont_type);
713             if (found_in_cont_type)
714             {
715                 fprintf(h, "%s%s", toplevel_prefix, e->u.sval);
716                 break;
717             }
718         }
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)
786         {
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;
806         }
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)
813         {
814             write_expr(h, e->ref->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
815             fprintf(h, "->");
816         }
817         else
818         {
819             write_expr(h, e->ref, 1, toplevel, toplevel_prefix, cont_type, local_var_prefix);
820             fprintf(h, ".");
821         }
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;
842     }
843 }
844
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)
851 {
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;
859 }
860
861 int compare_expr(const expr_t *a, const expr_t *b)
862 {
863     int ret;
864
865     if (a->type != b->type)
866         return a->type - b->type;
867
868     switch (a->type)
869     {
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;
929     }
930     return -1;
931 }