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.
24 #include "expression.h"
27 static int match_oplist(int op
, ...)
33 int nextop
= va_arg(args
, int);
41 static struct token
*comma_expression(struct token
*, struct expression
**);
43 struct token
*parens_expression(struct token
*token
, struct expression
**expr
, const char *where
)
45 token
= expect(token
, '(', where
);
46 if (match_op(token
, '{')) {
47 struct expression
*e
= alloc_expression(token
->pos
, EXPR_STATEMENT
);
48 struct statement
*stmt
= alloc_statement(token
->pos
, STMT_COMPOUND
);
52 token
= compound_statement(token
->next
, stmt
);
54 token
= expect(token
, '}', "at end of statement expression");
56 token
= parse_expression(token
, expr
);
57 return expect(token
, ')', where
);
60 static struct token
*string_expression(struct token
*token
, struct expression
*expr
)
62 struct string
*string
= token
->string
;
63 struct token
*next
= token
->next
;
65 if (token_type(next
) == TOKEN_STRING
) {
66 int totlen
= string
->length
;
70 totlen
+= next
->string
->length
-1;
72 } while (token_type(next
) == TOKEN_STRING
);
74 string
= __alloc_string(totlen
);
75 string
->length
= totlen
;
79 struct string
*s
= next
->string
;
83 memcpy(data
, s
->data
, len
);
85 } while (token_type(next
) == TOKEN_STRING
);
87 expr
->string
= string
;
91 static void get_fp_value(struct expression
*expr
, struct token
*token
)
95 expr
->ctype
= &double_ctype
;
98 warn(token
->pos
, "FP values not yet implemented");
103 static void get_number_value(struct expression
*expr
, struct token
*token
)
105 const char *str
= token
->number
;
106 unsigned long long value
= 0;
107 unsigned int base
= 10, digit
, bits
;
108 unsigned long modifiers
, extramod
;
113 base
= 18; // the -= 2 for the octal case will
114 str
++; // skip the '0'
117 str
++; // skip the '0' or 'x/X'
118 base
-= 2; // the fall-through will make this 8
128 value
= value
* base
+ digit
;
134 if (c
== 'u' || c
== 'U') {
135 modifiers
|= MOD_UNSIGNED
;
138 if (c
== 'l' || c
== 'L') {
139 if (modifiers
& MOD_LONG
)
140 modifiers
|= MOD_LONGLONG
;
141 modifiers
|= MOD_LONG
;
145 get_fp_value(expr
, token
);
151 bits
= bits_in_longlong
;
153 if (!(modifiers
& MOD_LONGLONG
)) {
154 if (value
& (~1ULL << (bits_in_long
-1))) {
155 extramod
= MOD_LONGLONG
| MOD_LONG
;
158 if (!(modifiers
& MOD_LONG
)) {
159 if (value
& (~1ULL << (bits_in_int
-1))) {
166 if (!(modifiers
& MOD_UNSIGNED
)) {
167 if (value
& (1ULL << (bits
-1))) {
168 extramod
|= MOD_UNSIGNED
;
173 * Special case: "int" gets promoted directly to "long"
174 * for normal decimal numbers..
176 modifiers
|= extramod
;
177 if (base
== 10 && modifiers
== MOD_UNSIGNED
) {
178 if (bits_in_long
!= bits_in_int
)
179 modifiers
= MOD_LONG
;
182 /* Hex or octal constants don't complain about missing signedness */
183 if (base
== 10 || extramod
!= MOD_UNSIGNED
)
184 warn(expr
->pos
, "constant %s is so big it is%s%s%s",
186 (modifiers
& MOD_UNSIGNED
) ? " unsigned":"",
187 (modifiers
& MOD_LONG
) ? " long":"",
188 (modifiers
& MOD_LONGLONG
) ? " long":"");
191 expr
->type
= EXPR_VALUE
;
192 expr
->ctype
= ctype_integer(modifiers
);
196 struct token
*primary_expression(struct token
*token
, struct expression
**tree
)
198 struct expression
*expr
= NULL
;
200 switch (token_type(token
)) {
202 expr
= alloc_expression(token
->pos
, EXPR_VALUE
);
203 expr
->ctype
= &int_ctype
;
204 expr
->value
= (unsigned char) token
->character
;
209 expr
= alloc_expression(token
->pos
, EXPR_VALUE
);
210 get_number_value(expr
, token
);
215 struct symbol
*sym
= lookup_symbol(token
->ident
, NS_SYMBOL
| NS_TYPEDEF
);
216 struct token
*next
= token
->next
;
218 expr
= alloc_expression(token
->pos
, EXPR_SYMBOL
);
221 * We support types as real first-class citizens, with type
224 * if (typeof(a) == int) ..
226 if (sym
&& sym
->namespace == NS_TYPEDEF
) {
227 warn(token
->pos
, "typename in expression");
230 expr
->symbol_name
= token
->ident
;
237 expr
= alloc_expression(token
->pos
, EXPR_STRING
);
238 token
= string_expression(token
, expr
);
243 if (token
->special
== '(') {
244 expr
= alloc_expression(token
->pos
, EXPR_PREOP
);
246 token
= parens_expression(token
, &expr
->unop
, "in expression");
249 if (token
->special
== '[' && lookup_type(token
->next
)) {
250 expr
= alloc_expression(token
->pos
, EXPR_TYPE
);
251 token
= typename(token
->next
, &expr
->symbol
);
252 token
= expect(token
, ']', "in type expression");
263 static struct token
*expression_list(struct token
*token
, struct expression_list
**list
)
265 while (!match_op(token
, ')')) {
266 struct expression
*expr
= NULL
;
267 token
= assignment_expression(token
, &expr
);
270 add_expression(list
, expr
);
271 if (!match_op(token
, ','))
279 * extend to deal with the ambiguous C grammar for parsing
280 * a cast expressions followed by an initializer.
282 static struct token
*postfix_expression(struct token
*token
, struct expression
**tree
, struct expression
*cast_init_expr
)
284 struct expression
*expr
= cast_init_expr
;
287 token
= primary_expression(token
, &expr
);
289 while (expr
&& token_type(token
) == TOKEN_SPECIAL
) {
290 switch (token
->special
) {
291 case '[': { /* Array dereference */
292 struct expression
*deref
= alloc_expression(token
->pos
, EXPR_PREOP
);
293 struct expression
*add
= alloc_expression(token
->pos
, EXPR_BINOP
);
300 token
= parse_expression(token
->next
, &add
->right
);
301 token
= expect(token
, ']', "at end of array dereference");
305 case SPECIAL_INCREMENT
: /* Post-increment */
306 case SPECIAL_DECREMENT
: { /* Post-decrement */
307 struct expression
*post
= alloc_expression(token
->pos
, EXPR_POSTOP
);
308 post
->op
= token
->special
;
314 case SPECIAL_DEREFERENCE
: { /* Structure pointer member dereference */
315 /* "x->y" is just shorthand for "(*x).y" */
316 struct expression
*inner
= alloc_expression(token
->pos
, EXPR_PREOP
);
322 case '.': { /* Structure member dereference */
323 struct expression
*deref
= alloc_expression(token
->pos
, EXPR_DEREF
);
327 if (token_type(token
) != TOKEN_IDENT
) {
328 warn(token
->pos
, "Expected member name");
331 deref
->member
= token
->ident
;
337 case '(': { /* Function call */
338 struct expression
*call
= alloc_expression(token
->pos
, EXPR_CALL
);
341 token
= expression_list(token
->next
, &call
->args
);
342 token
= expect(token
, ')', "in function call");
356 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
);
357 static struct token
*unary_expression(struct token
*token
, struct expression
**tree
)
359 if (token_type(token
) == TOKEN_IDENT
&&
360 (token
->ident
== &sizeof_ident
||
361 token
->ident
== &__alignof___ident
)) {
362 struct expression
*sizeof_ex
= alloc_expression(token
->pos
, EXPR_SIZEOF
);
364 tree
= &sizeof_ex
->unop
;
366 if (!match_op(token
, '(') || !lookup_type(token
->next
))
367 return unary_expression(token
, &sizeof_ex
->cast_expression
);
368 token
= typename(token
->next
, &sizeof_ex
->cast_type
);
369 return expect(token
, ')', "at end of sizeof type-name");
372 if (token_type(token
) == TOKEN_SPECIAL
) {
373 if (match_oplist(token
->special
,
374 SPECIAL_INCREMENT
, SPECIAL_DECREMENT
,
375 '&', '*', '+', '-', '~', '!', 0)) {
376 struct expression
*unop
;
377 struct expression
*unary
;
380 next
= cast_expression(token
->next
, &unop
);
382 warn(token
->pos
, "Syntax error in unary expression");
385 unary
= alloc_expression(token
->pos
, EXPR_PREOP
);
386 unary
->op
= token
->special
;
392 /* Gcc extension: &&label gives the address of a label */
393 if (match_op(token
, SPECIAL_LOGICAL_AND
) &&
394 token_type(token
->next
) == TOKEN_IDENT
) {
395 struct expression
*label
= alloc_expression(token
->pos
, EXPR_LABEL
);
396 label
->label_symbol
= label_symbol(token
->next
);
398 return token
->next
->next
;
403 return postfix_expression(token
, tree
, NULL
);
407 * Ambiguity: a '(' can be either a cast-expression or
408 * a primary-expression depending on whether it is followed
411 * additional ambiguity: a "cast expression" followed by
412 * an initializer is really a postfix-expression.
414 static struct token
*cast_expression(struct token
*token
, struct expression
**tree
)
416 if (match_op(token
, '(')) {
417 struct token
*next
= token
->next
;
418 if (lookup_type(next
)) {
419 struct expression
*cast
= alloc_expression(next
->pos
, EXPR_CAST
);
422 token
= typename(next
, &sym
);
423 cast
->cast_type
= sym
;
424 token
= expect(token
, ')', "at end of cast operator");
425 if (match_op(token
, '{')) {
426 token
= initializer(&cast
->cast_expression
, token
);
427 return postfix_expression(token
, tree
, cast
);
430 token
= cast_expression(token
, &cast
->cast_expression
);
434 return unary_expression(token
, tree
);
438 * Generic left-to-right binop parsing
440 * This _really_ needs to be inlined, because that makes the inner
441 * function call statically deterministic rather than a totally
442 * unpredictable indirect call. But gcc-3 is so "clever" that it
443 * doesn't do so by default even when you tell it to inline it.
445 * Making it a macro avoids the inlining problem, and also means
446 * that we can pass in the op-comparison as an expression rather
447 * than create a data structure for it.
450 #define LR_BINOP_EXPRESSION(token, tree, type, inner, compare) \
451 struct expression *left = NULL; \
452 struct token * next = inner(token, &left); \
455 while (token_type(next) == TOKEN_SPECIAL) { \
456 struct expression *top, *right = NULL; \
457 int op = next->special; \
461 top = alloc_expression(next->pos, type); \
462 next = inner(next->next, &right); \
464 warn(next->pos, "No right hand side of '%s'-expression", show_special(op)); \
469 top->right = right; \
478 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
481 token
, tree
, EXPR_BINOP
, cast_expression
,
482 (op
== '*') || (op
== '/') || (op
== '%')
486 static struct token
*additive_expression(struct token
*token
, struct expression
**tree
)
489 token
, tree
, EXPR_BINOP
, multiplicative_expression
,
490 (op
== '+') || (op
== '-')
494 static struct token
*shift_expression(struct token
*token
, struct expression
**tree
)
497 token
, tree
, EXPR_BINOP
, additive_expression
,
498 (op
== SPECIAL_LEFTSHIFT
) || (op
== SPECIAL_RIGHTSHIFT
)
502 static struct token
*relational_expression(struct token
*token
, struct expression
**tree
)
505 token
, tree
, EXPR_COMPARE
, shift_expression
,
506 (op
== '<') || (op
== '>') ||
507 (op
== SPECIAL_LTE
) || (op
== SPECIAL_GTE
)
511 static struct token
*equality_expression(struct token
*token
, struct expression
**tree
)
514 token
, tree
, EXPR_COMPARE
, relational_expression
,
515 (op
== SPECIAL_EQUAL
) || (op
== SPECIAL_NOTEQUAL
)
519 static struct token
*bitwise_and_expression(struct token
*token
, struct expression
**tree
)
522 token
, tree
, EXPR_BINOP
, equality_expression
,
527 static struct token
*bitwise_xor_expression(struct token
*token
, struct expression
**tree
)
530 token
, tree
, EXPR_BINOP
, bitwise_and_expression
,
535 static struct token
*bitwise_or_expression(struct token
*token
, struct expression
**tree
)
538 token
, tree
, EXPR_BINOP
, bitwise_xor_expression
,
543 static struct token
*logical_and_expression(struct token
*token
, struct expression
**tree
)
546 token
, tree
, EXPR_LOGICAL
, bitwise_or_expression
,
547 (op
== SPECIAL_LOGICAL_AND
)
551 static struct token
*logical_or_expression(struct token
*token
, struct expression
**tree
)
554 token
, tree
, EXPR_LOGICAL
, logical_and_expression
,
555 (op
== SPECIAL_LOGICAL_OR
)
559 struct token
*conditional_expression(struct token
*token
, struct expression
**tree
)
561 token
= logical_or_expression(token
, tree
);
562 if (match_op(token
, '?')) {
563 struct expression
*expr
= alloc_expression(token
->pos
, EXPR_CONDITIONAL
);
564 expr
->op
= token
->special
;
567 token
= parse_expression(token
->next
, &expr
->cond_true
);
568 token
= expect(token
, ':', "in conditional expression");
569 token
= conditional_expression(token
, &expr
->cond_false
);
574 struct token
*assignment_expression(struct token
*token
, struct expression
**tree
)
576 token
= conditional_expression(token
, tree
);
577 if (token_type(token
) == TOKEN_SPECIAL
) {
578 static const int assignments
[] = {
580 SPECIAL_ADD_ASSIGN
, SPECIAL_SUB_ASSIGN
,
581 SPECIAL_MUL_ASSIGN
, SPECIAL_DIV_ASSIGN
,
582 SPECIAL_MOD_ASSIGN
, SPECIAL_SHL_ASSIGN
,
583 SPECIAL_SHR_ASSIGN
, SPECIAL_AND_ASSIGN
,
584 SPECIAL_OR_ASSIGN
, SPECIAL_XOR_ASSIGN
};
585 int i
, op
= token
->special
;
586 for (i
= 0; i
< sizeof(assignments
)/sizeof(int); i
++)
587 if (assignments
[i
] == op
) {
588 struct expression
* expr
= alloc_expression(token
->pos
, EXPR_ASSIGNMENT
);
592 return assignment_expression(token
->next
, &expr
->right
);
598 static struct token
*comma_expression(struct token
*token
, struct expression
**tree
)
601 token
, tree
, EXPR_COMMA
, assignment_expression
,
606 struct token
*parse_expression(struct token
*token
, struct expression
**tree
)
608 return comma_expression(token
,tree
);