double_checking: fix compile problem
[smatch.git] / expression.c
blob50068d9a77af5c35b05dbd7b541524224dc21eba
1 /*
2 * sparse/expression.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
7 * Licensed under the Open Software License version 1.1
9 * This is the expression parsing part of parsing C.
11 #include <stdarg.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <errno.h>
19 #include <limits.h>
21 #include "lib.h"
22 #include "allocate.h"
23 #include "token.h"
24 #include "parse.h"
25 #include "symbol.h"
26 #include "scope.h"
27 #include "expression.h"
28 #include "target.h"
29 #include "char.h"
31 static int match_oplist(int op, ...)
33 va_list args;
34 int nextop;
36 va_start(args, op);
37 do {
38 nextop = va_arg(args, int);
39 } while (nextop != 0 && nextop != op);
40 va_end(args);
42 return nextop != 0;
45 static struct token *comma_expression(struct token *, struct expression **);
47 struct token *parens_expression(struct token *token, struct expression **expr, const char *where)
49 token = expect(token, '(', where);
50 if (match_op(token, '{')) {
51 struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT);
52 struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND);
53 *expr = e;
54 e->statement = stmt;
55 start_symbol_scope(e->pos);
56 token = compound_statement(token->next, stmt);
57 end_symbol_scope();
58 token = expect(token, '}', "at end of statement expression");
59 } else
60 token = parse_expression(token, expr);
61 return expect(token, ')', where);
65 * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token
66 * conversion
68 static struct symbol *handle_func(struct token *token)
70 struct ident *ident = token->ident;
71 struct symbol *decl, *array;
72 struct string *string;
73 int len;
75 if (ident != &__func___ident &&
76 ident != &__FUNCTION___ident &&
77 ident != &__PRETTY_FUNCTION___ident)
78 return NULL;
80 if (!current_fn || !current_fn->ident)
81 return NULL;
83 /* OK, it's one of ours */
84 array = alloc_symbol(token->pos, SYM_ARRAY);
85 array->ctype.base_type = &char_ctype;
86 array->ctype.alignment = 1;
87 array->endpos = token->pos;
88 decl = alloc_symbol(token->pos, SYM_NODE);
89 decl->ctype.base_type = array;
90 decl->ctype.alignment = 1;
91 decl->ctype.modifiers = MOD_STATIC;
92 decl->endpos = token->pos;
94 /* function-scope, but in NS_SYMBOL */
95 bind_symbol(decl, ident, NS_LABEL);
96 decl->namespace = NS_SYMBOL;
98 len = current_fn->ident->len;
99 string = __alloc_string(len + 1);
100 memcpy(string->data, current_fn->ident->name, len);
101 string->data[len] = 0;
102 string->length = len + 1;
104 decl->initializer = alloc_expression(token->pos, EXPR_STRING);
105 decl->initializer->string = string;
106 decl->initializer->ctype = decl;
107 decl->array_size = alloc_const_expression(token->pos, len + 1);
108 array->array_size = decl->array_size;
109 decl->bit_size = array->bit_size = bytes_to_bits(len + 1);
111 return decl;
114 static struct token *parse_type(struct token *token, struct expression **tree)
116 struct symbol *sym;
117 *tree = alloc_expression(token->pos, EXPR_TYPE);
118 (*tree)->flags = Int_const_expr; /* sic */
119 token = typename(token, &sym, NULL);
120 if (sym->ident)
121 sparse_error(token->pos,
122 "type expression should not include identifier "
123 "\"%s\"", sym->ident->name);
124 (*tree)->symbol = sym;
125 return token;
128 static struct token *builtin_types_compatible_p_expr(struct token *token,
129 struct expression **tree)
131 struct expression *expr = alloc_expression(
132 token->pos, EXPR_COMPARE);
133 expr->flags = Int_const_expr;
134 expr->op = SPECIAL_EQUAL;
135 token = token->next;
136 if (!match_op(token, '('))
137 return expect(token, '(',
138 "after __builtin_types_compatible_p");
139 token = token->next;
140 token = parse_type(token, &expr->left);
141 if (!match_op(token, ','))
142 return expect(token, ',',
143 "in __builtin_types_compatible_p");
144 token = token->next;
145 token = parse_type(token, &expr->right);
146 if (!match_op(token, ')'))
147 return expect(token, ')',
148 "at end of __builtin_types_compatible_p");
149 token = token->next;
151 *tree = expr;
152 return token;
155 static struct token *builtin_offsetof_expr(struct token *token,
156 struct expression **tree)
158 struct expression *expr = NULL;
159 struct expression **p = &expr;
160 struct symbol *sym;
161 int op = '.';
163 token = token->next;
164 if (!match_op(token, '('))
165 return expect(token, '(', "after __builtin_offset");
167 token = token->next;
168 token = typename(token, &sym, NULL);
169 if (sym->ident)
170 sparse_error(token->pos,
171 "type expression should not include identifier "
172 "\"%s\"", sym->ident->name);
174 if (!match_op(token, ','))
175 return expect(token, ',', "in __builtin_offset");
177 while (1) {
178 struct expression *e;
179 switch (op) {
180 case ')':
181 expr->in = sym;
182 *tree = expr;
183 default:
184 return expect(token, ')', "at end of __builtin_offset");
185 case SPECIAL_DEREFERENCE:
186 e = alloc_expression(token->pos, EXPR_OFFSETOF);
187 e->flags = Int_const_expr;
188 e->op = '[';
189 *p = e;
190 p = &e->down;
191 /* fall through */
192 case '.':
193 token = token->next;
194 e = alloc_expression(token->pos, EXPR_OFFSETOF);
195 e->flags = Int_const_expr;
196 e->op = '.';
197 if (token_type(token) != TOKEN_IDENT) {
198 sparse_error(token->pos, "Expected member name");
199 return token;
201 e->ident = token->ident;
202 token = token->next;
203 break;
204 case '[':
205 token = token->next;
206 e = alloc_expression(token->pos, EXPR_OFFSETOF);
207 e->flags = Int_const_expr;
208 e->op = '[';
209 token = parse_expression(token, &e->index);
210 token = expect(token, ']',
211 "at end of array dereference");
212 if (!e->index)
213 return token;
215 *p = e;
216 p = &e->down;
217 op = token_type(token) == TOKEN_SPECIAL ? token->special : 0;
221 #ifndef ULLONG_MAX
222 #define ULLONG_MAX (~0ULL)
223 #endif
225 static unsigned long long parse_num(const char *nptr, char **end)
227 if (nptr[0] == '0' && tolower(nptr[1]) == 'b')
228 return strtoull(&nptr[2], end, 2);
229 return strtoull(nptr, end, 0);
232 static void get_number_value(struct expression *expr, struct token *token)
234 const char *str = token->number;
235 unsigned long long value;
236 char *end;
237 int size = 0, want_unsigned = 0;
238 int overflow = 0, do_warn = 0;
239 int try_unsigned = 1;
240 int bits;
242 errno = 0;
243 value = parse_num(str, &end);
244 if (end == str)
245 goto Float;
246 if (value == ULLONG_MAX && errno == ERANGE)
247 overflow = 1;
248 while (1) {
249 char c = *end++;
250 if (!c) {
251 break;
252 } else if (c == 'u' || c == 'U') {
253 if (want_unsigned)
254 goto Enoint;
255 want_unsigned = 1;
256 } else if (c == 'l' || c == 'L') {
257 if (size)
258 goto Enoint;
259 size = 1;
260 if (*end == c) {
261 size = 2;
262 end++;
264 } else
265 goto Float;
267 if (overflow)
268 goto Eoverflow;
269 /* OK, it's a valid integer */
270 /* decimals can be unsigned only if directly specified as such */
271 if (str[0] != '0' && !want_unsigned)
272 try_unsigned = 0;
273 if (!size) {
274 bits = bits_in_int - 1;
275 if (!(value & (~1ULL << bits))) {
276 if (!(value & (1ULL << bits))) {
277 goto got_it;
278 } else if (try_unsigned) {
279 want_unsigned = 1;
280 goto got_it;
283 size = 1;
284 do_warn = 1;
286 if (size < 2) {
287 bits = bits_in_long - 1;
288 if (!(value & (~1ULL << bits))) {
289 if (!(value & (1ULL << bits))) {
290 goto got_it;
291 } else if (try_unsigned) {
292 want_unsigned = 1;
293 goto got_it;
295 do_warn |= 2;
297 size = 2;
298 do_warn |= 1;
300 bits = bits_in_longlong - 1;
301 if (value & (~1ULL << bits))
302 goto Eoverflow;
303 if (!(value & (1ULL << bits)))
304 goto got_it;
305 if (!try_unsigned)
306 warning(expr->pos, "decimal constant %s is too big for long long",
307 show_token(token));
308 want_unsigned = 1;
309 got_it:
310 if (do_warn)
311 warning(expr->pos, "constant %s is so big it is%s%s%s",
312 show_token(token),
313 want_unsigned ? " unsigned":"",
314 size > 0 ? " long":"",
315 size > 1 ? " long":"");
316 if (do_warn & 2)
317 warning(expr->pos,
318 "decimal constant %s is between LONG_MAX and ULONG_MAX."
319 " For C99 that means long long, C90 compilers are very "
320 "likely to produce unsigned long (and a warning) here",
321 show_token(token));
322 expr->type = EXPR_VALUE;
323 expr->flags = Int_const_expr;
324 expr->ctype = ctype_integer(size, want_unsigned);
325 expr->value = value;
326 return;
327 Eoverflow:
328 error_die(expr->pos, "constant %s is too big even for unsigned long long",
329 show_token(token));
330 return;
331 Float:
332 expr->fvalue = string_to_ld(str, &end);
333 if (str == end)
334 goto Enoint;
336 if (*end && end[1])
337 goto Enoint;
339 if (*end == 'f' || *end == 'F')
340 expr->ctype = &float_ctype;
341 else if (*end == 'l' || *end == 'L')
342 expr->ctype = &ldouble_ctype;
343 else if (!*end)
344 expr->ctype = &double_ctype;
345 else
346 goto Enoint;
348 expr->flags = Float_literal;
349 expr->type = EXPR_FVALUE;
350 return;
352 Enoint:
353 error_die(expr->pos, "constant %s is not a valid number", show_token(token));
356 struct token *primary_expression(struct token *token, struct expression **tree)
358 struct expression *expr = NULL;
360 switch (token_type(token)) {
361 case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3:
362 expr = alloc_expression(token->pos, EXPR_VALUE);
363 expr->flags = Int_const_expr;
364 expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype;
365 get_char_constant(token, &expr->value);
366 token = token->next;
367 break;
369 case TOKEN_NUMBER:
370 expr = alloc_expression(token->pos, EXPR_VALUE);
371 get_number_value(expr, token); /* will see if it's an integer */
372 token = token->next;
373 break;
375 case TOKEN_ZERO_IDENT: {
376 expr = alloc_expression(token->pos, EXPR_SYMBOL);
377 expr->flags = Int_const_expr;
378 expr->ctype = &int_ctype;
379 expr->symbol = &zero_int;
380 expr->symbol_name = token->ident;
381 token = token->next;
382 break;
385 case TOKEN_IDENT: {
386 struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
387 struct token *next = token->next;
389 if (!sym) {
390 sym = handle_func(token);
391 if (token->ident == &__builtin_types_compatible_p_ident) {
392 token = builtin_types_compatible_p_expr(token, &expr);
393 break;
395 if (token->ident == &__builtin_offsetof_ident) {
396 token = builtin_offsetof_expr(token, &expr);
397 break;
399 } else if (sym->enum_member) {
400 expr = alloc_expression(token->pos, EXPR_VALUE);
401 *expr = *sym->initializer;
402 /* we want the right position reported, thus the copy */
403 expr->pos = token->pos;
404 expr->flags = Int_const_expr;
405 token = next;
406 break;
409 expr = alloc_expression(token->pos, EXPR_SYMBOL);
412 * We support types as real first-class citizens, with type
413 * comparisons etc:
415 * if (typeof(a) == int) ..
417 if (sym && sym->namespace == NS_TYPEDEF) {
418 sparse_error(token->pos, "typename in expression");
419 sym = NULL;
421 expr->symbol_name = token->ident;
422 expr->symbol = sym;
423 token = next;
424 break;
427 case TOKEN_STRING:
428 case TOKEN_WIDE_STRING:
429 expr = alloc_expression(token->pos, EXPR_STRING);
430 token = get_string_constant(token, expr);
431 break;
433 case TOKEN_SPECIAL:
434 if (token->special == '(') {
435 expr = alloc_expression(token->pos, EXPR_PREOP);
436 expr->op = '(';
437 token = parens_expression(token, &expr->unop, "in expression");
438 if (expr->unop)
439 expr->flags = expr->unop->flags;
440 break;
442 if (token->special == '[' && lookup_type(token->next)) {
443 expr = alloc_expression(token->pos, EXPR_TYPE);
444 expr->flags = Int_const_expr; /* sic */
445 token = typename(token->next, &expr->symbol, NULL);
446 token = expect(token, ']', "in type expression");
447 break;
450 default:
453 *tree = expr;
454 return token;
457 static struct token *expression_list(struct token *token, struct expression_list **list)
459 while (!match_op(token, ')')) {
460 struct expression *expr = NULL;
461 token = assignment_expression(token, &expr);
462 if (!expr)
463 break;
464 add_expression(list, expr);
465 if (!match_op(token, ','))
466 break;
467 token = token->next;
469 return token;
473 * extend to deal with the ambiguous C grammar for parsing
474 * a cast expressions followed by an initializer.
476 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
478 struct expression *expr = cast_init_expr;
480 if (!expr)
481 token = primary_expression(token, &expr);
483 while (expr && token_type(token) == TOKEN_SPECIAL) {
484 switch (token->special) {
485 case '[': { /* Array dereference */
486 struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
487 struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
489 deref->op = '*';
490 deref->unop = add;
492 add->op = '+';
493 add->left = expr;
494 token = parse_expression(token->next, &add->right);
495 token = expect(token, ']', "at end of array dereference");
496 expr = deref;
497 continue;
499 case SPECIAL_INCREMENT: /* Post-increment */
500 case SPECIAL_DECREMENT: { /* Post-decrement */
501 struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
502 post->op = token->special;
503 post->unop = expr;
504 expr = post;
505 token = token->next;
506 continue;
508 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
509 /* "x->y" is just shorthand for "(*x).y" */
510 struct expression *inner = alloc_expression(token->pos, EXPR_PREOP);
511 inner->op = '*';
512 inner->unop = expr;
513 expr = inner;
515 /* Fall through!! */
516 case '.': { /* Structure member dereference */
517 struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
518 deref->op = '.';
519 deref->deref = expr;
520 token = token->next;
521 if (token_type(token) != TOKEN_IDENT) {
522 sparse_error(token->pos, "Expected member name");
523 break;
525 deref->member = token->ident;
526 token = token->next;
527 expr = deref;
528 continue;
531 case '(': { /* Function call */
532 struct expression *call = alloc_expression(token->pos, EXPR_CALL);
533 call->op = '(';
534 call->fn = expr;
535 token = expression_list(token->next, &call->args);
536 token = expect(token, ')', "in function call");
537 expr = call;
538 continue;
541 default:
542 break;
544 break;
546 *tree = expr;
547 return token;
550 static struct token *cast_expression(struct token *token, struct expression **tree);
551 static struct token *unary_expression(struct token *token, struct expression **tree);
553 static struct token *type_info_expression(struct token *token,
554 struct expression **tree, int type)
556 struct expression *expr = alloc_expression(token->pos, type);
557 struct token *p;
559 *tree = expr;
560 expr->flags = Int_const_expr; /* XXX: VLA support will need that changed */
561 token = token->next;
562 if (!match_op(token, '(') || !lookup_type(token->next))
563 return unary_expression(token, &expr->cast_expression);
564 p = token;
565 token = typename(token->next, &expr->cast_type, NULL);
567 if (!match_op(token, ')')) {
568 static const char * error[] = {
569 [EXPR_SIZEOF] = "at end of sizeof",
570 [EXPR_ALIGNOF] = "at end of __alignof__",
571 [EXPR_PTRSIZEOF] = "at end of __sizeof_ptr__"
573 return expect(token, ')', error[type]);
576 token = token->next;
578 * C99 ambiguity: the typename might have been the beginning
579 * of a typed initializer expression..
581 if (match_op(token, '{')) {
582 struct expression *cast = alloc_expression(p->pos, EXPR_CAST);
583 cast->cast_type = expr->cast_type;
584 expr->cast_type = NULL;
585 expr->cast_expression = cast;
586 token = initializer(&cast->cast_expression, token);
587 token = postfix_expression(token, &expr->cast_expression, cast);
589 return token;
592 static struct token *unary_expression(struct token *token, struct expression **tree)
594 if (token_type(token) == TOKEN_IDENT) {
595 struct ident *ident = token->ident;
596 if (ident->reserved) {
597 static const struct {
598 struct ident *id;
599 int type;
600 } type_information[] = {
601 { &sizeof_ident, EXPR_SIZEOF },
602 { &__alignof___ident, EXPR_ALIGNOF },
603 { &__alignof_ident, EXPR_ALIGNOF },
604 { &__sizeof_ptr___ident, EXPR_PTRSIZEOF },
606 int i;
607 for (i = 0; i < ARRAY_SIZE(type_information); i++) {
608 if (ident == type_information[i].id)
609 return type_info_expression(token, tree, type_information[i].type);
614 if (token_type(token) == TOKEN_SPECIAL) {
615 if (match_oplist(token->special,
616 SPECIAL_INCREMENT, SPECIAL_DECREMENT,
617 '&', '*', 0)) {
618 struct expression *unop;
619 struct expression *unary;
620 struct token *next;
622 next = cast_expression(token->next, &unop);
623 if (!unop) {
624 sparse_error(token->pos, "Syntax error in unary expression");
625 *tree = NULL;
626 return next;
628 unary = alloc_expression(token->pos, EXPR_PREOP);
629 unary->op = token->special;
630 unary->unop = unop;
631 *tree = unary;
632 return next;
634 /* possibly constant ones */
635 if (match_oplist(token->special, '+', '-', '~', '!', 0)) {
636 struct expression *unop;
637 struct expression *unary;
638 struct token *next;
640 next = cast_expression(token->next, &unop);
641 if (!unop) {
642 sparse_error(token->pos, "Syntax error in unary expression");
643 *tree = NULL;
644 return next;
646 unary = alloc_expression(token->pos, EXPR_PREOP);
647 unary->op = token->special;
648 unary->unop = unop;
649 unary->flags = unop->flags & Int_const_expr;
650 *tree = unary;
651 return next;
653 /* Gcc extension: &&label gives the address of a label */
654 if (match_op(token, SPECIAL_LOGICAL_AND) &&
655 token_type(token->next) == TOKEN_IDENT) {
656 struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
657 struct symbol *sym = label_symbol(token->next);
658 if (!(sym->ctype.modifiers & MOD_ADDRESSABLE)) {
659 sym->ctype.modifiers |= MOD_ADDRESSABLE;
660 add_symbol(&function_computed_target_list, sym);
662 label->label_symbol = sym;
663 *tree = label;
664 return token->next->next;
669 return postfix_expression(token, tree, NULL);
673 * Ambiguity: a '(' can be either a cast-expression or
674 * a primary-expression depending on whether it is followed
675 * by a type or not.
677 * additional ambiguity: a "cast expression" followed by
678 * an initializer is really a postfix-expression.
680 static struct token *cast_expression(struct token *token, struct expression **tree)
682 if (match_op(token, '(')) {
683 struct token *next = token->next;
684 if (lookup_type(next)) {
685 struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
686 struct expression *v;
687 struct symbol *sym;
688 int is_force;
690 token = typename(next, &sym, &is_force);
691 cast->cast_type = sym;
692 token = expect(token, ')', "at end of cast operator");
693 if (match_op(token, '{')) {
694 if (is_force)
695 warning(sym->pos,
696 "[force] in compound literal");
697 token = initializer(&cast->cast_expression, token);
698 return postfix_expression(token, tree, cast);
700 *tree = cast;
701 if (is_force)
702 cast->type = EXPR_FORCE_CAST;
703 token = cast_expression(token, &v);
704 if (!v)
705 return token;
706 cast->cast_expression = v;
707 if (v->flags & Int_const_expr)
708 cast->flags = Int_const_expr;
709 else if (v->flags & Float_literal) /* and _not_ int */
710 cast->flags = Int_const_expr | Float_literal;
711 return token;
714 return unary_expression(token, tree);
718 * Generic left-to-right binop parsing
720 * This _really_ needs to be inlined, because that makes the inner
721 * function call statically deterministic rather than a totally
722 * unpredictable indirect call. But gcc-3 is so "clever" that it
723 * doesn't do so by default even when you tell it to inline it.
725 * Making it a macro avoids the inlining problem, and also means
726 * that we can pass in the op-comparison as an expression rather
727 * than create a data structure for it.
730 #define LR_BINOP_EXPRESSION(__token, tree, type, inner, compare) \
731 struct expression *left = NULL; \
732 struct token * next = inner(__token, &left); \
734 if (left) { \
735 while (token_type(next) == TOKEN_SPECIAL) { \
736 struct expression *top, *right = NULL; \
737 int op = next->special; \
739 if (!(compare)) \
740 goto out; \
741 top = alloc_expression(next->pos, type); \
742 next = inner(next->next, &right); \
743 if (!right) { \
744 sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op)); \
745 break; \
747 top->flags = left->flags & right->flags \
748 & Int_const_expr; \
749 top->op = op; \
750 top->left = left; \
751 top->right = right; \
752 left = top; \
755 out: \
756 *tree = left; \
757 return next; \
759 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
761 LR_BINOP_EXPRESSION(
762 token, tree, EXPR_BINOP, cast_expression,
763 (op == '*') || (op == '/') || (op == '%')
767 static struct token *additive_expression(struct token *token, struct expression **tree)
769 LR_BINOP_EXPRESSION(
770 token, tree, EXPR_BINOP, multiplicative_expression,
771 (op == '+') || (op == '-')
775 static struct token *shift_expression(struct token *token, struct expression **tree)
777 LR_BINOP_EXPRESSION(
778 token, tree, EXPR_BINOP, additive_expression,
779 (op == SPECIAL_LEFTSHIFT) || (op == SPECIAL_RIGHTSHIFT)
783 static struct token *relational_expression(struct token *token, struct expression **tree)
785 LR_BINOP_EXPRESSION(
786 token, tree, EXPR_COMPARE, shift_expression,
787 (op == '<') || (op == '>') ||
788 (op == SPECIAL_LTE) || (op == SPECIAL_GTE)
792 static struct token *equality_expression(struct token *token, struct expression **tree)
794 LR_BINOP_EXPRESSION(
795 token, tree, EXPR_COMPARE, relational_expression,
796 (op == SPECIAL_EQUAL) || (op == SPECIAL_NOTEQUAL)
800 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
802 LR_BINOP_EXPRESSION(
803 token, tree, EXPR_BINOP, equality_expression,
804 (op == '&')
808 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
810 LR_BINOP_EXPRESSION(
811 token, tree, EXPR_BINOP, bitwise_and_expression,
812 (op == '^')
816 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
818 LR_BINOP_EXPRESSION(
819 token, tree, EXPR_BINOP, bitwise_xor_expression,
820 (op == '|')
824 static struct token *logical_and_expression(struct token *token, struct expression **tree)
826 LR_BINOP_EXPRESSION(
827 token, tree, EXPR_LOGICAL, bitwise_or_expression,
828 (op == SPECIAL_LOGICAL_AND)
832 static struct token *logical_or_expression(struct token *token, struct expression **tree)
834 LR_BINOP_EXPRESSION(
835 token, tree, EXPR_LOGICAL, logical_and_expression,
836 (op == SPECIAL_LOGICAL_OR)
840 struct token *conditional_expression(struct token *token, struct expression **tree)
842 token = logical_or_expression(token, tree);
843 if (*tree && match_op(token, '?')) {
844 struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
845 expr->op = token->special;
846 expr->left = *tree;
847 *tree = expr;
848 token = parse_expression(token->next, &expr->cond_true);
849 token = expect(token, ':', "in conditional expression");
850 token = conditional_expression(token, &expr->cond_false);
851 if (expr->left && expr->cond_false) {
852 int is_const = expr->left->flags &
853 expr->cond_false->flags &
854 Int_const_expr;
855 if (expr->cond_true)
856 is_const &= expr->cond_true->flags;
857 expr->flags = is_const;
860 return token;
863 struct token *assignment_expression(struct token *token, struct expression **tree)
865 token = conditional_expression(token, tree);
866 if (*tree && token_type(token) == TOKEN_SPECIAL) {
867 static const int assignments[] = {
868 '=',
869 SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
870 SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
871 SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
872 SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
873 SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN };
874 int i, op = token->special;
875 for (i = 0; i < ARRAY_SIZE(assignments); i++)
876 if (assignments[i] == op) {
877 struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
878 expr->left = *tree;
879 expr->op = op;
880 *tree = expr;
881 return assignment_expression(token->next, &expr->right);
884 return token;
887 static struct token *comma_expression(struct token *token, struct expression **tree)
889 LR_BINOP_EXPRESSION(
890 token, tree, EXPR_COMMA, assignment_expression,
891 (op == ',')
895 struct token *parse_expression(struct token *token, struct expression **tree)
897 return comma_expression(token,tree);