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