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