ReactOS 0.4.15-dev-7788-g1ad9096
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 e->type = type;
116 e->ref = NULL;
117 e->u.lval = 0;
118 e->is_const = FALSE;
119 e->cval = 0;
120 return e;
121}
122
124{
125 expr_t *e = xmalloc(sizeof(expr_t));
126 e->type = type;
127 e->ref = NULL;
128 e->u.lval = val;
129 e->is_const = FALSE;
130 /* check for numeric constant */
131 if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE)
132 {
133 /* make sure true/false value is valid */
134 assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
135 e->is_const = TRUE;
136 e->cval = val;
137 }
138 return e;
139}
140
142{
143 expr_t *e = xmalloc(sizeof(expr_t));
144 e->type = type;
145 e->ref = NULL;
146 e->u.dval = val;
147 e->is_const = TRUE;
148 e->cval = val;
149 return e;
150}
151
153{
154 expr_t *e;
155 e = xmalloc(sizeof(expr_t));
156 e->type = type;
157 e->ref = NULL;
158 e->u.sval = val;
159 e->is_const = FALSE;
160 /* check for predefined constants */
161 switch (type)
162 {
163 case EXPR_IDENTIFIER:
164 {
165 var_t *c = find_const(val, 0);
166 if (c)
167 {
168 e->u.sval = c->name;
169 free(val);
170 e->is_const = TRUE;
171 e->cval = c->eval->cval;
172 }
173 break;
174 }
175 case EXPR_CHARCONST:
176 if (!val[0])
177 error_loc("empty character constant\n");
178 else if (val[1])
179 error_loc("multi-character constants are endian dependent\n");
180 else
181 {
182 e->is_const = TRUE;
183 e->cval = *val;
184 }
185 break;
186 default:
187 break;
188 }
189 return e;
190}
191
193{
194 expr_t *e;
195 type_t *tref;
196
197 if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
198 error_loc("invalid storage class for type expression\n");
199
200 tref = var->type;
201
202 e = xmalloc(sizeof(expr_t));
203 e->type = type;
204 e->ref = expr;
205 e->u.tref = tref;
206 e->is_const = FALSE;
207 if (type == EXPR_SIZEOF)
208 {
209 /* only do this for types that should be the same on all platforms */
210 if (is_integer_type(tref) || is_float_type(tref))
211 {
212 e->is_const = TRUE;
213 e->cval = type_memsize(tref);
214 }
215 }
216 /* check for cast of constant expression */
217 if (type == EXPR_CAST && expr->is_const)
218 {
219 if (is_integer_type(tref))
220 {
221 unsigned int cast_type_bits = type_memsize(tref) * 8;
222 unsigned int cast_mask;
223
224 e->is_const = TRUE;
225 if (is_signed_integer_type(tref))
226 {
227 cast_mask = (1u << (cast_type_bits - 1)) - 1;
228 if (expr->cval & (1u << (cast_type_bits - 1)))
229 e->cval = -((-expr->cval) & cast_mask);
230 else
231 e->cval = expr->cval & cast_mask;
232 }
233 else
234 {
235 /* calculate ((1 << cast_type_bits) - 1) avoiding overflow */
236 cast_mask = ((1u << (cast_type_bits - 1)) - 1) |
237 1u << (cast_type_bits - 1);
238 e->cval = expr->cval & cast_mask;
239 }
240 }
241 else
242 {
243 e->is_const = TRUE;
244 e->cval = expr->cval;
245 }
246 }
247 free(var);
248 return e;
249}
250
252{
253 expr_t *e;
254 e = xmalloc(sizeof(expr_t));
255 e->type = type;
256 e->ref = expr;
257 e->u.lval = 0;
258 e->is_const = FALSE;
259 /* check for compile-time optimization */
260 if (expr->is_const)
261 {
262 e->is_const = TRUE;
263 switch (type)
264 {
265 case EXPR_LOGNOT:
266 e->cval = !expr->cval;
267 break;
268 case EXPR_POS:
269 e->cval = +expr->cval;
270 break;
271 case EXPR_NEG:
272 e->cval = -expr->cval;
273 break;
274 case EXPR_NOT:
275 e->cval = ~expr->cval;
276 break;
277 default:
278 e->is_const = FALSE;
279 break;
280 }
281 }
282 return e;
283}
284
286{
287 expr_t *e;
288 e = xmalloc(sizeof(expr_t));
289 e->type = type;
290 e->ref = expr1;
291 e->u.ext = expr2;
292 e->is_const = FALSE;
293 /* check for compile-time optimization */
294 if (expr1->is_const && expr2->is_const)
295 {
296 e->is_const = TRUE;
297 switch (type)
298 {
299 case EXPR_ADD:
300 e->cval = expr1->cval + expr2->cval;
301 break;
302 case EXPR_SUB:
303 e->cval = expr1->cval - expr2->cval;
304 break;
305 case EXPR_MOD:
306 if (expr2->cval == 0)
307 {
308 error_loc("divide by zero in expression\n");
309 e->cval = 0;
310 }
311 else
312 e->cval = expr1->cval % expr2->cval;
313 break;
314 case EXPR_MUL:
315 e->cval = expr1->cval * expr2->cval;
316 break;
317 case EXPR_DIV:
318 if (expr2->cval == 0)
319 {
320 error_loc("divide by zero in expression\n");
321 e->cval = 0;
322 }
323 else
324 e->cval = expr1->cval / expr2->cval;
325 break;
326 case EXPR_OR:
327 e->cval = expr1->cval | expr2->cval;
328 break;
329 case EXPR_AND:
330 e->cval = expr1->cval & expr2->cval;
331 break;
332 case EXPR_SHL:
333 e->cval = expr1->cval << expr2->cval;
334 break;
335 case EXPR_SHR:
336 e->cval = expr1->cval >> expr2->cval;
337 break;
338 case EXPR_LOGOR:
339 e->cval = expr1->cval || expr2->cval;
340 break;
341 case EXPR_LOGAND:
342 e->cval = expr1->cval && expr2->cval;
343 break;
344 case EXPR_XOR:
345 e->cval = expr1->cval ^ expr2->cval;
346 break;
347 case EXPR_EQUALITY:
348 e->cval = expr1->cval == expr2->cval;
349 break;
350 case EXPR_INEQUALITY:
351 e->cval = expr1->cval != expr2->cval;
352 break;
353 case EXPR_GTR:
354 e->cval = expr1->cval > expr2->cval;
355 break;
356 case EXPR_LESS:
357 e->cval = expr1->cval < expr2->cval;
358 break;
359 case EXPR_GTREQL:
360 e->cval = expr1->cval >= expr2->cval;
361 break;
362 case EXPR_LESSEQL:
363 e->cval = expr1->cval <= expr2->cval;
364 break;
365 default:
366 e->is_const = FALSE;
367 break;
368 }
369 }
370 return e;
371}
372
373expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
374{
375 expr_t *e;
376 e = xmalloc(sizeof(expr_t));
377 e->type = type;
378 e->ref = expr1;
379 e->u.ext = expr2;
380 e->ext2 = expr3;
381 e->is_const = FALSE;
382 /* check for compile-time optimization */
383 if (expr1->is_const && expr2->is_const && expr3->is_const)
384 {
385 e->is_const = TRUE;
386 switch (type)
387 {
388 case EXPR_COND:
389 e->cval = expr1->cval ? expr2->cval : expr3->cval;
390 break;
391 default:
392 e->is_const = FALSE;
393 break;
394 }
395 }
396 return e;
397}
398
400{
401 int is_variable; /* is the expression resolved to a variable? */
402 int is_temporary; /* should the type be freed? */
404};
405
406static void check_scalar_type(const struct expr_loc *expr_loc,
407 const type_t *cont_type, const type_t *type)
408{
409 if (!cont_type || (!is_integer_type(type) && !is_ptr(type) &&
411 error_loc_info(&expr_loc->v->loc_info, "scalar type required in expression%s%s\n",
412 expr_loc->attr ? " for attribute " : "",
413 expr_loc->attr ? expr_loc->attr : "");
414}
415
416static void check_arithmetic_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) && !is_float_type(type)))
420 error_loc_info(&expr_loc->v->loc_info, "arithmetic type required in expression%s%s\n",
421 expr_loc->attr ? " for attribute " : "",
422 expr_loc->attr ? expr_loc->attr : "");
423}
424
425static void check_integer_type(const struct expr_loc *expr_loc,
426 const type_t *cont_type, const type_t *type)
427{
428 if (!cont_type || !is_integer_type(type))
429 error_loc_info(&expr_loc->v->loc_info, "integer type required in expression%s%s\n",
430 expr_loc->attr ? " for attribute " : "",
431 expr_loc->attr ? expr_loc->attr : "");
432}
433
434static type_t *find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
435{
436 type_t *type = NULL;
437 const var_t *field;
438 const var_list_t *fields = NULL;
439
440 *found_in_cont_type = 0;
441
442 if (cont_type)
443 {
444 switch (type_get_type(cont_type))
445 {
446 case TYPE_FUNCTION:
447 fields = type_function_get_args(cont_type);
448 break;
449 case TYPE_STRUCT:
450 fields = type_struct_get_fields(cont_type);
451 break;
452 case TYPE_UNION:
454 fields = type_union_get_cases(cont_type);
455 break;
456 case TYPE_VOID:
457 case TYPE_BASIC:
458 case TYPE_ENUM:
459 case TYPE_MODULE:
460 case TYPE_COCLASS:
461 case TYPE_INTERFACE:
462 case TYPE_POINTER:
463 case TYPE_ARRAY:
464 case TYPE_BITFIELD:
465 /* nothing to do */
466 break;
467 case TYPE_ALIAS:
468 /* shouldn't get here because of using type_get_type above */
469 assert(0);
470 break;
471 }
472 }
473
475 if (field->name && !strcmp(identifier, field->name))
476 {
477 type = field->type;
478 *found_in_cont_type = 1;
479 break;
480 }
481
482 if (!type)
483 {
484 var_t *const_var = find_const(identifier, 0);
485 if (const_var) type = const_var->type;
486 }
487
488 return type;
489}
490
492{
493 switch (type_get_type(type))
494 {
495 case TYPE_STRUCT:
496 case TYPE_UNION:
497 case TYPE_ENUM:
498 return TRUE;
499 default:
500 return FALSE;
501 }
502}
503
505 const type_t *cont_type,
506 const expr_t *e)
507{
508 struct expression_type result;
510 result.is_temporary = FALSE;
511 result.type = NULL;
512 switch (e->type)
513 {
514 case EXPR_VOID:
515 break;
516 case EXPR_HEXNUM:
517 case EXPR_NUM:
518 case EXPR_TRUEFALSE:
519 result.is_temporary = FALSE;
521 break;
522 case EXPR_STRLIT:
523 result.is_temporary = TRUE;
525 break;
526 case EXPR_WSTRLIT:
527 result.is_temporary = TRUE;
529 break;
530 case EXPR_CHARCONST:
531 result.is_temporary = TRUE;
533 break;
534 case EXPR_DOUBLE:
535 result.is_temporary = TRUE;
537 break;
538 case EXPR_IDENTIFIER:
539 {
540 int found_in_cont_type;
541 result.is_variable = TRUE;
542 result.is_temporary = FALSE;
543 result.type = find_identifier(e->u.sval, cont_type, &found_in_cont_type);
544 if (!result.type)
545 {
546 error_loc_info(&expr_loc->v->loc_info, "identifier %s cannot be resolved in expression%s%s\n",
547 e->u.sval, expr_loc->attr ? " for attribute " : "",
548 expr_loc->attr ? expr_loc->attr : "");
549 }
550 break;
551 }
552 case EXPR_LOGNOT:
553 result = resolve_expression(expr_loc, cont_type, e->ref);
554 check_scalar_type(expr_loc, cont_type, result.type);
555 result.is_variable = FALSE;
556 result.is_temporary = FALSE;
558 break;
559 case EXPR_NOT:
560 result = resolve_expression(expr_loc, cont_type, e->ref);
561 check_integer_type(expr_loc, cont_type, result.type);
562 result.is_variable = FALSE;
563 break;
564 case EXPR_POS:
565 case EXPR_NEG:
566 result = resolve_expression(expr_loc, cont_type, e->ref);
567 check_arithmetic_type(expr_loc, cont_type, result.type);
568 result.is_variable = FALSE;
569 break;
570 case EXPR_ADDRESSOF:
571 result = resolve_expression(expr_loc, cont_type, e->ref);
572 if (!result.is_variable)
573 error_loc_info(&expr_loc->v->loc_info, "address-of operator applied to non-variable type in expression%s%s\n",
574 expr_loc->attr ? " for attribute " : "",
575 expr_loc->attr ? expr_loc->attr : "");
576 result.is_variable = FALSE;
577 result.is_temporary = TRUE;
578 result.type = type_new_pointer(FC_UP, result.type, NULL);
579 break;
580 case EXPR_PPTR:
581 result = resolve_expression(expr_loc, cont_type, e->ref);
582 if (result.type && is_ptr(result.type))
584 else if(result.type && is_array(result.type)
587 else
588 error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
589 expr_loc->attr ? " for attribute " : "",
590 expr_loc->attr ? expr_loc->attr : "");
591 break;
592 case EXPR_CAST:
593 result = resolve_expression(expr_loc, cont_type, e->ref);
594 result.type = e->u.tref;
595 break;
596 case EXPR_SIZEOF:
597 result.is_temporary = FALSE;
599 break;
600 case EXPR_SHL:
601 case EXPR_SHR:
602 case EXPR_MOD:
603 case EXPR_MUL:
604 case EXPR_DIV:
605 case EXPR_ADD:
606 case EXPR_SUB:
607 case EXPR_AND:
608 case EXPR_OR:
609 case EXPR_XOR:
610 {
611 struct expression_type result_right;
612 result = resolve_expression(expr_loc, cont_type, e->ref);
613 result.is_variable = FALSE;
614 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
615 /* FIXME: these checks aren't strict enough for some of the operators */
616 check_scalar_type(expr_loc, cont_type, result.type);
617 check_scalar_type(expr_loc, cont_type, result_right.type);
618 break;
619 }
620 case EXPR_LOGOR:
621 case EXPR_LOGAND:
622 case EXPR_EQUALITY:
623 case EXPR_INEQUALITY:
624 case EXPR_GTR:
625 case EXPR_LESS:
626 case EXPR_GTREQL:
627 case EXPR_LESSEQL:
628 {
629 struct expression_type result_left, result_right;
630 result_left = resolve_expression(expr_loc, cont_type, e->ref);
631 result_right = resolve_expression(expr_loc, cont_type, e->u.ext);
632 check_scalar_type(expr_loc, cont_type, result_left.type);
633 check_scalar_type(expr_loc, cont_type, result_right.type);
634 result.is_temporary = FALSE;
636 break;
637 }
638 case EXPR_MEMBER:
639 result = resolve_expression(expr_loc, cont_type, e->ref);
640 if (result.type && is_valid_member_operand(result.type))
641 result = resolve_expression(expr_loc, result.type, e->u.ext);
642 else
643 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",
644 expr_loc->attr ? " for attribute " : "",
645 expr_loc->attr ? expr_loc->attr : "");
646 break;
647 case EXPR_COND:
648 {
649 struct expression_type result_first, result_second, result_third;
650 result_first = resolve_expression(expr_loc, cont_type, e->ref);
651 check_scalar_type(expr_loc, cont_type, result_first.type);
652 result_second = resolve_expression(expr_loc, cont_type, e->u.ext);
653 result_third = resolve_expression(expr_loc, cont_type, e->ext2);
654 check_scalar_type(expr_loc, cont_type, result_second.type);
655 check_scalar_type(expr_loc, cont_type, result_third.type);
656 if (!is_ptr(result_second.type) ^ !is_ptr(result_third.type))
657 error_loc_info(&expr_loc->v->loc_info, "type mismatch in ?: expression\n" );
658 /* FIXME: determine the correct return type */
659 result = result_second;
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;
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
684const type_t *expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
685{
688 return expr_type.type;
689}
690
691void 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. */
856static 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
867int 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}
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
static void check_integer_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:425
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:251
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:406
int compare_expr(const expr_t *a, const expr_t *b)
Definition: expr.c:867
const type_t * expr_resolve_type(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *expr)
Definition: expr.c:684
expr_t * make_exprs(enum expr_type type, char *val)
Definition: expr.c:152
expr_t * make_exprl(enum expr_type type, int val)
Definition: expr.c:123
expr_t * make_exprt(enum expr_type type, var_t *var, expr_t *expr)
Definition: expr.c:192
static void check_arithmetic_type(const struct expr_loc *expr_loc, const type_t *cont_type, const type_t *type)
Definition: expr.c:416
static struct expression_type resolve_expression(const struct expr_loc *expr_loc, const type_t *cont_type, const expr_t *e)
Definition: expr.c:504
expr_t * make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
Definition: expr.c:373
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:691
static int is_valid_member_operand(const type_t *type)
Definition: expr.c:491
static int compare_type(const type_t *a, const type_t *b)
Definition: expr.c:856
expr_t * make_exprd(enum expr_type type, double val)
Definition: expr.c:141
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:285
static type_t * find_identifier(const char *identifier, const type_t *cont_type, int *found_in_cont_type)
Definition: expr.c:434
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
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
static int is_ptr(const type_t *t)
Definition: header.h:59
static int is_array(const type_t *t)
Definition: header.h:64
_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)
Definition: ndr_typelib.c:152
@ FC_UP
Definition: ndrtypes.h:153
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
void write_type_decl(FILE *f, type_t *t, const char *name)
Definition: header.c:561
void error_loc_info(const loc_info_t *loc_info, const char *s,...)
Definition: utils.c:85
void error_loc(const char *s,...)
Definition: utils.c:69
int is_const
Definition: widltypes.h:318
int cval
Definition: widltypes.h:319
type_t * type
Definition: widltypes.h:453
struct _loc_info_t loc_info
Definition: widltypes.h:460
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:87
type_t * type
Definition: expr.c:403
int is_temporary
Definition: expr.c:402
int is_variable
Definition: expr.c:401
Definition: parser.c:44
type_t * type_new_basic(enum type_basic_type basic_type)
Definition: typetree.c:243
type_t * type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
Definition: typetree.c:181
type_t * type_new_int(enum type_basic_type basic_type, int sign)
Definition: typetree.c:251
static int type_array_is_decl_as_ptr(const type_t *type)
Definition: typetree.h:260
static enum type_type type_get_type(const type_t *type)
Definition: typetree.h:68
static int type_basic_get_sign(const type_t *type)
Definition: typetree.h:80
static var_list_t * type_union_get_cases(const type_t *type)
Definition: typetree.h:134
static enum type_basic_type type_basic_get_type(const type_t *type)
Definition: typetree.h:73
static var_list_t * type_struct_get_fields(const type_t *type)
Definition: typetree.h:87
static type_t * type_array_get_element(const type_t *type)
Definition: typetree.h:253
static var_list_t * type_function_get_args(const type_t *type)
Definition: typetree.h:94
static type_t * type_pointer_get_ref(const type_t *type)
Definition: typetree.h:292
expr_type
int ret
@ TYPE_ENUM
Definition: widltypes.h:404
@ TYPE_BITFIELD
Definition: widltypes.h:415
@ TYPE_BASIC
Definition: widltypes.h:403
@ TYPE_UNION
Definition: widltypes.h:407
@ TYPE_ALIAS
Definition: widltypes.h:408
@ TYPE_POINTER
Definition: widltypes.h:413
@ TYPE_VOID
Definition: widltypes.h:402
@ TYPE_ENCAPSULATED_UNION
Definition: widltypes.h:406
@ TYPE_COCLASS
Definition: widltypes.h:410
@ TYPE_STRUCT
Definition: widltypes.h:405
@ TYPE_MODULE
Definition: widltypes.h:409
@ TYPE_INTERFACE
Definition: widltypes.h:412
@ TYPE_ARRAY
Definition: widltypes.h:414
@ TYPE_FUNCTION
Definition: widltypes.h:411
@ EXPR_CAST
Definition: widltypes.h:184
@ EXPR_HEXNUM
Definition: widltypes.h:178
@ EXPR_LOGOR
Definition: widltypes.h:200
@ EXPR_LOGAND
Definition: widltypes.h:201
@ EXPR_TRUEFALSE
Definition: widltypes.h:195
@ EXPR_CHARCONST
Definition: widltypes.h:213
@ EXPR_IDENTIFIER
Definition: widltypes.h:180
@ EXPR_SHR
Definition: widltypes.h:187
@ EXPR_LOGNOT
Definition: widltypes.h:209
@ EXPR_SHL
Definition: widltypes.h:186
@ EXPR_GTR
Definition: widltypes.h:205
@ EXPR_EQUALITY
Definition: widltypes.h:203
@ EXPR_INEQUALITY
Definition: widltypes.h:204
@ EXPR_POS
Definition: widltypes.h:210
@ EXPR_LESSEQL
Definition: widltypes.h:208
@ EXPR_WSTRLIT
Definition: widltypes.h:212
@ EXPR_STRLIT
Definition: widltypes.h:211
@ EXPR_NUM
Definition: widltypes.h:177
@ EXPR_PPTR
Definition: widltypes.h:183
@ EXPR_SIZEOF
Definition: widltypes.h:185
@ EXPR_GTREQL
Definition: widltypes.h:207
@ EXPR_ADDRESSOF
Definition: widltypes.h:196
@ STG_REGISTER
Definition: widltypes.h:235
@ STG_NONE
Definition: widltypes.h:232
var_t * find_const(const char *name, int f)
@ TYPE_BASIC_DOUBLE
Definition: widltypes.h:275
@ TYPE_BASIC_INT32
Definition: widltypes.h:265
@ TYPE_BASIC_ERROR_STATUS_T
Definition: widltypes.h:276
@ TYPE_BASIC_CHAR
Definition: widltypes.h:270
@ TYPE_BASIC_WCHAR
Definition: widltypes.h:273
@ TYPE_BASIC_INT16
Definition: widltypes.h:264
@ TYPE_BASIC_HYPER
Definition: widltypes.h:271
@ TYPE_BASIC_HANDLE
Definition: widltypes.h:277
@ TYPE_BASIC_INT8
Definition: widltypes.h:263
@ TYPE_BASIC_INT3264
Definition: widltypes.h:268
@ TYPE_BASIC_LONG
Definition: widltypes.h:269
@ TYPE_BASIC_INT64
Definition: widltypes.h:266
@ TYPE_BASIC_BYTE
Definition: widltypes.h:272
@ TYPE_BASIC_INT
Definition: widltypes.h:267
@ TYPE_BASIC_FLOAT
Definition: widltypes.h:274
#define const
Definition: zconf.h:233