4 * Copyright (C) 2003 Transmeta Corp.
7 * Licensed under the Open Software License version 1.1
9 * This is the expression parsing part of parsing C.
11 #define _ISOC99_SOURCE
27 #include "expression.h"
30 static int match_oplist(int op
, ...)
36 int nextop
= va_arg(args
, int);
44 static struct token
*comma_expression(struct token
*, struct expression
**);
46 struct token
*parens_expression(struct token
*token
, struct expression
**expr
, const char *where
)
48 token
= expect(token
, '(', where
);
49 if (match_op(token
, '{')) {
50 struct expression
*e
= alloc_expression(token
->pos
, EXPR_STATEMENT
);
51 struct statement
*stmt
= alloc_statement(token
->pos
, STMT_COMPOUND
);
55 token
= compound_statement(token
->next
, stmt
);
57 token
= expect(token
, '}', "at end of statement expression");
59 token
= parse_expression(token
, expr
);
60 return expect(token
, ')', where
);
63 static struct token
*string_expression(struct token
*token
, struct expression
*expr
)
65 struct string
*string
= token
->string
;
66 struct token
*next
= token
->next
;
68 if (token_type(next
) == TOKEN_STRING
) {
69 int totlen
= string
->length
-1;
73 totlen
+= next
->string
->length
-1;
75 } while (token_type(next
) == TOKEN_STRING
);
77 if (totlen
> MAX_STRING
) {
78 warn(token
->pos
, "trying to concatenate %d-character string (%d bytes max)", totlen
, MAX_STRING
);
82 string
= __alloc_string(totlen
+1);
83 string
->length
= totlen
+1;
87 struct string
*s
= next
->string
;
88 int len
= s
->length
-1;
95 memcpy(data
, s
->data
, len
);
97 } while (token_type(next
) == TOKEN_STRING
);
100 expr
->string
= string
;
105 #define ULLONG_MAX (~0ULL)
108 static void get_number_value(struct expression
*expr
, struct token
*token
)
110 const char *str
= token
->number
;
111 unsigned long long value
;
113 unsigned long modifiers
= 0;
114 int overflow
= 0, do_warn
= 0;
115 int try_unsigned
= 1;
119 value
= strtoull(str
, &end
, 0);
122 if (value
== ULLONG_MAX
&& errno
== ERANGE
)
129 } else if (c
== 'u' || c
== 'U') {
130 added
= MOD_UNSIGNED
;
131 } else if (c
== 'l' || c
== 'L') {
134 added
|= MOD_LONGLONG
;
139 if (modifiers
& added
)
145 /* OK, it's a valid integer */
146 /* decimals can be unsigned only if directly specified as such */
147 if (str
[0] != '0' && !(modifiers
& MOD_UNSIGNED
))
149 if (!(modifiers
& MOD_LONG
)) {
150 bits
= bits_in_int
- 1;
151 if (!(value
& (~1ULL << bits
))) {
152 if (!(value
& (1ULL << bits
))) {
154 } else if (try_unsigned
) {
155 modifiers
|= MOD_UNSIGNED
;
159 modifiers
|= MOD_LONG
;
162 if (!(modifiers
& MOD_LONGLONG
)) {
163 bits
= bits_in_long
- 1;
164 if (!(value
& (~1ULL << bits
))) {
165 if (!(value
& (1ULL << bits
))) {
167 } else if (try_unsigned
) {
168 modifiers
|= MOD_UNSIGNED
;
173 modifiers
|= MOD_LONGLONG
;
176 bits
= bits_in_longlong
- 1;
177 if (value
& (~1ULL << bits
))
179 if (!(value
& (1ULL << bits
)))
182 warn(expr
->pos
, "decimal constant %s is too big for long long",
184 modifiers
|= MOD_UNSIGNED
;
187 warn(expr
->pos
, "constant %s is so big it is%s%s%s",
189 (modifiers
& MOD_UNSIGNED
) ? " unsigned":"",
190 (modifiers
& MOD_LONG
) ? " long":"",
191 (modifiers
& MOD_LONGLONG
) ? " long":"");
194 "decimal constant %s is between LONG_MAX and ULONG_MAX."
195 " For C99 that means long long, C90 compilers are very "
196 "likely to produce unsigned long (and a warning) here",
198 expr
->type
= EXPR_VALUE
;
199 expr
->ctype
= ctype_integer(modifiers
);
203 error(expr
->pos
, "constant %s is too big even for unsigned long long",
207 expr
->fvalue
= strtold(str
, &end
);
214 if (*end
== 'f' || *end
== 'F')
215 expr
->ctype
= &float_ctype
;
216 else if (*end
== 'l' || *end
== 'L')
217 expr
->ctype
= &ldouble_ctype
;
219 expr
->ctype
= &double_ctype
;
223 expr
->type
= EXPR_FVALUE
;
227 error(expr
->pos
, "constant %s is not a valid number", show_token(token
));
230 struct token
*primary_expression(struct token
*token
, struct expression
**tree
)
232 struct expression
*expr
= NULL
;
234 switch (token_type(token
)) {
236 expr
= alloc_expression(token
->pos
, EXPR_VALUE
);
237 expr
->ctype
= &int_ctype
;
238 expr
->value
= (unsigned char) token
->character
;
243 expr
= alloc_expression(token
->pos
, EXPR_VALUE
);
244 get_number_value(expr
, token
);
249 struct symbol
*sym
= lookup_symbol(token
->ident
, NS_SYMBOL
| NS_TYPEDEF
);
250 struct token
*next
= token
->next
;
252 expr
= alloc_expression(token
->pos
, EXPR_SYMBOL
);
255 * We support types as real first-class citizens, with type
258 * if (typeof(a) == int) ..
260 if (sym
&& sym
->namespace == NS_TYPEDEF
) {
261 warn(token
->pos
, "typename in expression");
264 expr
->symbol_name
= token
->ident
;
271 expr
= alloc_expression(token
->pos
, EXPR_STRING
);
272 token
= string_expression(token
, expr
);
277 if (token
->special
== '(') {
278 expr
= alloc_expression(token
->pos
, EXPR_PREOP
);
280 token
= parens_expression(token
, &expr
->unop
, "in expression");
283 if (token
->special
== '[' && lookup_type(token
->next
)) {
284 expr
= alloc_expression(token
->pos
, EXPR_TYPE
);
285 token
= typename(token
->next
, &expr
->symbol
);
286 token
= expect(token
, ']', "in type expression");
297 static struct token
*expression_list(struct token
*token
, struct expression_list
**list
)
299 while (!match_op(token
, ')')) {
300 struct expression
*expr
= NULL
;
301 token
= assignment_expression(token
, &expr
);
304 add_expression(list
, expr
);
305 if (!match_op(token
, ','))
313 * extend to deal with the ambiguous C grammar for parsing
314 * a cast expressions followed by an initializer.
316 static struct token
*postfix_expression(struct token
*token
, struct expression
**tree
, struct expression
*cast_init_expr
)
318 struct expression
*expr
= cast_init_expr
;
321 token
= primary_expression(token
, &expr
);
323 while (expr
&& token_type(token
) == TOKEN_SPECIAL
) {
324 switch (token
->special
) {
325 case '[': { /* Array dereference */
326 struct expression
*deref
= alloc_expression(token
->pos
, EXPR_PREOP
);
327 struct expression
*add
= alloc_expression(token
->pos
, EXPR_BINOP
);
334 token
= parse_expression(token
->next
, &add
->right
);
335 token
= expect(token
, ']', "at end of array dereference");
339 case SPECIAL_INCREMENT
: /* Post-increment */
340 case SPECIAL_DECREMENT
: { /* Post-decrement */
341 struct expression
*post
= alloc_expression(token
->pos
, EXPR_POSTOP
);
342 post
->op
= token
->special
;
348 case SPECIAL_DEREFERENCE
: { /* Structure pointer member dereference */
349 /* "x->y" is just shorthand for "(*x).y" */
350 struct expression
*inner
= alloc_expression(token
->pos
, EXPR_PREOP
);
356 case '.': { /* Structure member dereference */
357 struct expression
*deref
= alloc_expression(token
->pos
, EXPR_DEREF
);
361 if (token_type(token
) != TOKEN_IDENT
) {
362 warn(token
->pos
, "Expected member name");
365 deref
->member
= token
->ident
;
371 case '(': { /* Function call */
372 struct expression
*call
= alloc_expression(token
->pos
, EXPR_CALL
);
375 token
= expression_list(token
->next
, &call
->args
);
376 token
= expect(token
, ')', "in function call");
390 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
);
391 static struct token
*unary_expression(struct token
*token
, struct expression
**tree
)
393 if (token_type(token
) == TOKEN_IDENT
) {
394 if (token
->ident
== &sizeof_ident
) {
395 struct expression
*sizeof_ex
396 = alloc_expression(token
->pos
, EXPR_SIZEOF
);
398 tree
= &sizeof_ex
->unop
;
400 if (!match_op(token
, '(') || !lookup_type(token
->next
))
401 return unary_expression(token
, &sizeof_ex
->cast_expression
);
402 token
= typename(token
->next
, &sizeof_ex
->cast_type
);
404 if (!match_op(token
, ')'))
405 return expect(token
, ')', "at end of sizeof type-name");
409 * C99 ambiguity: the typename might have been the beginning
410 * of a typed initializer expression..
412 if (match_op(token
, '{'))
413 token
= initializer(&sizeof_ex
->cast_expression
, token
);
415 } else if (token
->ident
== &__alignof___ident
) {
416 struct expression
*alignof_ex
417 = alloc_expression(token
->pos
, EXPR_ALIGNOF
);
419 tree
= &alignof_ex
->unop
;
421 if (!match_op(token
, '(') || !lookup_type(token
->next
))
422 return unary_expression(token
, &alignof_ex
->cast_expression
);
423 token
= typename(token
->next
, &alignof_ex
->cast_type
);
424 return expect(token
, ')', "at end of alignof type-name");
428 if (token_type(token
) == TOKEN_SPECIAL
) {
429 if (match_oplist(token
->special
,
430 SPECIAL_INCREMENT
, SPECIAL_DECREMENT
,
431 '&', '*', '+', '-', '~', '!', 0)) {
432 struct expression
*unop
;
433 struct expression
*unary
;
436 next
= cast_expression(token
->next
, &unop
);
438 warn(token
->pos
, "Syntax error in unary expression");
441 unary
= alloc_expression(token
->pos
, EXPR_PREOP
);
442 unary
->op
= token
->special
;
448 /* Gcc extension: &&label gives the address of a label */
449 if (match_op(token
, SPECIAL_LOGICAL_AND
) &&
450 token_type(token
->next
) == TOKEN_IDENT
) {
451 struct expression
*label
= alloc_expression(token
->pos
, EXPR_LABEL
);
452 label
->label_symbol
= label_symbol(token
->next
);
454 return token
->next
->next
;
459 return postfix_expression(token
, tree
, NULL
);
463 * Ambiguity: a '(' can be either a cast-expression or
464 * a primary-expression depending on whether it is followed
467 * additional ambiguity: a "cast expression" followed by
468 * an initializer is really a postfix-expression.
470 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
)
472 if (match_op(token
, '(')) {
473 struct token
*next
= token
->next
;
474 if (lookup_type(next
)) {
475 struct expression
*cast
= alloc_expression(next
->pos
, EXPR_CAST
);
478 token
= typename(next
, &sym
);
479 cast
->cast_type
= sym
;
480 token
= expect(token
, ')', "at end of cast operator");
481 if (match_op(token
, '{')) {
482 token
= initializer(&cast
->cast_expression
, token
);
483 return postfix_expression(token
, tree
, cast
);
486 token
= cast_expression(token
, &cast
->cast_expression
);
490 return unary_expression(token
, tree
);
494 * Generic left-to-right binop parsing
496 * This _really_ needs to be inlined, because that makes the inner
497 * function call statically deterministic rather than a totally
498 * unpredictable indirect call. But gcc-3 is so "clever" that it
499 * doesn't do so by default even when you tell it to inline it.
501 * Making it a macro avoids the inlining problem, and also means
502 * that we can pass in the op-comparison as an expression rather
503 * than create a data structure for it.
506 #define LR_BINOP_EXPRESSION(token, tree, type, inner, compare) \
507 struct expression *left = NULL; \
508 struct token * next = inner(token, &left); \
511 while (token_type(next) == TOKEN_SPECIAL) { \
512 struct expression *top, *right = NULL; \
513 int op = next->special; \
517 top = alloc_expression(next->pos, type); \
518 next = inner(next->next, &right); \
520 warn(next->pos, "No right hand side of '%s'-expression", show_special(op)); \
525 top->right = right; \
534 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
537 token
, tree
, EXPR_BINOP
, cast_expression
,
538 (op
== '*') || (op
== '/') || (op
== '%')
542 static struct token
*additive_expression(struct token
*token
, struct expression
**tree
)
545 token
, tree
, EXPR_BINOP
, multiplicative_expression
,
546 (op
== '+') || (op
== '-')
550 static struct token
*shift_expression(struct token
*token
, struct expression
**tree
)
553 token
, tree
, EXPR_BINOP
, additive_expression
,
554 (op
== SPECIAL_LEFTSHIFT
) || (op
== SPECIAL_RIGHTSHIFT
)
558 static struct token
*relational_expression(struct token
*token
, struct expression
**tree
)
561 token
, tree
, EXPR_COMPARE
, shift_expression
,
562 (op
== '<') || (op
== '>') ||
563 (op
== SPECIAL_LTE
) || (op
== SPECIAL_GTE
)
567 static struct token
*equality_expression(struct token
*token
, struct expression
**tree
)
570 token
, tree
, EXPR_COMPARE
, relational_expression
,
571 (op
== SPECIAL_EQUAL
) || (op
== SPECIAL_NOTEQUAL
)
575 static struct token
*bitwise_and_expression(struct token
*token
, struct expression
**tree
)
578 token
, tree
, EXPR_BINOP
, equality_expression
,
583 static struct token
*bitwise_xor_expression(struct token
*token
, struct expression
**tree
)
586 token
, tree
, EXPR_BINOP
, bitwise_and_expression
,
591 static struct token
*bitwise_or_expression(struct token
*token
, struct expression
**tree
)
594 token
, tree
, EXPR_BINOP
, bitwise_xor_expression
,
599 static struct token
*logical_and_expression(struct token
*token
, struct expression
**tree
)
602 token
, tree
, EXPR_LOGICAL
, bitwise_or_expression
,
603 (op
== SPECIAL_LOGICAL_AND
)
607 static struct token
*logical_or_expression(struct token
*token
, struct expression
**tree
)
610 token
, tree
, EXPR_LOGICAL
, logical_and_expression
,
611 (op
== SPECIAL_LOGICAL_OR
)
615 struct token
*conditional_expression(struct token
*token
, struct expression
**tree
)
617 token
= logical_or_expression(token
, tree
);
618 if (match_op(token
, '?')) {
619 struct expression
*expr
= alloc_expression(token
->pos
, EXPR_CONDITIONAL
);
620 expr
->op
= token
->special
;
623 token
= parse_expression(token
->next
, &expr
->cond_true
);
624 token
= expect(token
, ':', "in conditional expression");
625 token
= conditional_expression(token
, &expr
->cond_false
);
630 struct token
*assignment_expression(struct token
*token
, struct expression
**tree
)
632 token
= conditional_expression(token
, tree
);
633 if (token_type(token
) == TOKEN_SPECIAL
) {
634 static const int assignments
[] = {
636 SPECIAL_ADD_ASSIGN
, SPECIAL_SUB_ASSIGN
,
637 SPECIAL_MUL_ASSIGN
, SPECIAL_DIV_ASSIGN
,
638 SPECIAL_MOD_ASSIGN
, SPECIAL_SHL_ASSIGN
,
639 SPECIAL_SHR_ASSIGN
, SPECIAL_AND_ASSIGN
,
640 SPECIAL_OR_ASSIGN
, SPECIAL_XOR_ASSIGN
};
641 int i
, op
= token
->special
;
642 for (i
= 0; i
< sizeof(assignments
)/sizeof(int); i
++)
643 if (assignments
[i
] == op
) {
644 struct expression
* expr
= alloc_expression(token
->pos
, EXPR_ASSIGNMENT
);
648 return assignment_expression(token
->next
, &expr
->right
);
654 static struct token
*comma_expression(struct token
*token
, struct expression
**tree
)
657 token
, tree
, EXPR_COMMA
, assignment_expression
,
662 struct token
*parse_expression(struct token
*token
, struct expression
**tree
)
664 return comma_expression(token
,tree
);