4 * Copyright (C) 2003 Linus Torvalds, all rights reserved.
6 * Evaluate constant expressions.
22 #include "expression.h"
24 static int evaluate_symbol(struct expression
*expr
)
26 struct symbol
*sym
= expr
->symbol
;
27 struct symbol
*base_type
;
30 warn(expr
->token
, "undefined identifier '%s'", show_token(expr
->token
));
33 examine_symbol_type(sym
);
34 base_type
= sym
->ctype
.base_type
;
38 expr
->ctype
= base_type
;
39 examine_symbol_type(base_type
);
41 /* enum's can be turned into plain values */
42 if (base_type
->type
== SYM_ENUM
) {
43 expr
->type
= EXPR_VALUE
;
44 expr
->value
= sym
->value
;
49 static int get_int_value(struct expression
*expr
, const char *str
)
51 unsigned long long value
= 0;
52 unsigned int base
= 10, digit
, bits
;
53 unsigned long modifiers
, extramod
;
57 base
= 18; // the -= 2 for the octal case will
58 str
++; // skip the 'x'
61 str
++; // skip the 'o' or 'x/X'
62 base
-= 2; // the fall-through will make this 8
64 while ((digit
= hexval(*str
)) < base
) {
65 value
= value
* base
+ digit
;
71 if (c
== 'u' || c
== 'U') {
72 modifiers
|= MOD_UNSIGNED
;
75 if (c
== 'l' || c
== 'L') {
76 if (modifiers
& MOD_LONG
)
77 modifiers
|= MOD_LONGLONG
;
78 modifiers
|= MOD_LONG
;
84 bits
= BITS_IN_LONGLONG
;
86 if (!(modifiers
& MOD_LONGLONG
)) {
87 if (value
& (~0ULL << BITS_IN_LONG
)) {
88 extramod
= MOD_LONGLONG
| MOD_LONG
;
91 if (!(modifiers
& MOD_LONG
)) {
92 if (value
& (~0ULL << BITS_IN_INT
)) {
99 if (!(modifiers
& MOD_UNSIGNED
)) {
100 if (value
& (1ULL << (bits
-1))) {
101 extramod
|= MOD_UNSIGNED
;
106 * Special case: "int" gets promoted directly to "long"
107 * for normal decimal numbers..
109 modifiers
|= extramod
;
110 if (base
== 10 && modifiers
== MOD_UNSIGNED
) {
111 modifiers
= MOD_LONG
;
112 if (BITS_IN_LONG
== BITS_IN_INT
)
113 modifiers
= MOD_LONG
| MOD_UNSIGNED
;
115 warn(expr
->token
, "value is so big it is%s%s%s",
116 (modifiers
& MOD_UNSIGNED
) ? " unsigned":"",
117 (modifiers
& MOD_LONG
) ? " long":"",
118 (modifiers
& MOD_LONGLONG
) ? " long":"");
121 expr
->type
= EXPR_VALUE
;
122 expr
->ctype
= ctype_integer(modifiers
);
127 static int evaluate_constant(struct expression
*expr
)
129 struct token
*token
= expr
->token
;
131 switch (token
->type
) {
133 return get_int_value(expr
, token
->integer
);
136 expr
->type
= EXPR_VALUE
;
137 expr
->ctype
= &int_ctype
;
138 expr
->value
= (char) token
->character
;
141 expr
->ctype
= &string_ctype
;
144 warn(token
, "non-typed expression");
149 static struct symbol
*bigger_int_type(struct symbol
*left
, struct symbol
*right
)
151 unsigned long lmod
, rmod
, mod
;
156 if (left
->bit_size
> right
->bit_size
)
159 if (right
->bit_size
> left
->bit_size
)
162 /* Same size integers - promote to unsigned, promote to long */
163 lmod
= left
->ctype
.modifiers
;
164 rmod
= right
->ctype
.modifiers
;
170 return ctype_integer(mod
);
173 static int cast_value(struct expression
*expr
, struct symbol
*newtype
,
174 struct expression
*old
, struct symbol
*oldtype
)
176 int old_size
= oldtype
->bit_size
;
177 int new_size
= newtype
->bit_size
;
178 long long value
, mask
, ormask
, andmask
;
181 // FIXME! We don't handle FP casts of constant values yet
182 if (newtype
->ctype
.base_type
== &fp_type
)
184 if (oldtype
->ctype
.base_type
== &fp_type
)
187 // For pointers and integers, we can just move the value around
188 expr
->type
= EXPR_VALUE
;
189 if (old_size
== new_size
) {
190 expr
->value
= old
->value
;
194 // expand it to the full "long long" value
195 is_signed
= !(oldtype
->ctype
.modifiers
& MOD_UNSIGNED
);
196 mask
= 1ULL << (old_size
-1);
200 andmask
= mask
| (mask
-1);
204 value
= (value
& andmask
) | ormask
;
206 // Truncate it to the new size
207 mask
= 1ULL << (new_size
-1);
208 mask
= mask
| (mask
-1);
209 expr
->value
= value
& mask
;
213 static struct expression
* cast_to(struct expression
*old
, struct symbol
*type
)
215 struct expression
*expr
= alloc_expression(old
->token
, EXPR_CAST
);
217 expr
->cast_type
= type
;
218 expr
->cast_expression
= old
;
219 if (old
->type
== EXPR_VALUE
)
220 cast_value(expr
, type
, old
, old
->ctype
);
224 static int is_ptr_type(struct symbol
*type
)
226 return type
->type
== SYM_PTR
|| type
->type
== SYM_ARRAY
|| type
->type
== SYM_FN
;
229 static int is_int_type(struct symbol
*type
)
231 return type
->ctype
.base_type
== &int_type
;
234 static int bad_expr_type(struct expression
*expr
)
236 warn(expr
->token
, "incompatible types for operation");
240 static struct symbol
* compatible_integer_binop(struct expression
*expr
)
242 struct expression
*left
= expr
->left
, *right
= expr
->right
;
243 struct symbol
*ltype
= left
->ctype
, *rtype
= right
->ctype
;
245 /* Integer promotion? */
246 if (ltype
->type
== SYM_ENUM
)
248 if (rtype
->type
== SYM_ENUM
)
250 if (is_int_type(ltype
) && is_int_type(rtype
)) {
251 struct symbol
*ctype
= bigger_int_type(ltype
, rtype
);
253 /* Don't bother promoting same-size entities, it only adds clutter */
254 if (ltype
->bit_size
!= ctype
->bit_size
)
255 expr
->left
= cast_to(left
, ctype
);
256 if (rtype
->bit_size
!= ctype
->bit_size
)
257 expr
->right
= cast_to(right
, ctype
);
263 static int evaluate_int_binop(struct expression
*expr
)
265 struct symbol
*ctype
= compatible_integer_binop(expr
);
270 return bad_expr_type(expr
);
273 static int evaluate_ptr_add(struct expression
*expr
, struct expression
*ptr
, struct expression
*i
)
275 struct symbol
*ctype
;
276 struct symbol
*ptr_type
= ptr
->ctype
;
277 struct symbol
*i_type
= i
->ctype
;
279 if (i_type
->type
== SYM_ENUM
)
281 if (!is_int_type(i_type
))
282 return bad_expr_type(expr
);
284 ctype
= ptr_type
->ctype
.base_type
;
285 examine_symbol_type(ctype
);
287 expr
->ctype
= ptr_type
;
288 if (ctype
->bit_size
> BITS_IN_CHAR
) {
289 struct expression
*add
= expr
;
290 struct expression
*mul
= alloc_expression(expr
->token
, EXPR_BINOP
);
291 struct expression
*val
= alloc_expression(expr
->token
, EXPR_VALUE
);
293 val
->ctype
= size_t_ctype
;
294 val
->value
= ctype
->bit_size
>> 3;
297 mul
->ctype
= size_t_ctype
;
301 /* Leave 'add->op' as 'expr->op' - either '+' or '-' */
302 add
->ctype
= ptr_type
;
310 static int evaluate_plus(struct expression
*expr
)
312 struct expression
*left
= expr
->left
, *right
= expr
->right
;
313 struct symbol
*ltype
= left
->ctype
, *rtype
= right
->ctype
;
315 if (is_ptr_type(ltype
))
316 return evaluate_ptr_add(expr
, left
, right
);
318 if (is_ptr_type(rtype
))
319 return evaluate_ptr_add(expr
, right
, left
);
321 // FIXME! FP promotion
322 return evaluate_int_binop(expr
);
325 static struct symbol
*same_ptr_types(struct symbol
*a
, struct symbol
*b
)
327 a
= a
->ctype
.base_type
;
328 b
= b
->ctype
.base_type
;
330 if (a
->bit_size
!= b
->bit_size
)
333 // FIXME! We should really check a bit more..
337 static int evaluate_ptr_sub(struct expression
*expr
, struct expression
*l
, struct expression
*r
)
339 struct symbol
*ctype
;
340 struct symbol
*ltype
= l
->ctype
, *rtype
= r
->ctype
;
343 * If it is an integer subtract: the ptr add case will do the
346 if (!is_ptr_type(rtype
))
347 return evaluate_ptr_add(expr
, l
, r
);
350 ctype
= same_ptr_types(ltype
, rtype
);
352 warn(expr
->token
, "subtraction of different types can't work");
355 examine_symbol_type(ctype
);
357 expr
->ctype
= ssize_t_ctype
;
358 if (ctype
->bit_size
> BITS_IN_CHAR
) {
359 struct expression
*sub
= alloc_expression(expr
->token
, EXPR_BINOP
);
360 struct expression
*div
= expr
;
361 struct expression
*val
= alloc_expression(expr
->token
, EXPR_VALUE
);
363 val
->ctype
= size_t_ctype
;
364 val
->value
= ctype
->bit_size
>> 3;
367 sub
->ctype
= ssize_t_ctype
;
379 static int evaluate_minus(struct expression
*expr
)
381 struct expression
*left
= expr
->left
, *right
= expr
->right
;
382 struct symbol
*ltype
= left
->ctype
;
384 if (is_ptr_type(ltype
))
385 return evaluate_ptr_sub(expr
, left
, right
);
387 // FIXME! FP promotion
388 return evaluate_int_binop(expr
);
391 static int evaluate_logical(struct expression
*expr
)
393 // FIXME! Short-circuit, FP and pointers!
394 expr
->ctype
= &bool_ctype
;
398 static int evaluate_arithmetic(struct expression
*expr
)
400 // FIXME! Floating-point promotion!
401 return evaluate_int_binop(expr
);
404 static int evaluate_binop(struct expression
*expr
)
407 // addition can take ptr+int, fp and int
409 return evaluate_plus(expr
);
411 // subtraction can take ptr-ptr, fp and int
413 return evaluate_minus(expr
);
415 // Logical ops can take a lot of special stuff and have early-out
416 case SPECIAL_LOGICAL_AND
:
417 case SPECIAL_LOGICAL_OR
:
418 return evaluate_logical(expr
);
420 // Arithmetic operations can take fp and int
421 case '*': case '/': case '%':
422 return evaluate_arithmetic(expr
);
424 // The rest are integer operations (bitops)
425 // SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT
428 return evaluate_int_binop(expr
);
432 static int evaluate_comma(struct expression
*expr
)
434 expr
->ctype
= expr
->right
->ctype
;
438 static int evaluate_compare(struct expression
*expr
)
440 struct expression
*left
= expr
->left
, *right
= expr
->right
;
441 struct symbol
*ltype
= left
->ctype
, *rtype
= right
->ctype
;
444 if (is_ptr_type(ltype
) || is_ptr_type(rtype
)) {
445 expr
->ctype
= &bool_ctype
;
446 // FIXME! Check the types for compatibility
450 if (compatible_integer_binop(expr
)) {
451 expr
->ctype
= &bool_ctype
;
455 return bad_expr_type(expr
);
458 static int evaluate_assignment(struct expression
*expr
)
460 struct expression
*left
= expr
->left
, *right
= expr
->right
;
461 struct symbol
*ltype
= left
->ctype
, *rtype
= right
->ctype
;
463 // FIXME! We need to cast and check the rigth side!
464 if (ltype
->bit_size
!= rtype
->bit_size
)
465 expr
->right
= cast_to(right
, ltype
);
466 expr
->ctype
= expr
->left
->ctype
;
470 static int evaluate_preop(struct expression
*expr
)
472 struct symbol
*ctype
= expr
->unop
->ctype
;
480 if (ctype
->type
!= SYM_PTR
&& ctype
->type
!= SYM_ARRAY
) {
481 warn(expr
->token
, "cannot derefence this type");
484 examine_symbol_type(expr
->ctype
);
485 expr
->ctype
= ctype
->ctype
.base_type
;
487 warn(expr
->token
, "undefined type");
493 struct symbol
*symbol
= alloc_symbol(expr
->token
, SYM_PTR
);
494 symbol
->ctype
.base_type
= ctype
;
495 symbol
->bit_size
= BITS_IN_POINTER
;
496 symbol
->alignment
= POINTER_ALIGNMENT
;
497 expr
->ctype
= symbol
;
502 expr
->ctype
= &bool_ctype
;
511 static int evaluate_postop(struct expression
*expr
)
513 struct symbol
*ctype
= expr
->unop
->ctype
;
518 struct symbol
*find_identifier(struct ident
*ident
, struct symbol_list
*_list
, int *offset
)
520 struct ptr_list
*head
= (struct ptr_list
*)_list
;
521 struct ptr_list
*list
= head
;
527 for (i
= 0; i
< list
->nr
; i
++) {
528 struct symbol
*sym
= (struct symbol
*) list
->list
[i
];
530 if (sym
->ident
->ident
!= ident
)
532 *offset
= sym
->offset
;
535 struct symbol
*ctype
= sym
->ctype
.base_type
;
539 if (ctype
->type
!= SYM_UNION
&& ctype
->type
!= SYM_STRUCT
)
541 sub
= find_identifier(ident
, ctype
->symbol_list
, offset
);
544 *offset
+= sym
->offset
;
548 } while ((list
= list
->next
) != head
);
552 /* structure/union dereference */
553 static int evaluate_dereference(struct expression
*expr
)
556 struct symbol
*ctype
, *member
;
557 struct expression
*deref
= expr
->deref
, *add
;
558 struct token
*token
= expr
->member
;
560 if (!evaluate_expression(deref
) || !token
)
563 ctype
= deref
->ctype
;
564 if (expr
->op
== SPECIAL_DEREFERENCE
) {
565 if (ctype
->type
!= SYM_PTR
) {
566 warn(expr
->token
, "expected a pointer to a struct/union");
569 ctype
= ctype
->ctype
.base_type
;
571 if (!ctype
|| (ctype
->type
!= SYM_STRUCT
&& ctype
->type
!= SYM_UNION
)) {
572 warn(expr
->token
, "expected structure or union");
576 member
= find_identifier(token
->ident
, ctype
->symbol_list
, &offset
);
578 warn(expr
->token
, "no such struct/union member");
584 add
= alloc_expression(expr
->token
, EXPR_BINOP
);
586 add
->ctype
= &ptr_ctype
;
588 add
->right
= alloc_expression(expr
->token
, EXPR_VALUE
);
589 add
->right
->ctype
= &int_ctype
;
590 add
->right
->value
= offset
;
593 ctype
= member
->ctype
.base_type
;
594 if (ctype
->type
== SYM_BITFIELD
) {
595 expr
->type
= EXPR_BITFIELD
;
596 expr
->ctype
= ctype
->ctype
.base_type
;
597 expr
->bitpos
= member
->bit_offset
;
598 expr
->nrbits
= member
->fieldwidth
;
601 expr
->type
= EXPR_PREOP
;
610 static int evaluate_sizeof(struct expression
*expr
)
614 if (expr
->cast_type
) {
615 examine_symbol_type(expr
->cast_type
);
616 size
= expr
->cast_type
->bit_size
;
618 if (!evaluate_expression(expr
->cast_expression
))
620 size
= expr
->cast_expression
->ctype
->bit_size
;
623 warn(expr
->token
, "cannot size expression");
626 expr
->type
= EXPR_VALUE
;
627 expr
->value
= size
>> 3;
628 expr
->ctype
= size_t_ctype
;
632 static int evaluate_lvalue_expression(struct expression
*expr
)
635 return evaluate_expression(expr
);
638 static int evaluate_expression_list(struct expression_list
*head
)
641 struct ptr_list
*list
= (struct ptr_list
*)head
;
644 for (i
= 0; i
< list
->nr
; i
++) {
645 struct expression
*expr
= (struct expression
*)list
->list
[i
];
646 evaluate_expression(expr
);
648 } while ((list
= list
->next
) != (struct ptr_list
*)head
);
654 static int evaluate_cast(struct expression
*expr
)
656 struct expression
*target
= expr
->cast_expression
;
657 struct symbol
*ctype
= expr
->cast_type
;
659 if (!evaluate_expression(target
))
661 examine_symbol_type(ctype
);
664 /* Simplify normal integer casts.. */
665 if (target
->type
== EXPR_VALUE
)
666 cast_value(expr
, ctype
, target
, target
->ctype
);
670 static int evaluate_call(struct expression
*expr
)
673 struct symbol
*ctype
;
674 struct expression
*fn
= expr
->fn
;
675 struct expression_list
*arglist
= expr
->args
;
677 if (!evaluate_expression(fn
))
679 if (!evaluate_expression_list(arglist
))
682 if (ctype
->type
== SYM_PTR
)
683 ctype
= ctype
->ctype
.base_type
;
684 if (ctype
->type
!= SYM_FN
) {
685 warn(expr
->token
, "not a function");
688 args
= expression_list_size(expr
->args
);
689 fnargs
= symbol_list_size(ctype
->arguments
);
691 warn(expr
->token
, "not enough arguments for function");
692 if (args
> fnargs
&& !ctype
->variadic
)
693 warn(expr
->token
, "too many arguments for function");
694 expr
->ctype
= ctype
->ctype
.base_type
;
698 int evaluate_expression(struct expression
*expr
)
705 switch (expr
->type
) {
707 return evaluate_constant(expr
);
709 return evaluate_symbol(expr
);
711 if (!evaluate_expression(expr
->left
))
713 if (!evaluate_expression(expr
->right
))
715 return evaluate_binop(expr
);
717 if (!evaluate_expression(expr
->left
))
719 if (!evaluate_expression(expr
->right
))
721 return evaluate_comma(expr
);
723 if (!evaluate_expression(expr
->left
))
725 if (!evaluate_expression(expr
->right
))
727 return evaluate_compare(expr
);
728 case EXPR_ASSIGNMENT
:
729 if (!evaluate_lvalue_expression(expr
->left
))
731 if (!evaluate_expression(expr
->right
))
733 return evaluate_assignment(expr
);
735 if (!evaluate_expression(expr
->unop
))
737 return evaluate_preop(expr
);
739 if (!evaluate_expression(expr
->unop
))
741 return evaluate_postop(expr
);
743 return evaluate_cast(expr
);
745 return evaluate_sizeof(expr
);
747 return evaluate_dereference(expr
);
749 return evaluate_call(expr
);
756 long long get_expression_value(struct expression
*expr
)
758 long long left
, middle
, right
;
760 switch (expr
->type
) {
762 if (expr
->cast_type
) {
763 examine_symbol_type(expr
->cast_type
);
764 if (expr
->cast_type
->bit_size
& 7) {
765 warn(expr
->token
, "type has no size");
768 return expr
->cast_type
->bit_size
>> 3;
770 warn(expr
->token
, "expression sizes not yet supported");
773 evaluate_constant(expr
);
774 if (expr
->type
== EXPR_VALUE
)
778 struct symbol
*sym
= expr
->symbol
;
779 if (!sym
|| !sym
->ctype
.base_type
|| sym
->ctype
.base_type
->type
!= SYM_ENUM
) {
780 warn(expr
->token
, "undefined identifier in constant expression");
786 #define OP(x,y) case x: return left y right;
789 left
= get_expression_value(expr
->left
);
790 if (!left
&& expr
->op
== SPECIAL_LOGICAL_AND
)
792 if (left
&& expr
->op
== SPECIAL_LOGICAL_OR
)
794 right
= get_expression_value(expr
->right
);
796 OP('+',+); OP('-',-); OP('*',*); OP('/',/);
797 OP('%',%); OP('<',<); OP('>',>);
798 OP('&',&);OP('|',|);OP('^',^);
799 OP(SPECIAL_EQUAL
,==); OP(SPECIAL_NOTEQUAL
,!=);
800 OP(SPECIAL_LTE
,<=); OP(SPECIAL_LEFTSHIFT
,<<);
801 OP(SPECIAL_RIGHTSHIFT
,>>); OP(SPECIAL_GTE
,>=);
802 OP(SPECIAL_LOGICAL_AND
,&&);OP(SPECIAL_LOGICAL_OR
,||);
807 #define OP(x,y) case x: return y left;
809 left
= get_expression_value(expr
->unop
);
811 OP('+', +); OP('-', -); OP('!', !); OP('~', ~); OP('(', );
815 case EXPR_CONDITIONAL
:
816 left
= get_expression_value(expr
->conditional
);
817 if (!expr
->cond_true
)
820 middle
= get_expression_value(expr
->cond_true
);
821 right
= get_expression_value(expr
->cond_false
);
822 return left
? middle
: right
;
827 error(expr
->token
, "bad constant expression");