[PATCH] Fix "return" target handling
[smatch.git] / expression.c
blobdc022356ec60cdafa1c607824b6990edeecf4e4e
1 /*
2 * sparse/expression.c
4 * Copyright (C) 2003 Transmeta Corp.
5 * 2003 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>
19 #include "lib.h"
20 #include "token.h"
21 #include "parse.h"
22 #include "symbol.h"
23 #include "scope.h"
24 #include "expression.h"
25 #include "target.h"
27 static int match_oplist(int op, ...)
29 va_list args;
31 va_start(args, op);
32 for (;;) {
33 int nextop = va_arg(args, int);
34 if (!nextop)
35 return 0;
36 if (op == nextop)
37 return 1;
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);
49 *expr = e;
50 e->statement = stmt;
51 start_symbol_scope();
52 token = compound_statement(token->next, stmt);
53 end_symbol_scope();
54 token = expect(token, '}', "at end of statement expression");
55 } else
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;
67 char *data;
69 do {
70 totlen += next->string->length-1;
71 next = next->next;
72 } while (token_type(next) == TOKEN_STRING);
74 string = __alloc_string(totlen);
75 string->length = totlen;
76 data = string->data;
77 next = token;
78 do {
79 struct string *s = next->string;
80 int len = s->length;
82 next = next->next;
83 memcpy(data, s->data, len);
84 data += len-1;
85 } while (token_type(next) == TOKEN_STRING);
87 expr->string = string;
88 return next;
91 static void get_int_value(struct expression *expr, const char *str)
93 unsigned long long value = 0;
94 unsigned int base = 10, digit, bits;
95 unsigned long modifiers, extramod;
97 switch (str[0]) {
98 case 'x':
99 base = 18; // the -= 2 for the octal case will
100 str++; // skip the 'x'
101 /* fallthrough */
102 case 'o':
103 str++; // skip the 'o' or 'x/X'
104 base -= 2; // the fall-through will make this 8
106 while ((digit = hexval(*str)) < base) {
107 value = value * base + digit;
108 str++;
110 modifiers = 0;
111 for (;;) {
112 char c = *str++;
113 if (c == 'u' || c == 'U') {
114 modifiers |= MOD_UNSIGNED;
115 continue;
117 if (c == 'l' || c == 'L') {
118 if (modifiers & MOD_LONG)
119 modifiers |= MOD_LONGLONG;
120 modifiers |= MOD_LONG;
121 continue;
123 break;
126 bits = BITS_IN_LONGLONG;
127 extramod = 0;
128 if (!(modifiers & MOD_LONGLONG)) {
129 if (value & (~1ULL << (BITS_IN_LONG-1))) {
130 extramod = MOD_LONGLONG | MOD_LONG;
131 } else {
132 bits = BITS_IN_LONG;
133 if (!(modifiers & MOD_LONG)) {
134 if (value & (~1ULL << (BITS_IN_INT-1))) {
135 extramod = MOD_LONG;
136 } else
137 bits = BITS_IN_INT;
141 if (!(modifiers & MOD_UNSIGNED)) {
142 if (value & (1ULL << (bits-1))) {
143 extramod |= MOD_UNSIGNED;
146 if (extramod) {
148 * Special case: "int" gets promoted directly to "long"
149 * for normal decimal numbers..
151 modifiers |= extramod;
152 if (base == 10 && modifiers == MOD_UNSIGNED) {
153 modifiers = MOD_LONG;
154 if (BITS_IN_LONG == BITS_IN_INT)
155 modifiers = MOD_LONG | MOD_UNSIGNED;
158 /* Hex or octal constants don't complain about missing signedness */
159 if (base == 10 || extramod != MOD_UNSIGNED)
160 warn(expr->pos, "value is so big it is%s%s%s",
161 (modifiers & MOD_UNSIGNED) ? " unsigned":"",
162 (modifiers & MOD_LONG) ? " long":"",
163 (modifiers & MOD_LONGLONG) ? " long":"");
166 expr->type = EXPR_VALUE;
167 expr->ctype = ctype_integer(modifiers);
168 expr->value = value;
171 struct token *primary_expression(struct token *token, struct expression **tree)
173 struct expression *expr = NULL;
175 switch (token_type(token)) {
176 static int fp_warned;
177 case TOKEN_FP:
178 expr = alloc_expression(token->pos, EXPR_VALUE);
179 expr->ctype = &double_ctype;
180 expr->value = 0;
181 if (!fp_warned) {
182 warn(token->pos, "FP values not yet implemented");
183 fp_warned = 1;
185 token = token->next;
186 break;
188 case TOKEN_CHAR:
189 expr = alloc_expression(token->pos, EXPR_VALUE);
190 expr->ctype = &int_ctype;
191 expr->value = (unsigned char) token->character;
192 token = token->next;
193 break;
195 case TOKEN_INTEGER:
196 expr = alloc_expression(token->pos, EXPR_VALUE);
197 get_int_value(expr, token->integer);
198 token = token->next;
199 break;
201 case TOKEN_IDENT: {
202 struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
203 struct token *next = token->next;
205 expr = alloc_expression(token->pos, EXPR_SYMBOL);
208 * We support types as real first-class citizens, with type
209 * comparisons etc:
211 * if (typeof(a) == int) ..
213 if (sym && sym->namespace == NS_TYPEDEF) {
214 warn(token->pos, "typename in expression");
215 sym = NULL;
217 expr->symbol_name = token->ident;
218 expr->symbol = sym;
219 token = next;
220 break;
223 case TOKEN_STRING: {
224 expr = alloc_expression(token->pos, EXPR_STRING);
225 token = string_expression(token, expr);
226 break;
229 case TOKEN_SPECIAL:
230 if (token->special == '(') {
231 expr = alloc_expression(token->pos, EXPR_PREOP);
232 expr->op = '(';
233 token = parens_expression(token, &expr->unop, "in expression");
234 break;
236 if (token->special == '[' && lookup_type(token->next)) {
237 expr = alloc_expression(token->pos, EXPR_TYPE);
238 token = typename(token->next, &expr->symbol);
239 token = expect(token, ']', "in type expression");
240 break;
243 default:
246 *tree = expr;
247 return token;
250 static struct token *expression_list(struct token *token, struct expression_list **list)
252 while (!match_op(token, ')')) {
253 struct expression *expr = NULL;
254 token = assignment_expression(token, &expr);
255 if (!expr)
256 break;
257 add_expression(list, expr);
258 if (!match_op(token, ','))
259 break;
260 token = token->next;
262 return token;
266 * extend to deal with the ambiguous C grammar for parsing
267 * a cast expressions followed by an initializer.
269 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
271 struct expression *expr = cast_init_expr;
273 if (!expr)
274 token = primary_expression(token, &expr);
276 while (expr && token_type(token) == TOKEN_SPECIAL) {
277 switch (token->special) {
278 case '[': { /* Array dereference */
279 struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
280 struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
282 deref->op = '*';
283 deref->unop = add;
285 add->op = '+';
286 add->left = expr;
287 token = parse_expression(token->next, &add->right);
288 token = expect(token, ']', "at end of array dereference");
289 expr = deref;
290 continue;
292 case SPECIAL_INCREMENT: /* Post-increment */
293 case SPECIAL_DECREMENT: { /* Post-decrement */
294 struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
295 post->op = token->special;
296 post->unop = expr;
297 expr = post;
298 token = token->next;
299 continue;
301 case '.': /* Structure member dereference */
302 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
303 struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
304 deref->op = token->special;
305 deref->deref = expr;
306 token = token->next;
307 if (token_type(token) != TOKEN_IDENT) {
308 warn(token->pos, "Expected member name");
309 break;
311 deref->member = token->ident;
312 token = token->next;
313 expr = deref;
314 continue;
317 case '(': { /* Function call */
318 struct expression *call = alloc_expression(token->pos, EXPR_CALL);
319 call->op = '(';
320 call->fn = expr;
321 token = expression_list(token->next, &call->args);
322 token = expect(token, ')', "in function call");
323 expr = call;
324 continue;
327 default:
328 break;
330 break;
332 *tree = expr;
333 return token;
336 static struct token *cast_expression(struct token *token, struct expression **tree);
337 static struct token *unary_expression(struct token *token, struct expression **tree)
339 if (token_type(token) == TOKEN_IDENT &&
340 (token->ident == &sizeof_ident ||
341 token->ident == &__alignof___ident)) {
342 struct expression *sizeof_ex = alloc_expression(token->pos, EXPR_SIZEOF);
343 *tree = sizeof_ex;
344 tree = &sizeof_ex->unop;
345 token = token->next;
346 if (!match_op(token, '(') || !lookup_type(token->next))
347 return unary_expression(token, &sizeof_ex->cast_expression);
348 token = typename(token->next, &sizeof_ex->cast_type);
349 return expect(token, ')', "at end of sizeof type-name");
352 if (token_type(token) == TOKEN_SPECIAL) {
353 if (match_oplist(token->special,
354 SPECIAL_INCREMENT, SPECIAL_DECREMENT,
355 '&', '*', '+', '-', '~', '!', 0)) {
356 struct expression *unary = alloc_expression(token->pos, EXPR_PREOP);
357 unary->op = token->special;
358 *tree = unary;
359 return cast_expression(token->next, &unary->unop);
362 /* Gcc extension: &&label gives the address of a label */
363 if (match_op(token, SPECIAL_LOGICAL_AND) &&
364 token_type(token->next) == TOKEN_IDENT) {
365 struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
366 label->label_symbol = label_symbol(token->next);
367 *tree = label;
368 return token->next->next;
373 return postfix_expression(token, tree, NULL);
377 * Ambiguity: a '(' can be either a cast-expression or
378 * a primary-expression depending on whether it is followed
379 * by a type or not.
381 * additional ambiguity: a "cast expression" followed by
382 * an initializer is really a postfix-expression.
384 static struct token *cast_expression(struct token *token, struct expression **tree)
386 if (match_op(token, '(')) {
387 struct token *next = token->next;
388 if (lookup_type(next)) {
389 struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
390 struct symbol *sym;
392 token = typename(next, &sym);
393 cast->cast_type = sym->ctype.base_type;
394 token = expect(token, ')', "at end of cast operator");
395 if (match_op(token, '{')) {
396 token = initializer(&cast->cast_expression, token);
397 return postfix_expression(token, tree, cast);
399 *tree = cast;
400 token = cast_expression(token, &cast->cast_expression);
401 return token;
404 return unary_expression(token, tree);
407 /* Generic left-to-right binop parsing */
408 static struct token *lr_binop_expression(struct token *token, struct expression **tree,
409 enum expression_type type, struct token *(*inner)(struct token *, struct expression **), ...)
411 struct expression *left = NULL;
412 struct token * next = inner(token, &left);
414 if (left) {
415 while (token_type(next) == TOKEN_SPECIAL) {
416 struct expression *top, *right = NULL;
417 int op = next->special;
418 va_list args;
420 va_start(args, inner);
421 for (;;) {
422 int nextop = va_arg(args, int);
423 if (!nextop)
424 goto out;
425 if (op == nextop)
426 break;
428 va_end(args);
429 top = alloc_expression(next->pos, type);
430 next = inner(next->next, &right);
431 if (!right) {
432 warn(next->pos, "No right hand side of '%s'-expression", show_special(op));
433 break;
435 top->op = op;
436 top->left = left;
437 top->right = right;
438 left = top;
441 out:
442 *tree = left;
443 return next;
446 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
448 return lr_binop_expression(token, tree, EXPR_BINOP, cast_expression, '*', '/', '%', 0);
451 static struct token *additive_expression(struct token *token, struct expression **tree)
453 return lr_binop_expression(token, tree, EXPR_BINOP, multiplicative_expression, '+', '-', 0);
456 static struct token *shift_expression(struct token *token, struct expression **tree)
458 return lr_binop_expression(token, tree, EXPR_BINOP, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0);
461 static struct token *relational_expression(struct token *token, struct expression **tree)
463 return lr_binop_expression(token, tree, EXPR_COMPARE, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0);
466 static struct token *equality_expression(struct token *token, struct expression **tree)
468 return lr_binop_expression(token, tree, EXPR_COMPARE, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0);
471 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
473 return lr_binop_expression(token, tree, EXPR_BINOP, equality_expression, '&', 0);
476 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
478 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_and_expression, '^', 0);
481 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
483 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_xor_expression, '|', 0);
486 static struct token *logical_and_expression(struct token *token, struct expression **tree)
488 return lr_binop_expression(token, tree, EXPR_LOGICAL, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0);
491 static struct token *logical_or_expression(struct token *token, struct expression **tree)
493 return lr_binop_expression(token, tree, EXPR_LOGICAL, logical_and_expression, SPECIAL_LOGICAL_OR, 0);
496 struct token *conditional_expression(struct token *token, struct expression **tree)
498 token = logical_or_expression(token, tree);
499 if (match_op(token, '?')) {
500 struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
501 expr->op = token->special;
502 expr->left = *tree;
503 *tree = expr;
504 token = parse_expression(token->next, &expr->cond_true);
505 token = expect(token, ':', "in conditional expression");
506 token = conditional_expression(token, &expr->cond_false);
508 return token;
511 struct token *assignment_expression(struct token *token, struct expression **tree)
513 token = conditional_expression(token, tree);
514 if (token_type(token) == TOKEN_SPECIAL) {
515 static const int assignments[] = {
516 '=',
517 SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
518 SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
519 SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
520 SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
521 SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN };
522 int i, op = token->special;
523 for (i = 0; i < sizeof(assignments)/sizeof(int); i++)
524 if (assignments[i] == op) {
525 struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
526 expr->left = *tree;
527 expr->op = op;
528 *tree = expr;
529 return assignment_expression(token->next, &expr->right);
532 return token;
535 static struct token *comma_expression(struct token *token, struct expression **tree)
537 return lr_binop_expression(token, tree, EXPR_COMMA, assignment_expression, ',', 0);
540 struct token *parse_expression(struct token *token, struct expression **tree)
542 return comma_expression(token,tree);