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