1 /*
2 * sparse/expression.c
3 *
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003-2004 Linus Torvalds
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 * This is the expression parsing part of parsing C.
26 */
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <limits.h>
36
37 #include "lib.h"
38 #include "allocate.h"
39 #include "token.h"
40 #include "parse.h"
41 #include "symbol.h"
42 #include "scope.h"
43 #include "expression.h"
44 #include "target.h"
45 #include "char.h"
46
match_oplist(int op,...)47 static int match_oplist(int op, ...)
48 {
49 va_list args;
50 int nextop;
51
52 va_start(args, op);
53 do {
54 nextop = va_arg(args, int);
55 } while (nextop != 0 && nextop != op);
56 va_end(args);
57
58 return nextop != 0;
59 }
60
61 static struct token *comma_expression(struct token *, struct expression **);
62
parens_expression(struct token * token,struct expression ** expr,const char * where)63 struct token *parens_expression(struct token *token, struct expression **expr, const char *where)
64 {
65 struct token *p;
66
67 token = expect(token, '(', where);
68 p = token;
69 if (match_op(token, '{')) {
70 struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT);
71 struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND);
72 *expr = e;
73 e->statement = stmt;
74 start_symbol_scope(e->pos);
75 token = compound_statement(token->next, stmt);
76 end_symbol_scope();
77 token = expect(token, '}', "at end of statement expression");
78 } else
79 token = parse_expression(token, expr);
80
81 if (token == p)
82 sparse_error(token->pos, "an expression is expected before ')'");
83 return expect(token, ')', where);
84 }
85
86 /*
87 * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token
88 * conversion
89 */
handle_func(struct token * token)90 static struct symbol *handle_func(struct token *token)
91 {
92 struct ident *ident = token->ident;
93 struct symbol *decl, *array;
94 struct string *string;
95 int len;
96
97 if (ident != &__func___ident &&
98 ident != &__FUNCTION___ident &&
99 ident != &__PRETTY_FUNCTION___ident)
100 return NULL;
101
102 if (!current_fn || !current_fn->ident)
103 return NULL;
104
105 /* OK, it's one of ours */
106 array = alloc_symbol(token->pos, SYM_ARRAY);
107 array->ctype.base_type = &char_ctype;
108 array->ctype.alignment = 1;
109 array->endpos = token->pos;
110 decl = alloc_symbol(token->pos, SYM_NODE);
111 decl->ctype.base_type = array;
112 decl->ctype.alignment = 1;
113 decl->ctype.modifiers = MOD_STATIC;
114 decl->endpos = token->pos;
115
116 /* function-scope, but in NS_SYMBOL */
117 bind_symbol(decl, ident, NS_LABEL);
118 decl->namespace = NS_SYMBOL;
119
120 len = current_fn->ident->len;
121 string = __alloc_string(len + 1);
122 memcpy(string->data, current_fn->ident->name, len);
123 string->data[len] = 0;
124 string->length = len + 1;
125
126 decl->initializer = alloc_expression(token->pos, EXPR_STRING);
127 decl->initializer->string = string;
128 decl->initializer->ctype = decl;
129 decl->array_size = alloc_const_expression(token->pos, len + 1);
130 array->array_size = decl->array_size;
131 decl->bit_size = array->bit_size = bytes_to_bits(len + 1);
132
133 return decl;
134 }
135
parse_type(struct token * token,struct expression ** tree)136 static struct token *parse_type(struct token *token, struct expression **tree)
137 {
138 struct symbol *sym;
139 *tree = alloc_expression(token->pos, EXPR_TYPE);
140 token = typename(token, &sym, NULL);
141 if (sym->ident)
142 sparse_error(token->pos,
143 "type expression should not include identifier "
144 "\"%s\"", sym->ident->name);
145 (*tree)->symbol = sym;
146 return token;
147 }
148
builtin_types_compatible_p_expr(struct token * token,struct expression ** tree)149 static struct token *builtin_types_compatible_p_expr(struct token *token,
150 struct expression **tree)
151 {
152 struct expression *expr = alloc_expression(
153 token->pos, EXPR_COMPARE);
154 expr->op = SPECIAL_EQUAL;
155 token = token->next;
156 if (!match_op(token, '('))
157 return expect(token, '(',
158 "after __builtin_types_compatible_p");
159 token = token->next;
160 token = parse_type(token, &expr->left);
161 if (!match_op(token, ','))
162 return expect(token, ',',
163 "in __builtin_types_compatible_p");
164 token = token->next;
165 token = parse_type(token, &expr->right);
166 if (!match_op(token, ')'))
167 return expect(token, ')',
168 "at end of __builtin_types_compatible_p");
169 token = token->next;
170
171 *tree = expr;
172 return token;
173 }
174
builtin_offsetof_expr(struct token * token,struct expression ** tree)175 static struct token *builtin_offsetof_expr(struct token *token,
176 struct expression **tree)
177 {
178 struct expression *expr = NULL;
179 struct expression **p = &expr;
180 struct symbol *sym;
181 int op = '.';
182
183 token = token->next;
184 if (!match_op(token, '('))
185 return expect(token, '(', "after __builtin_offset");
186
187 token = token->next;
188 token = typename(token, &sym, NULL);
189 if (sym->ident)
190 sparse_error(token->pos,
191 "type expression should not include identifier "
192 "\"%s\"", sym->ident->name);
193
194 if (!match_op(token, ','))
195 return expect(token, ',', "in __builtin_offset");
196
197 while (1) {
198 struct expression *e;
199 switch (op) {
200 case ')':
201 expr->in = sym;
202 *tree = expr;
203 default:
204 return expect(token, ')', "at end of __builtin_offset");
205 case SPECIAL_DEREFERENCE:
206 e = alloc_expression(token->pos, EXPR_OFFSETOF);
207 e->op = '[';
208 *p = e;
209 p = &e->down;
210 /* fall through */
211 case '.':
212 token = token->next;
213 e = alloc_expression(token->pos, EXPR_OFFSETOF);
214 e->op = '.';
215 if (token_type(token) != TOKEN_IDENT) {
216 sparse_error(token->pos, "Expected member name");
217 return token;
218 }
219 e->ident = token->ident;
220 token = token->next;
221 break;
222 case '[':
223 token = token->next;
224 e = alloc_expression(token->pos, EXPR_OFFSETOF);
225 e->op = '[';
226 token = parse_expression(token, &e->index);
227 token = expect(token, ']',
228 "at end of array dereference");
229 if (!e->index)
230 return token;
231 }
232 *p = e;
233 p = &e->down;
234 op = token_type(token) == TOKEN_SPECIAL ? token->special : 0;
235 }
236 }
237
238 #ifndef ULLONG_MAX
239 #define ULLONG_MAX (~0ULL)
240 #endif
241
parse_num(const char * nptr,char ** end)242 static unsigned long long parse_num(const char *nptr, char **end)
243 {
244 if (nptr[0] == '0' && tolower((unsigned char)nptr[1]) == 'b')
245 return strtoull(&nptr[2], end, 2);
246 return strtoull(nptr, end, 0);
247 }
248
get_number_value(struct expression * expr,struct token * token)249 static void get_number_value(struct expression *expr, struct token *token)
250 {
251 const char *str = token->number;
252 unsigned long long value;
253 char *end;
254 int size = 0, want_unsigned = 0;
255 int overflow = 0, do_warn = 0;
256 int try_unsigned = 1;
257 int bits;
258
259 errno = 0;
260 value = parse_num(str, &end);
261 if (end == str)
262 goto Float;
263 if (value == ULLONG_MAX && errno == ERANGE)
264 overflow = 1;
265 while (1) {
266 char c = *end++;
267 if (!c) {
268 break;
269 } else if (c == 'u' || c == 'U') {
270 if (want_unsigned)
271 goto Enoint;
272 want_unsigned = 1;
273 } else if (c == 'l' || c == 'L') {
274 if (size)
275 goto Enoint;
276 size = 1;
277 if (*end == c) {
278 size = 2;
279 end++;
280 }
281 } else
282 goto Float;
283 }
284 if (overflow)
285 goto Eoverflow;
286 /* OK, it's a valid integer */
287 /* decimals can be unsigned only if directly specified as such */
288 if (str[0] != '0' && !want_unsigned)
289 try_unsigned = 0;
290 if (!size) {
291 bits = bits_in_int - 1;
292 if (!(value & (~1ULL << bits))) {
293 if (!(value & (1ULL << bits))) {
294 goto got_it;
295 } else if (try_unsigned) {
296 want_unsigned = 1;
297 goto got_it;
298 }
299 }
300 size = 1;
301 do_warn = 1;
302 }
303 if (size < 2) {
304 bits = bits_in_long - 1;
305 if (!(value & (~1ULL << bits))) {
306 if (!(value & (1ULL << bits))) {
307 goto got_it;
308 } else if (try_unsigned) {
309 want_unsigned = 1;
310 goto got_it;
311 }
312 do_warn |= 2;
313 }
314 size = 2;
315 do_warn |= 1;
316 }
317 bits = bits_in_longlong - 1;
318 if (value & (~1ULL << bits))
319 goto Eoverflow;
320 if (!(value & (1ULL << bits)))
321 goto got_it;
322 if (!try_unsigned)
323 warning(expr->pos, "decimal constant %s is too big for long long",
324 show_token(token));
325 want_unsigned = 1;
326 got_it:
327 if (do_warn && Wconstant_suffix)
328 warning(expr->pos, "constant %s is so big it is%s%s%s",
329 show_token(token),
330 want_unsigned ? " unsigned":"",
331 size > 0 ? " long":"",
332 size > 1 ? " long":"");
333 if (do_warn & 2)
334 warning(expr->pos,
335 "decimal constant %s is between LONG_MAX and ULONG_MAX."
336 " For C99 that means long long, C90 compilers are very "
337 "likely to produce unsigned long (and a warning) here",
338 show_token(token));
339 expr->type = EXPR_VALUE;
340 expr->flags = CEF_SET_INT;
341 expr->ctype = ctype_integer(size, want_unsigned);
342 expr->value = value;
343 return;
344 Eoverflow:
345 error_die(expr->pos, "constant %s is too big even for unsigned long long",
346 show_token(token));
347 return;
348 Float:
349 expr->fvalue = string_to_ld(str, &end);
350 if (str == end)
351 goto Enoint;
352
353 if (*end && end[1])
354 goto Enoint;
355
356 if (*end == 'f' || *end == 'F')
357 expr->ctype = &float_ctype;
358 else if (*end == 'l' || *end == 'L')
359 expr->ctype = &ldouble_ctype;
360 else if (!*end)
361 expr->ctype = &double_ctype;
362 else
363 goto Enoint;
364
365 expr->flags = CEF_SET_FLOAT;
366 expr->type = EXPR_FVALUE;
367 return;
368
369 Enoint:
370 error_die(expr->pos, "constant %s is not a valid number", show_token(token));
371 }
372
primary_expression(struct token * token,struct expression ** tree)373 struct token *primary_expression(struct token *token, struct expression **tree)
374 {
375 struct expression *expr = NULL;
376
377 switch (token_type(token)) {
378 case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3:
379 expr = alloc_expression(token->pos, EXPR_VALUE);
380 expr->flags = CEF_SET_CHAR;
381 expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype;
382 get_char_constant(token, &expr->value);
383 token = token->next;
384 break;
385
386 case TOKEN_NUMBER:
387 expr = alloc_expression(token->pos, EXPR_VALUE);
388 get_number_value(expr, token); /* will see if it's an integer */
389 token = token->next;
390 break;
391
392 case TOKEN_ZERO_IDENT: {
393 expr = alloc_expression(token->pos, EXPR_SYMBOL);
394 expr->flags = CEF_SET_INT;
395 expr->ctype = &int_ctype;
396 expr->symbol = &zero_int;
397 expr->symbol_name = token->ident;
398 token = token->next;
399 break;
400 }
401
402 case TOKEN_IDENT: {
403 struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
404 struct token *next = token->next;
405
406 if (!sym) {
407 sym = handle_func(token);
408 if (token->ident == &__builtin_types_compatible_p_ident) {
409 token = builtin_types_compatible_p_expr(token, &expr);
410 break;
411 }
412 if (token->ident == &__builtin_offsetof_ident) {
413 token = builtin_offsetof_expr(token, &expr);
414 break;
415 }
416 } else if (sym->enum_member) {
417 expr = alloc_expression(token->pos, EXPR_VALUE);
418 *expr = *sym->initializer;
419 /* we want the right position reported, thus the copy */
420 expr->pos = token->pos;
421 expr->flags = CEF_SET_ENUM;
422 token = next;
423 break;
424 }
425
426 expr = alloc_expression(token->pos, EXPR_SYMBOL);
427
428 /*
429 * We support types as real first-class citizens, with type
430 * comparisons etc:
431 *
432 * if (typeof(a) == int) ..
433 */
434 if (sym && sym->namespace == NS_TYPEDEF) {
435 sparse_error(token->pos, "typename in expression");
436 sym = NULL;
437 }
438 expr->symbol_name = token->ident;
439 expr->symbol = sym;
440
441 /*
442 * A pointer to an lvalue designating a static storage
443 * duration object is an address constant [6.6(9)].
444 */
445 if (sym && (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC)))
446 expr->flags = CEF_ADDR;
447
448 token = next;
449 break;
450 }
451
452 case TOKEN_STRING:
453 case TOKEN_WIDE_STRING:
454 expr = alloc_expression(token->pos, EXPR_STRING);
455 token = get_string_constant(token, expr);
456 break;
457
458 case TOKEN_SPECIAL:
459 if (token->special == '(') {
460 expr = alloc_expression(token->pos, EXPR_PREOP);
461 expr->op = '(';
462 token = parens_expression(token, &expr->unop, "in expression");
463 break;
464 }
465 if (token->special == '[' && lookup_type(token->next)) {
466 expr = alloc_expression(token->pos, EXPR_TYPE);
467 token = typename(token->next, &expr->symbol, NULL);
468 token = expect(token, ']', "in type expression");
469 break;
470 }
471
472 default:
473 ;
474 }
475 *tree = expr;
476 return token;
477 }
478
expression_list(struct token * token,struct expression_list ** list)479 static struct token *expression_list(struct token *token, struct expression_list **list)
480 {
481 while (!match_op(token, ')')) {
482 struct expression *expr = NULL;
483 token = assignment_expression(token, &expr);
484 if (!expr)
485 break;
486 add_expression(list, expr);
487 if (!match_op(token, ','))
488 break;
489 token = token->next;
490 }
491 return token;
492 }
493
494 /*
495 * extend to deal with the ambiguous C grammar for parsing
496 * a cast expressions followed by an initializer.
497 */
postfix_expression(struct token * token,struct expression ** tree,struct expression * cast_init_expr)498 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
499 {
500 struct expression *expr = cast_init_expr;
501
502 if (!expr)
503 token = primary_expression(token, &expr);
504
505 while (expr && token_type(token) == TOKEN_SPECIAL) {
506 switch (token->special) {
507 case '[': { /* Array dereference */
508 struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
509 struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
510
511 deref->op = '*';
512 deref->unop = add;
513
514 add->op = '+';
515 add->left = expr;
516 token = parse_expression(token->next, &add->right);
517 token = expect(token, ']', "at end of array dereference");
518 expr = deref;
519 continue;
520 }
521 case SPECIAL_INCREMENT: /* Post-increment */
522 case SPECIAL_DECREMENT: { /* Post-decrement */
523 struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
524 post->op = token->special;
525 post->unop = expr;
526 expr = post;
527 token = token->next;
528 continue;
529 }
530 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
531 /* "x->y" is just shorthand for "(*x).y" */
532 struct expression *inner = alloc_expression(token->pos, EXPR_PREOP);
533 inner->op = '*';
534 inner->unop = expr;
535 expr = inner;
536 }
537 /* Fall through!! */
538 case '.': { /* Structure member dereference */
539 struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
540 deref->op = '.';
541 deref->deref = expr;
542 token = token->next;
543 if (token_type(token) != TOKEN_IDENT) {
544 sparse_error(token->pos, "Expected member name");
545 break;
546 }
547 deref->member = token->ident;
548 deref->member_offset = -1;
549 token = token->next;
550 expr = deref;
551 continue;
552 }
553
554 case '(': { /* Function call */
555 struct expression *call = alloc_expression(token->pos, EXPR_CALL);
556 call->op = '(';
557 call->fn = expr;
558 token = expression_list(token->next, &call->args);
559 token = expect(token, ')', "in function call");
560 expr = call;
561 continue;
562 }
563
564 default:
565 break;
566 }
567 break;
568 }
569 *tree = expr;
570 return token;
571 }
572
573 static struct token *cast_expression(struct token *token, struct expression **tree);
574 static struct token *unary_expression(struct token *token, struct expression **tree);
575
type_info_expression(struct token * token,struct expression ** tree,int type)576 static struct token *type_info_expression(struct token *token,
577 struct expression **tree, int type)
578 {
579 struct expression *expr = alloc_expression(token->pos, type);
580 struct token *p;
581
582 *tree = expr;
583 expr->flags = CEF_SET_ICE; /* XXX: VLA support will need that changed */
584 token = token->next;
585 if (!match_op(token, '(') || !lookup_type(token->next))
586 return unary_expression(token, &expr->cast_expression);
587 p = token;
588 token = typename(token->next, &expr->cast_type, NULL);
589
590 if (!match_op(token, ')')) {
591 static const char * error[] = {
592 [EXPR_SIZEOF] = "at end of sizeof",
593 [EXPR_ALIGNOF] = "at end of __alignof__",
594 [EXPR_PTRSIZEOF] = "at end of __sizeof_ptr__"
595 };
596 return expect(token, ')', error[type]);
597 }
598
599 token = token->next;
600 /*
601 * C99 ambiguity: the typename might have been the beginning
602 * of a typed initializer expression..
603 */
604 if (match_op(token, '{')) {
605 struct expression *cast = alloc_expression(p->pos, EXPR_CAST);
606 cast->cast_type = expr->cast_type;
607 expr->cast_type = NULL;
608 expr->cast_expression = cast;
609 token = initializer(&cast->cast_expression, token);
610 token = postfix_expression(token, &expr->cast_expression, cast);
611 }
612 return token;
613 }
614
unary_expression(struct token * token,struct expression ** tree)615 static struct token *unary_expression(struct token *token, struct expression **tree)
616 {
617 if (token_type(token) == TOKEN_IDENT) {
618 struct ident *ident = token->ident;
619 if (ident->reserved) {
620 static const struct {
621 struct ident *id;
622 int type;
623 } type_information[] = {
624 { &sizeof_ident, EXPR_SIZEOF },
625 { &__alignof___ident, EXPR_ALIGNOF },
626 { &__alignof_ident, EXPR_ALIGNOF },
627 { &_Alignof_ident, EXPR_ALIGNOF },
628 { &__sizeof_ptr___ident, EXPR_PTRSIZEOF },
629 };
630 int i;
631 for (i = 0; i < ARRAY_SIZE(type_information); i++) {
632 if (ident == type_information[i].id)
633 return type_info_expression(token, tree, type_information[i].type);
634 }
635 }
636 }
637
638 if (token_type(token) == TOKEN_SPECIAL) {
639 if (match_oplist(token->special,
640 SPECIAL_INCREMENT, SPECIAL_DECREMENT,
641 '&', '*', 0)) {
642 struct expression *unop;
643 struct expression *unary;
644 struct token *next;
645
646 next = cast_expression(token->next, &unop);
647 if (!unop) {
648 sparse_error(token->pos, "Syntax error in unary expression");
649 *tree = NULL;
650 return next;
651 }
652 unary = alloc_expression(token->pos, EXPR_PREOP);
653 unary->op = token->special;
654 unary->unop = unop;
655 *tree = unary;
656 return next;
657 }
658 /* possibly constant ones */
659 if (match_oplist(token->special, '+', '-', '~', '!', 0)) {
660 struct expression *unop;
661 struct expression *unary;
662 struct token *next;
663
664 next = cast_expression(token->next, &unop);
665 if (!unop) {
666 sparse_error(token->pos, "Syntax error in unary expression");
667 *tree = NULL;
668 return next;
669 }
670 unary = alloc_expression(token->pos, EXPR_PREOP);
671 unary->op = token->special;
672 unary->unop = unop;
673 *tree = unary;
674 return next;
675 }
676 /* Gcc extension: &&label gives the address of a label */
677 if (match_op(token, SPECIAL_LOGICAL_AND) &&
678 token_type(token->next) == TOKEN_IDENT) {
679 struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
680 struct symbol *sym = label_symbol(token->next);
681 if (!(sym->ctype.modifiers & MOD_ADDRESSABLE)) {
682 sym->ctype.modifiers |= MOD_ADDRESSABLE;
683 add_symbol(&function_computed_target_list, sym);
684 }
685 label->flags = CEF_ADDR;
686 label->label_symbol = sym;
687 *tree = label;
688 return token->next->next;
689 }
690
691 }
692
693 return postfix_expression(token, tree, NULL);
694 }
695
696 /*
697 * Ambiguity: a '(' can be either a cast-expression or
698 * a primary-expression depending on whether it is followed
699 * by a type or not.
700 *
701 * additional ambiguity: a "cast expression" followed by
702 * an initializer is really a postfix-expression.
703 */
cast_expression(struct token * token,struct expression ** tree)704 static struct token *cast_expression(struct token *token, struct expression **tree)
705 {
706 if (match_op(token, '(')) {
707 struct token *next = token->next;
708 if (lookup_type(next)) {
709 struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
710 struct expression *v;
711 struct symbol *sym;
712 int is_force;
713
714 token = typename(next, &sym, &is_force);
715 cast->cast_type = sym;
716 token = expect(token, ')', "at end of cast operator");
717 if (match_op(token, '{')) {
718 if (toplevel(block_scope))
719 sym->ctype.modifiers |= MOD_TOPLEVEL;
720 if (is_force)
721 warning(sym->pos,
722 "[force] in compound literal");
723 token = initializer(&cast->cast_expression, token);
724 return postfix_expression(token, tree, cast);
725 }
726 *tree = cast;
727 if (is_force)
728 cast->type = EXPR_FORCE_CAST;
729 token = cast_expression(token, &v);
730 if (!v)
731 return token;
732 cast->cast_expression = v;
733 return token;
734 }
735 }
736 return unary_expression(token, tree);
737 }
738
739 /*
740 * Generic left-to-right binop parsing
741 *
742 * This _really_ needs to be inlined, because that makes the inner
743 * function call statically deterministic rather than a totally
744 * unpredictable indirect call. But gcc-3 is so "clever" that it
745 * doesn't do so by default even when you tell it to inline it.
746 *
747 * Making it a macro avoids the inlining problem, and also means
748 * that we can pass in the op-comparison as an expression rather
749 * than create a data structure for it.
750 */
751
752 #define LR_BINOP_EXPRESSION(__token, tree, type, inner, compare) \
753 struct expression *left = NULL; \
754 struct token * next = inner(__token, &left); \
755 \
756 if (left) { \
757 while (token_type(next) == TOKEN_SPECIAL) { \
758 struct expression *top, *right = NULL; \
759 int op = next->special; \
760 \
761 if (!(compare)) \
762 goto out; \
763 top = alloc_expression(next->pos, type); \
764 next = inner(next->next, &right); \
765 if (!right) { \
766 sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op)); \
767 break; \
768 } \
769 top->op = op; \
770 top->left = left; \
771 top->right = right; \
772 left = top; \
773 } \
774 } \
775 out: \
776 *tree = left; \
777 return next; \
778
multiplicative_expression(struct token * token,struct expression ** tree)779 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
780 {
781 LR_BINOP_EXPRESSION(
782 token, tree, EXPR_BINOP, cast_expression,
783 (op == '*') || (op == '/') || (op == '%')
784 );
785 }
786
additive_expression(struct token * token,struct expression ** tree)787 static struct token *additive_expression(struct token *token, struct expression **tree)
788 {
789 LR_BINOP_EXPRESSION(
790 token, tree, EXPR_BINOP, multiplicative_expression,
791 (op == '+') || (op == '-')
792 );
793 }
794
shift_expression(struct token * token,struct expression ** tree)795 static struct token *shift_expression(struct token *token, struct expression **tree)
796 {
797 LR_BINOP_EXPRESSION(
798 token, tree, EXPR_BINOP, additive_expression,
799 (op == SPECIAL_LEFTSHIFT) || (op == SPECIAL_RIGHTSHIFT)
800 );
801 }
802
relational_expression(struct token * token,struct expression ** tree)803 static struct token *relational_expression(struct token *token, struct expression **tree)
804 {
805 LR_BINOP_EXPRESSION(
806 token, tree, EXPR_COMPARE, shift_expression,
807 (op == '<') || (op == '>') ||
808 (op == SPECIAL_LTE) || (op == SPECIAL_GTE)
809 );
810 }
811
equality_expression(struct token * token,struct expression ** tree)812 static struct token *equality_expression(struct token *token, struct expression **tree)
813 {
814 LR_BINOP_EXPRESSION(
815 token, tree, EXPR_COMPARE, relational_expression,
816 (op == SPECIAL_EQUAL) || (op == SPECIAL_NOTEQUAL)
817 );
818 }
819
bitwise_and_expression(struct token * token,struct expression ** tree)820 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
821 {
822 LR_BINOP_EXPRESSION(
823 token, tree, EXPR_BINOP, equality_expression,
824 (op == '&')
825 );
826 }
827
bitwise_xor_expression(struct token * token,struct expression ** tree)828 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
829 {
830 LR_BINOP_EXPRESSION(
831 token, tree, EXPR_BINOP, bitwise_and_expression,
832 (op == '^')
833 );
834 }
835
bitwise_or_expression(struct token * token,struct expression ** tree)836 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
837 {
838 LR_BINOP_EXPRESSION(
839 token, tree, EXPR_BINOP, bitwise_xor_expression,
840 (op == '|')
841 );
842 }
843
logical_and_expression(struct token * token,struct expression ** tree)844 static struct token *logical_and_expression(struct token *token, struct expression **tree)
845 {
846 LR_BINOP_EXPRESSION(
847 token, tree, EXPR_LOGICAL, bitwise_or_expression,
848 (op == SPECIAL_LOGICAL_AND)
849 );
850 }
851
logical_or_expression(struct token * token,struct expression ** tree)852 static struct token *logical_or_expression(struct token *token, struct expression **tree)
853 {
854 LR_BINOP_EXPRESSION(
855 token, tree, EXPR_LOGICAL, logical_and_expression,
856 (op == SPECIAL_LOGICAL_OR)
857 );
858 }
859
conditional_expression(struct token * token,struct expression ** tree)860 struct token *conditional_expression(struct token *token, struct expression **tree)
861 {
862 token = logical_or_expression(token, tree);
863 if (*tree && match_op(token, '?')) {
864 struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
865 expr->op = token->special;
866 expr->left = *tree;
867 *tree = expr;
868 token = parse_expression(token->next, &expr->cond_true);
869 token = expect(token, ':', "in conditional expression");
870 token = conditional_expression(token, &expr->cond_false);
871 }
872 return token;
873 }
874
assignment_expression(struct token * token,struct expression ** tree)875 struct token *assignment_expression(struct token *token, struct expression **tree)
876 {
877 token = conditional_expression(token, tree);
878 if (*tree && token_type(token) == TOKEN_SPECIAL) {
879 static const int assignments[] = {
880 '=',
881 SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
882 SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
883 SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
884 SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
885 SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN };
886 int i, op = token->special;
887 for (i = 0; i < ARRAY_SIZE(assignments); i++)
888 if (assignments[i] == op) {
889 struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
890 expr->left = *tree;
891 expr->op = op;
892 *tree = expr;
893 return assignment_expression(token->next, &expr->right);
894 }
895 }
896 return token;
897 }
898
comma_expression(struct token * token,struct expression ** tree)899 static struct token *comma_expression(struct token *token, struct expression **tree)
900 {
901 LR_BINOP_EXPRESSION(
902 token, tree, EXPR_COMMA, assignment_expression,
903 (op == ',')
904 );
905 }
906
parse_expression(struct token * token,struct expression ** tree)907 struct token *parse_expression(struct token *token, struct expression **tree)
908 {
909 return comma_expression(token,tree);
910 }
911
912
913