[PATCH] two-arguments ?:
[smatch.git] / expand.c
blobc02a2388eafb7734d7c69a121faf8c43960dc2a9
1 /*
2 * sparse/expand.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003 Linus Torvalds
7 * Licensed under the Open Software License version 1.1
9 * expand constant expressions.
11 #include <stdlib.h>
12 #include <stdarg.h>
13 #include <stddef.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <limits.h>
21 #include "lib.h"
22 #include "parse.h"
23 #include "token.h"
24 #include "symbol.h"
25 #include "target.h"
26 #include "expression.h"
28 /* Random cost numbers */
29 #define SIDE_EFFECTS 10000 /* The expression has side effects */
30 #define UNSAFE 100 /* The expression may be "infinitely costly" due to exceptions */
31 #define SELECT_COST 20 /* Cut-off for turning a conditional into a select */
32 #define BRANCH_COST 10 /* Cost of a conditional branch */
34 static int expand_expression(struct expression *);
35 static int expand_statement(struct statement *);
37 static int expand_symbol_expression(struct expression *expr)
39 struct symbol *sym = expr->symbol;
40 /* The cost of a symbol expression is lower for on-stack symbols */
41 return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1;
44 static long long get_longlong(struct expression *expr)
46 int no_expand = expr->ctype->ctype.modifiers & MOD_UNSIGNED;
47 long long mask = 1ULL << (expr->ctype->bit_size - 1);
48 long long value = expr->value;
49 long long ormask, andmask;
51 if (!(value & mask))
52 no_expand = 1;
53 andmask = mask | (mask-1);
54 ormask = ~andmask;
55 if (no_expand)
56 ormask = 0;
57 return (value & andmask) | ormask;
60 void cast_value(struct expression *expr, struct symbol *newtype,
61 struct expression *old, struct symbol *oldtype)
63 int old_size = oldtype->bit_size;
64 int new_size = newtype->bit_size;
65 long long value, mask;
67 if (newtype->ctype.base_type == &fp_type ||
68 oldtype->ctype.base_type == &fp_type)
69 goto Float;
71 // For pointers and integers, we can just move the value around
72 expr->type = EXPR_VALUE;
73 if (old_size == new_size) {
74 expr->value = old->value;
75 return;
78 // expand it to the full "long long" value
79 value = get_longlong(old);
81 Int:
82 // Truncate it to the new size
83 mask = 1ULL << (new_size-1);
84 mask = mask | (mask-1);
85 expr->value = value & mask;
86 return;
88 Float:
89 if (newtype->ctype.base_type != &fp_type) {
90 value = (long long)old->fvalue;
91 expr->type = EXPR_VALUE;
92 goto Int;
95 if (oldtype->ctype.base_type != &fp_type)
96 expr->fvalue = (long double)get_longlong(old);
97 else
98 expr->fvalue = old->value;
100 if (!(newtype->ctype.modifiers & MOD_LONGLONG)) {
101 if ((newtype->ctype.modifiers & MOD_LONG))
102 expr->fvalue = (double)expr->fvalue;
103 else
104 expr->fvalue = (float)expr->fvalue;
106 expr->type = EXPR_FVALUE;
109 static int check_shift_count(struct expression *expr, struct symbol *ctype, unsigned int count)
111 if (count >= ctype->bit_size) {
112 warning(expr->pos, "shift too big (%u) for type %s", count, show_typename(ctype));
113 count &= ctype->bit_size-1;
115 return count;
119 * CAREFUL! We need to get the size and sign of the
120 * result right!
122 #define CONVERT(op,s) (((op)<<1)+(s))
123 #define SIGNED(op) CONVERT(op, 1)
124 #define UNSIGNED(op) CONVERT(op, 0)
125 static int simplify_int_binop(struct expression *expr, struct symbol *ctype)
127 struct expression *left = expr->left, *right = expr->right;
128 unsigned long long v, l, r, mask;
129 signed long long sl, sr;
130 int is_signed;
132 if (right->type != EXPR_VALUE)
133 return 0;
134 r = right->value;
135 if (expr->op == SPECIAL_LEFTSHIFT || expr->op == SPECIAL_RIGHTSHIFT) {
136 r = check_shift_count(expr, ctype, r);
137 right->value = r;
139 if (left->type != EXPR_VALUE)
140 return 0;
141 l = left->value; r = right->value;
142 is_signed = !(ctype->ctype.modifiers & MOD_UNSIGNED);
143 mask = 1ULL << (ctype->bit_size-1);
144 sl = l; sr = r;
145 if (is_signed && (sl & mask))
146 sl |= ~(mask-1);
147 if (is_signed && (sr & mask))
148 sr |= ~(mask-1);
150 switch (CONVERT(expr->op,is_signed)) {
151 case SIGNED('+'):
152 case UNSIGNED('+'):
153 v = l + r;
154 break;
156 case SIGNED('-'):
157 case UNSIGNED('-'):
158 v = l - r;
159 break;
161 case SIGNED('&'):
162 case UNSIGNED('&'):
163 v = l & r;
164 break;
166 case SIGNED('|'):
167 case UNSIGNED('|'):
168 v = l | r;
169 break;
171 case SIGNED('^'):
172 case UNSIGNED('^'):
173 v = l ^ r;
174 break;
176 case SIGNED('*'):
177 v = sl * sr;
178 break;
180 case UNSIGNED('*'):
181 v = l * r;
182 break;
184 case SIGNED('/'):
185 if (!r)
186 goto Div;
187 if (l == mask && sr == -1)
188 goto Overflow;
189 v = sl / sr;
190 break;
192 case UNSIGNED('/'):
193 if (!r) goto Div;
194 v = l / r;
195 break;
197 case SIGNED('%'):
198 if (!r)
199 goto Div;
200 v = sl % sr;
201 break;
203 case UNSIGNED('%'):
204 if (!r) goto Div;
205 v = l % r;
206 break;
208 case SIGNED(SPECIAL_LEFTSHIFT):
209 case UNSIGNED(SPECIAL_LEFTSHIFT):
210 v = l << r;
211 break;
213 case SIGNED(SPECIAL_RIGHTSHIFT):
214 v = sl >> r;
215 break;
217 case UNSIGNED(SPECIAL_RIGHTSHIFT):
218 v = l >> r;
219 break;
221 default:
222 return 0;
224 mask = mask | (mask-1);
225 expr->value = v & mask;
226 expr->type = EXPR_VALUE;
227 return 1;
228 Div:
229 warning(expr->pos, "division by zero");
230 return 0;
231 Overflow:
232 warning(expr->pos, "constant integer operation overflow");
233 return 0;
236 static int simplify_cmp_binop(struct expression *expr, struct symbol *ctype)
238 struct expression *left = expr->left, *right = expr->right;
239 unsigned long long l, r, mask;
240 signed long long sl, sr;
242 if (left->type != EXPR_VALUE || right->type != EXPR_VALUE)
243 return 0;
244 l = left->value; r = right->value;
245 mask = 1ULL << (ctype->bit_size-1);
246 sl = l; sr = r;
247 if (sl & mask)
248 sl |= ~(mask-1);
249 if (sr & mask)
250 sr |= ~(mask-1);
251 switch (expr->op) {
252 case '<': expr->value = sl < sr; break;
253 case '>': expr->value = sl > sr; break;
254 case SPECIAL_LTE: expr->value = sl <= sr; break;
255 case SPECIAL_GTE: expr->value = sl >= sr; break;
256 case SPECIAL_EQUAL: expr->value = l == r; break;
257 case SPECIAL_NOTEQUAL: expr->value = l != r; break;
258 case SPECIAL_UNSIGNED_LT:expr->value = l < r; break;
259 case SPECIAL_UNSIGNED_GT:expr->value = l > r; break;
260 case SPECIAL_UNSIGNED_LTE:expr->value = l <= r; break;
261 case SPECIAL_UNSIGNED_GTE:expr->value = l >= r; break;
263 expr->type = EXPR_VALUE;
264 return 1;
267 static int simplify_float_binop(struct expression *expr)
269 struct expression *left = expr->left, *right = expr->right;
270 unsigned long mod = expr->ctype->ctype.modifiers;
271 long double l, r, res;
273 if (left->type != EXPR_FVALUE || right->type != EXPR_FVALUE)
274 return 0;
276 l = left->fvalue;
277 r = right->fvalue;
279 if (mod & MOD_LONGLONG) {
280 switch (expr->op) {
281 case '+': res = l + r; break;
282 case '-': res = l - r; break;
283 case '*': res = l * r; break;
284 case '/': if (!r) goto Div;
285 res = l / r; break;
286 default: return 0;
288 } else if (mod & MOD_LONG) {
289 switch (expr->op) {
290 case '+': res = (double) l + (double) r; break;
291 case '-': res = (double) l - (double) r; break;
292 case '*': res = (double) l * (double) r; break;
293 case '/': if (!r) goto Div;
294 res = (double) l / (double) r; break;
295 default: return 0;
297 } else {
298 switch (expr->op) {
299 case '+': res = (float)l + (float)r; break;
300 case '-': res = (float)l - (float)r; break;
301 case '*': res = (float)l * (float)r; break;
302 case '/': if (!r) goto Div;
303 res = (float)l / (float)r; break;
304 default: return 0;
307 expr->type = EXPR_FVALUE;
308 expr->fvalue = res;
309 return 1;
310 Div:
311 warning(expr->pos, "division by zero");
312 return 0;
315 static int simplify_float_cmp(struct expression *expr, struct symbol *ctype)
317 struct expression *left = expr->left, *right = expr->right;
318 long double l, r;
320 if (left->type != EXPR_FVALUE || right->type != EXPR_FVALUE)
321 return 0;
323 l = left->fvalue;
324 r = right->fvalue;
325 switch (expr->op) {
326 case '<': expr->value = l < r; break;
327 case '>': expr->value = l > r; break;
328 case SPECIAL_LTE: expr->value = l <= r; break;
329 case SPECIAL_GTE: expr->value = l >= r; break;
330 case SPECIAL_EQUAL: expr->value = l == r; break;
331 case SPECIAL_NOTEQUAL: expr->value = l != r; break;
333 expr->type = EXPR_VALUE;
334 return 1;
337 static int expand_binop(struct expression *expr)
339 int cost;
341 cost = expand_expression(expr->left);
342 cost += expand_expression(expr->right);
343 if (simplify_int_binop(expr, expr->ctype))
344 return 1;
345 if (simplify_float_binop(expr))
346 return 1;
347 return cost + 1;
350 static int expand_logical(struct expression *expr)
352 struct expression *left = expr->left;
353 struct expression *right;
354 int cost, rcost;
356 /* Do immediate short-circuiting ... */
357 cost = expand_expression(left);
358 if (left->type == EXPR_VALUE) {
359 if (expr->op == SPECIAL_LOGICAL_AND) {
360 if (!left->value) {
361 expr->type = EXPR_VALUE;
362 expr->value = 0;
363 return 0;
365 } else {
366 if (left->value) {
367 expr->type = EXPR_VALUE;
368 expr->value = 1;
369 return 0;
374 right = expr->right;
375 rcost = expand_expression(right);
376 if (left->type == EXPR_VALUE && right->type == EXPR_VALUE) {
378 * We know the left value doesn't matter, since
379 * otherwise we would have short-circuited it..
381 expr->type = EXPR_VALUE;
382 expr->value = right->value != 0;
383 return 0;
387 * If the right side is safe and cheaper than a branch,
388 * just avoid the branch and turn it into a regular binop
389 * style SAFELOGICAL.
391 if (rcost < BRANCH_COST) {
392 expr->type = EXPR_BINOP;
393 rcost -= BRANCH_COST - 1;
396 return cost + BRANCH_COST + rcost;
399 static int expand_comma(struct expression *expr)
401 int cost;
403 cost = expand_expression(expr->left);
404 cost += expand_expression(expr->right);
405 if (expr->left->type == EXPR_VALUE || expr->left->type == EXPR_FVALUE)
406 *expr = *expr->right;
407 return cost;
410 #define MOD_IGN (MOD_VOLATILE | MOD_CONST)
412 static int compare_types(int op, struct symbol *left, struct symbol *right)
414 switch (op) {
415 case SPECIAL_EQUAL:
416 return !type_difference(left, right, MOD_IGN, MOD_IGN);
417 case SPECIAL_NOTEQUAL:
418 return type_difference(left, right, MOD_IGN, MOD_IGN) != NULL;
419 case '<':
420 return left->bit_size < right->bit_size;
421 case '>':
422 return left->bit_size > right->bit_size;
423 case SPECIAL_LTE:
424 return left->bit_size <= right->bit_size;
425 case SPECIAL_GTE:
426 return left->bit_size >= right->bit_size;
428 return 0;
431 static int expand_compare(struct expression *expr)
433 struct expression *left = expr->left, *right = expr->right;
434 int cost;
436 cost = expand_expression(left);
437 cost += expand_expression(right);
439 /* Type comparison? */
440 if (left && right && left->type == EXPR_TYPE && right->type == EXPR_TYPE) {
441 int op = expr->op;
442 expr->type = EXPR_VALUE;
443 expr->value = compare_types(op, left->symbol, right->symbol);
444 return 0;
446 if (simplify_cmp_binop(expr, left->ctype))
447 return 0;
448 if (simplify_float_cmp(expr, left->ctype))
449 return 0;
450 return cost + 1;
453 static int expand_conditional(struct expression *expr)
455 struct expression *cond = expr->conditional;
456 struct expression *true = expr->cond_true;
457 struct expression *false = expr->cond_false;
458 int cost, cond_cost;
460 cond_cost = expand_expression(cond);
461 if (cond->type == EXPR_VALUE) {
462 true = true ? : cond;
463 if (!cond->value)
464 true = false;
465 *expr = *true;
466 return expand_expression(expr);
469 cost = expand_expression(true);
470 cost += expand_expression(false);
472 if (cost < SELECT_COST) {
473 expr->type = EXPR_SELECT;
474 cost -= BRANCH_COST - 1;
477 return cost + cond_cost + BRANCH_COST;
480 static int expand_assignment(struct expression *expr)
482 expand_expression(expr->left);
483 expand_expression(expr->right);
484 return SIDE_EFFECTS;
487 static int expand_addressof(struct expression *expr)
489 return expand_expression(expr->unop);
492 static int expand_dereference(struct expression *expr)
494 struct expression *unop = expr->unop;
496 expand_expression(unop);
499 * NOTE! We get a bogus warning right now for some special
500 * cases: apparently I've screwed up the optimization of
501 * a zero-offset derefence, and the ctype is wrong.
503 * Leave the warning in anyway, since this is also a good
504 * test for me to get the type evaluation right..
506 if (expr->ctype->ctype.modifiers & MOD_NODEREF)
507 warning(unop->pos, "dereference of noderef expression");
509 if (unop->type == EXPR_SYMBOL) {
510 struct symbol *sym = unop->symbol;
512 /* Const symbol with a constant initializer? */
513 if (!(sym->ctype.modifiers & (MOD_ASSIGNED | MOD_ADDRESSABLE))) {
514 struct expression *value = sym->initializer;
515 if (value) {
516 if (value->type == EXPR_VALUE) {
517 expr->type = EXPR_VALUE;
518 expr->value = value->value;
519 return 0;
520 } else if (value->type == EXPR_FVALUE) {
521 expr->type = EXPR_FVALUE;
522 expr->fvalue = value->fvalue;
523 return 0;
528 /* Direct symbol dereference? Cheap and safe */
529 return (sym->ctype.modifiers & (MOD_STATIC | MOD_EXTERN)) ? 2 : 1;
531 return UNSAFE;
534 static int simplify_preop(struct expression *expr)
536 struct expression *op = expr->unop;
537 unsigned long long v, mask;
539 if (op->type != EXPR_VALUE)
540 return 0;
542 mask = 1ULL << (expr->ctype->bit_size-1);
543 v = op->value;
544 switch (expr->op) {
545 case '+': break;
546 case '-':
547 if (v == mask && !(expr->ctype->ctype.modifiers & MOD_UNSIGNED))
548 goto Overflow;
549 v = -v;
550 break;
551 case '!': v = !v; break;
552 case '~': v = ~v; break;
553 default: return 0;
555 mask = mask | (mask-1);
556 expr->value = v & mask;
557 expr->type = EXPR_VALUE;
558 return 1;
560 Overflow:
561 warning(expr->pos, "constant integer operation overflow");
562 return 0;
565 static int simplify_float_preop(struct expression *expr)
567 struct expression *op = expr->unop;
568 long double v;
570 if (op->type != EXPR_FVALUE)
571 return 0;
572 v = op->fvalue;
573 switch (expr->op) {
574 case '+': break;
575 case '-': v = -v; break;
576 default: return 0;
578 expr->fvalue = v;
579 expr->type = EXPR_FVALUE;
580 return 1;
584 * Unary post-ops: x++ and x--
586 static int expand_postop(struct expression *expr)
588 expand_expression(expr->unop);
589 return SIDE_EFFECTS;
592 static int expand_preop(struct expression *expr)
594 int cost;
596 switch (expr->op) {
597 case '*':
598 return expand_dereference(expr);
600 case '&':
601 return expand_addressof(expr);
603 case SPECIAL_INCREMENT:
604 case SPECIAL_DECREMENT:
606 * From a type evaluation standpoint the pre-ops are
607 * the same as the postops
609 return expand_postop(expr);
611 default:
612 break;
614 cost = expand_expression(expr->unop);
616 if (simplify_preop(expr))
617 return 0;
618 if (simplify_float_preop(expr))
619 return 0;
620 return cost + 1;
623 static int expand_arguments(struct expression_list *head)
625 int cost = 0;
626 struct expression *expr;
628 FOR_EACH_PTR (head, expr) {
629 cost += expand_expression(expr);
630 } END_FOR_EACH_PTR(expr);
631 return cost;
634 static int expand_cast(struct expression *expr)
636 int cost;
637 struct expression *target = expr->cast_expression;
639 cost = expand_expression(target);
641 /* Simplify normal integer casts.. */
642 if (target->type == EXPR_VALUE || target->type == EXPR_FVALUE) {
643 cast_value(expr, expr->ctype, target, target->ctype);
644 return 0;
646 return cost + 1;
650 * expand a call expression with a symbol. This
651 * should expand builtins.
653 static int expand_symbol_call(struct expression *expr)
655 struct expression *fn = expr->fn;
656 struct symbol *ctype = fn->ctype;
658 if (fn->type != EXPR_PREOP)
659 return SIDE_EFFECTS;
661 if (ctype->op && ctype->op->expand)
662 return ctype->op->expand(expr);
664 return SIDE_EFFECTS;
667 static int expand_call(struct expression *expr)
669 int cost;
670 struct symbol *sym;
671 struct expression *fn = expr->fn;
673 cost = expand_arguments(expr->args);
674 sym = fn->ctype;
675 if (!sym) {
676 error(expr->pos, "function has no type");
677 return SIDE_EFFECTS;
679 if (sym->type == SYM_NODE)
680 return expand_symbol_call(expr);
682 return SIDE_EFFECTS;
685 static int expand_expression_list(struct expression_list *list)
687 int cost = 0;
688 struct expression *expr;
690 FOR_EACH_PTR(list, expr) {
691 cost += expand_expression(expr);
692 } END_FOR_EACH_PTR(expr);
693 return cost;
697 * We can simplify nested position expressions if
698 * this is a simple (single) positional expression.
700 static int expand_pos_expression(struct expression *expr)
702 struct expression *nested = expr->init_expr;
703 unsigned long offset = expr->init_offset;
704 int nr = expr->init_nr;
706 if (nr == 1) {
707 switch (nested->type) {
708 case EXPR_POS:
709 offset += nested->init_offset;
710 *expr = *nested;
711 expr->init_offset = offset;
712 nested = expr;
713 break;
715 case EXPR_INITIALIZER: {
716 struct expression *reuse = nested, *entry;
717 *expr = *nested;
718 FOR_EACH_PTR(expr->expr_list, entry) {
719 if (entry->type == EXPR_POS) {
720 entry->init_offset += offset;
721 } else {
722 if (!reuse) {
723 error(entry->pos, "multiple initializers at offset zero");
724 return SIDE_EFFECTS;
726 reuse->type = EXPR_POS;
727 reuse->ctype = entry->ctype;
728 reuse->init_offset = offset;
729 reuse->init_nr = 1;
730 reuse->init_expr = entry;
731 REPLACE_CURRENT_PTR(entry, reuse);
732 reuse = NULL;
734 } END_FOR_EACH_PTR(entry);
735 nested = expr;
736 break;
739 default:
740 break;
743 return expand_expression(nested);
746 static int compare_expressions(const void *_a, const void *_b)
748 const struct expression *a = _a;
749 const struct expression *b = _b;
750 int r;
752 r = (b->type != EXPR_POS) - (a->type != EXPR_POS);
753 if (r) return r;
755 if (a->init_offset < b->init_offset)
756 return -1;
757 if (a->init_offset > b->init_offset)
758 return +1;
759 /* Check bitfield offset.. */
760 a = a->init_expr;
761 b = b->init_expr;
762 if (a && b) {
763 if (a->ctype && b->ctype) {
764 if (a->ctype->bit_offset < b->ctype->bit_offset)
765 return -1;
766 return +1;
769 return 0;
772 static void sort_expression_list(struct expression_list **list)
774 sort_list((struct ptr_list **)list, compare_expressions);
777 static int expand_expression(struct expression *expr)
779 if (!expr)
780 return 0;
781 if (!expr->ctype)
782 return UNSAFE;
784 switch (expr->type) {
785 case EXPR_VALUE:
786 case EXPR_FVALUE:
787 case EXPR_STRING:
788 return 0;
789 case EXPR_TYPE:
790 case EXPR_SYMBOL:
791 return expand_symbol_expression(expr);
792 case EXPR_BINOP:
793 return expand_binop(expr);
795 case EXPR_LOGICAL:
796 return expand_logical(expr);
798 case EXPR_COMMA:
799 return expand_comma(expr);
801 case EXPR_COMPARE:
802 return expand_compare(expr);
804 case EXPR_ASSIGNMENT:
805 return expand_assignment(expr);
807 case EXPR_PREOP:
808 return expand_preop(expr);
810 case EXPR_POSTOP:
811 return expand_postop(expr);
813 case EXPR_CAST:
814 return expand_cast(expr);
816 case EXPR_CALL:
817 return expand_call(expr);
819 case EXPR_DEREF:
820 warning(expr->pos, "we should not have an EXPR_DEREF left at expansion time");
821 return UNSAFE;
823 case EXPR_BITFIELD:
824 return expand_expression(expr->address);
826 case EXPR_SELECT:
827 case EXPR_CONDITIONAL:
828 return expand_conditional(expr);
830 case EXPR_STATEMENT:
831 return expand_statement(expr->statement);
833 case EXPR_LABEL:
834 return 0;
836 case EXPR_INITIALIZER:
837 sort_expression_list(&expr->expr_list);
838 return expand_expression_list(expr->expr_list);
840 case EXPR_IDENTIFIER:
841 return UNSAFE;
843 case EXPR_INDEX:
844 return UNSAFE;
846 case EXPR_SLICE:
847 return expand_expression(expr->base) + 1;
849 case EXPR_POS:
850 return expand_pos_expression(expr);
852 case EXPR_SIZEOF:
853 case EXPR_ALIGNOF:
854 warning(expr->pos, "internal front-end error: sizeof in expansion?");
855 return UNSAFE;
857 return SIDE_EFFECTS;
860 static void expand_const_expression(struct expression *expr, const char *where)
862 if (expr) {
863 expand_expression(expr);
864 if (expr->type != EXPR_VALUE)
865 warning(expr->pos, "Expected constant expression in %s", where);
869 void expand_symbol(struct symbol *sym)
871 struct symbol *base_type;
873 if (!sym)
874 return;
875 base_type = sym->ctype.base_type;
876 if (!base_type)
877 return;
879 expand_expression(sym->initializer);
880 /* expand the body of the symbol */
881 if (base_type->type == SYM_FN) {
882 if (base_type->stmt)
883 expand_statement(base_type->stmt);
887 static void expand_return_expression(struct statement *stmt)
889 expand_expression(stmt->expression);
892 static int expand_if_statement(struct statement *stmt)
894 struct expression *expr = stmt->if_conditional;
896 if (!expr || !expr->ctype)
897 return UNSAFE;
899 expand_expression(expr);
901 /* This is only valid if nobody jumps into the "dead" side */
902 #if 0
903 /* Simplify constant conditionals without even evaluating the false side */
904 if (expr->type == EXPR_VALUE) {
905 struct statement *simple;
906 simple = expr->value ? stmt->if_true : stmt->if_false;
908 /* Nothing? */
909 if (!simple) {
910 stmt->type = STMT_NONE;
911 return 0;
913 expand_statement(simple);
914 *stmt = *simple;
915 return SIDE_EFFECTS;
917 #endif
918 expand_statement(stmt->if_true);
919 expand_statement(stmt->if_false);
920 return SIDE_EFFECTS;
923 static int expand_statement(struct statement *stmt)
925 if (!stmt)
926 return 0;
928 switch (stmt->type) {
929 case STMT_RETURN:
930 expand_return_expression(stmt);
931 return SIDE_EFFECTS;
933 case STMT_EXPRESSION:
934 return expand_expression(stmt->expression);
936 case STMT_COMPOUND: {
937 struct symbol *sym;
938 struct statement *s;
939 int cost;
941 FOR_EACH_PTR(stmt->syms, sym) {
942 expand_symbol(sym);
943 } END_FOR_EACH_PTR(sym);
944 expand_symbol(stmt->ret);
946 cost = 0;
947 FOR_EACH_PTR(stmt->stmts, s) {
948 cost += expand_statement(s);
949 } END_FOR_EACH_PTR(s);
950 return cost;
953 case STMT_IF:
954 return expand_if_statement(stmt);
956 case STMT_ITERATOR:
957 expand_expression(stmt->iterator_pre_condition);
958 expand_expression(stmt->iterator_post_condition);
959 expand_statement(stmt->iterator_pre_statement);
960 expand_statement(stmt->iterator_statement);
961 expand_statement(stmt->iterator_post_statement);
962 return SIDE_EFFECTS;
964 case STMT_SWITCH:
965 expand_expression(stmt->switch_expression);
966 expand_statement(stmt->switch_statement);
967 return SIDE_EFFECTS;
969 case STMT_CASE:
970 expand_const_expression(stmt->case_expression, "case statement");
971 expand_const_expression(stmt->case_to, "case statement");
972 expand_statement(stmt->case_statement);
973 return SIDE_EFFECTS;
975 case STMT_LABEL:
976 expand_statement(stmt->label_statement);
977 return SIDE_EFFECTS;
979 case STMT_GOTO:
980 expand_expression(stmt->goto_expression);
981 return SIDE_EFFECTS;
983 case STMT_NONE:
984 break;
985 case STMT_ASM:
986 /* FIXME! Do the asm parameter evaluation! */
987 break;
989 return SIDE_EFFECTS;
992 long long get_expression_value(struct expression *expr)
994 long long value, mask;
995 struct symbol *ctype;
997 if (!expr)
998 return 0;
999 ctype = evaluate_expression(expr);
1000 if (!ctype) {
1001 warning(expr->pos, "bad constant expression type");
1002 return 0;
1004 expand_expression(expr);
1005 if (expr->type != EXPR_VALUE) {
1006 warning(expr->pos, "bad constant expression");
1007 return 0;
1010 value = expr->value;
1011 mask = 1ULL << (ctype->bit_size-1);
1013 if (value & mask) {
1014 while (ctype->type != SYM_BASETYPE)
1015 ctype = ctype->ctype.base_type;
1016 if (!(ctype->ctype.modifiers & MOD_UNSIGNED))
1017 value = value | mask | ~(mask-1);
1019 return value;