o split handle_switch, to make it more lib friendly
[smatch.git] / expression.c
blob48414c3e1da030c922ad2cdd0b0faeb6295da6ca
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 expr = alloc_expression(token->pos, EXPR_SYMBOL);
203 expr->symbol_name = token->ident;
204 expr->symbol = lookup_symbol(token->ident, NS_SYMBOL);
205 token = token->next;
206 break;
209 case TOKEN_STRING: {
210 expr = alloc_expression(token->pos, EXPR_STRING);
211 token = string_expression(token, expr);
212 break;
215 case TOKEN_SPECIAL:
216 if (token->special == '(') {
217 expr = alloc_expression(token->pos, EXPR_PREOP);
218 expr->op = '(';
219 token = parens_expression(token, &expr->unop, "in expression");
220 break;
222 default:
225 *tree = expr;
226 return token;
229 static struct token *expression_list(struct token *token, struct expression_list **list)
231 while (!match_op(token, ')')) {
232 struct expression *expr = NULL;
233 token = assignment_expression(token, &expr);
234 if (!expr)
235 break;
236 add_expression(list, expr);
237 if (!match_op(token, ','))
238 break;
239 token = token->next;
241 return token;
245 * extend to deal with the ambiguous C grammar for parsing
246 * a cast expressions followed by an initializer.
248 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
250 struct expression *expr = cast_init_expr;
252 if (!expr)
253 token = primary_expression(token, &expr);
255 while (expr && token_type(token) == TOKEN_SPECIAL) {
256 switch (token->special) {
257 case '[': { /* Array dereference */
258 struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
259 struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
261 deref->op = '*';
262 deref->unop = add;
264 add->op = '+';
265 add->left = expr;
266 token = parse_expression(token->next, &add->right);
267 token = expect(token, ']', "at end of array dereference");
268 expr = deref;
269 continue;
271 case SPECIAL_INCREMENT: /* Post-increment */
272 case SPECIAL_DECREMENT: { /* Post-decrement */
273 struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
274 post->op = token->special;
275 post->unop = expr;
276 expr = post;
277 token = token->next;
278 continue;
280 case '.': /* Structure member dereference */
281 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
282 struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
283 deref->op = token->special;
284 deref->deref = expr;
285 token = token->next;
286 if (token_type(token) != TOKEN_IDENT) {
287 warn(token->pos, "Expected member name");
288 break;
290 deref->member = token->ident;
291 token = token->next;
292 expr = deref;
293 continue;
296 case '(': { /* Function call */
297 struct expression *call = alloc_expression(token->pos, EXPR_CALL);
298 call->op = '(';
299 call->fn = expr;
300 token = expression_list(token->next, &call->args);
301 token = expect(token, ')', "in function call");
302 expr = call;
303 continue;
306 default:
307 break;
309 break;
311 *tree = expr;
312 return token;
315 static struct token *cast_expression(struct token *token, struct expression **tree);
316 static struct token *unary_expression(struct token *token, struct expression **tree)
318 if (token_type(token) == TOKEN_IDENT &&
319 (token->ident == &sizeof_ident ||
320 token->ident == &__alignof___ident)) {
321 struct expression *sizeof_ex = alloc_expression(token->pos, EXPR_SIZEOF);
322 *tree = sizeof_ex;
323 tree = &sizeof_ex->unop;
324 token = token->next;
325 if (!match_op(token, '(') || !lookup_type(token->next))
326 return unary_expression(token, &sizeof_ex->cast_expression);
327 token = typename(token->next, &sizeof_ex->cast_type);
328 return expect(token, ')', "at end of sizeof type-name");
331 if (token_type(token) == TOKEN_SPECIAL) {
332 if (match_oplist(token->special,
333 SPECIAL_INCREMENT, SPECIAL_DECREMENT,
334 '&', '*', '+', '-', '~', '!', 0)) {
335 struct expression *unary = alloc_expression(token->pos, EXPR_PREOP);
336 unary->op = token->special;
337 *tree = unary;
338 return cast_expression(token->next, &unary->unop);
341 /* Gcc extension: &&label gives the address of a label */
342 if (match_op(token, SPECIAL_LOGICAL_AND) &&
343 token_type(token->next) == TOKEN_IDENT) {
344 struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
345 label->label_symbol = label_symbol(token->next);
346 *tree = label;
347 return token->next->next;
352 return postfix_expression(token, tree, NULL);
356 * Ambiguity: a '(' can be either a cast-expression or
357 * a primary-expression depending on whether it is followed
358 * by a type or not.
360 * additional ambiguity: a "cast expression" followed by
361 * an initializer is really a postfix-expression.
363 static struct token *cast_expression(struct token *token, struct expression **tree)
365 if (match_op(token, '(')) {
366 struct token *next = token->next;
367 if (lookup_type(next)) {
368 struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
369 struct symbol *sym;
371 token = typename(next, &sym);
372 cast->cast_type = sym->ctype.base_type;
373 token = expect(token, ')', "at end of cast operator");
374 if (match_op(token, '{')) {
375 token = initializer(&cast->cast_expression, token);
376 return postfix_expression(token, tree, cast);
378 *tree = cast;
379 token = cast_expression(token, &cast->cast_expression);
380 return token;
383 return unary_expression(token, tree);
386 /* Generic left-to-right binop parsing */
387 static struct token *lr_binop_expression(struct token *token, struct expression **tree,
388 enum expression_type type, struct token *(*inner)(struct token *, struct expression **), ...)
390 struct expression *left = NULL;
391 struct token * next = inner(token, &left);
393 if (left) {
394 while (token_type(next) == TOKEN_SPECIAL) {
395 struct expression *top, *right = NULL;
396 int op = next->special;
397 va_list args;
399 va_start(args, inner);
400 for (;;) {
401 int nextop = va_arg(args, int);
402 if (!nextop)
403 goto out;
404 if (op == nextop)
405 break;
407 va_end(args);
408 top = alloc_expression(next->pos, type);
409 next = inner(next->next, &right);
410 if (!right) {
411 warn(next->pos, "No right hand side of '%s'-expression", show_special(op));
412 break;
414 top->op = op;
415 top->left = left;
416 top->right = right;
417 left = top;
420 out:
421 *tree = left;
422 return next;
425 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
427 return lr_binop_expression(token, tree, EXPR_BINOP, cast_expression, '*', '/', '%', 0);
430 static struct token *additive_expression(struct token *token, struct expression **tree)
432 return lr_binop_expression(token, tree, EXPR_BINOP, multiplicative_expression, '+', '-', 0);
435 static struct token *shift_expression(struct token *token, struct expression **tree)
437 return lr_binop_expression(token, tree, EXPR_BINOP, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0);
440 static struct token *relational_expression(struct token *token, struct expression **tree)
442 return lr_binop_expression(token, tree, EXPR_COMPARE, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0);
445 static struct token *equality_expression(struct token *token, struct expression **tree)
447 return lr_binop_expression(token, tree, EXPR_COMPARE, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0);
450 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
452 return lr_binop_expression(token, tree, EXPR_BINOP, equality_expression, '&', 0);
455 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
457 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_and_expression, '^', 0);
460 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
462 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_xor_expression, '|', 0);
465 static struct token *logical_and_expression(struct token *token, struct expression **tree)
467 return lr_binop_expression(token, tree, EXPR_LOGICAL, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0);
470 static struct token *logical_or_expression(struct token *token, struct expression **tree)
472 return lr_binop_expression(token, tree, EXPR_LOGICAL, logical_and_expression, SPECIAL_LOGICAL_OR, 0);
475 struct token *conditional_expression(struct token *token, struct expression **tree)
477 token = logical_or_expression(token, tree);
478 if (match_op(token, '?')) {
479 struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
480 expr->op = token->special;
481 expr->left = *tree;
482 *tree = expr;
483 token = parse_expression(token->next, &expr->cond_true);
484 token = expect(token, ':', "in conditional expression");
485 token = conditional_expression(token, &expr->cond_false);
487 return token;
490 struct token *assignment_expression(struct token *token, struct expression **tree)
492 token = conditional_expression(token, tree);
493 if (token_type(token) == TOKEN_SPECIAL) {
494 static const int assignments[] = {
495 '=',
496 SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
497 SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
498 SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
499 SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
500 SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN };
501 int i, op = token->special;
502 for (i = 0; i < sizeof(assignments)/sizeof(int); i++)
503 if (assignments[i] == op) {
504 struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
505 expr->left = *tree;
506 expr->op = op;
507 *tree = expr;
508 return assignment_expression(token->next, &expr->right);
511 return token;
514 static struct token *comma_expression(struct token *token, struct expression **tree)
516 return lr_binop_expression(token, tree, EXPR_COMMA, assignment_expression, ',', 0);
519 struct token *parse_expression(struct token *token, struct expression **tree)
521 return comma_expression(token,tree);