Support C types as first-class citizens, allowing type
[smatch.git] / expression.c
blob158387451118eda2e86bcaff947f6a6afa35ac61
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 next = typename(token, &sym);
215 expr->type = EXPR_TYPE;
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 default:
239 *tree = expr;
240 return token;
243 static struct token *expression_list(struct token *token, struct expression_list **list)
245 while (!match_op(token, ')')) {
246 struct expression *expr = NULL;
247 token = assignment_expression(token, &expr);
248 if (!expr)
249 break;
250 add_expression(list, expr);
251 if (!match_op(token, ','))
252 break;
253 token = token->next;
255 return token;
259 * extend to deal with the ambiguous C grammar for parsing
260 * a cast expressions followed by an initializer.
262 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
264 struct expression *expr = cast_init_expr;
266 if (!expr)
267 token = primary_expression(token, &expr);
269 while (expr && token_type(token) == TOKEN_SPECIAL) {
270 switch (token->special) {
271 case '[': { /* Array dereference */
272 struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
273 struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
275 deref->op = '*';
276 deref->unop = add;
278 add->op = '+';
279 add->left = expr;
280 token = parse_expression(token->next, &add->right);
281 token = expect(token, ']', "at end of array dereference");
282 expr = deref;
283 continue;
285 case SPECIAL_INCREMENT: /* Post-increment */
286 case SPECIAL_DECREMENT: { /* Post-decrement */
287 struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
288 post->op = token->special;
289 post->unop = expr;
290 expr = post;
291 token = token->next;
292 continue;
294 case '.': /* Structure member dereference */
295 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
296 struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
297 deref->op = token->special;
298 deref->deref = expr;
299 token = token->next;
300 if (token_type(token) != TOKEN_IDENT) {
301 warn(token->pos, "Expected member name");
302 break;
304 deref->member = token->ident;
305 token = token->next;
306 expr = deref;
307 continue;
310 case '(': { /* Function call */
311 struct expression *call = alloc_expression(token->pos, EXPR_CALL);
312 call->op = '(';
313 call->fn = expr;
314 token = expression_list(token->next, &call->args);
315 token = expect(token, ')', "in function call");
316 expr = call;
317 continue;
320 default:
321 break;
323 break;
325 *tree = expr;
326 return token;
329 static struct token *cast_expression(struct token *token, struct expression **tree);
330 static struct token *unary_expression(struct token *token, struct expression **tree)
332 if (token_type(token) == TOKEN_IDENT &&
333 (token->ident == &sizeof_ident ||
334 token->ident == &__alignof___ident)) {
335 struct expression *sizeof_ex = alloc_expression(token->pos, EXPR_SIZEOF);
336 *tree = sizeof_ex;
337 tree = &sizeof_ex->unop;
338 token = token->next;
339 if (!match_op(token, '(') || !lookup_type(token->next))
340 return unary_expression(token, &sizeof_ex->cast_expression);
341 token = typename(token->next, &sizeof_ex->cast_type);
342 return expect(token, ')', "at end of sizeof type-name");
345 if (token_type(token) == TOKEN_SPECIAL) {
346 if (match_oplist(token->special,
347 SPECIAL_INCREMENT, SPECIAL_DECREMENT,
348 '&', '*', '+', '-', '~', '!', 0)) {
349 struct expression *unary = alloc_expression(token->pos, EXPR_PREOP);
350 unary->op = token->special;
351 *tree = unary;
352 return cast_expression(token->next, &unary->unop);
355 /* Gcc extension: &&label gives the address of a label */
356 if (match_op(token, SPECIAL_LOGICAL_AND) &&
357 token_type(token->next) == TOKEN_IDENT) {
358 struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
359 label->label_symbol = label_symbol(token->next);
360 *tree = label;
361 return token->next->next;
366 return postfix_expression(token, tree, NULL);
370 * Ambiguity: a '(' can be either a cast-expression or
371 * a primary-expression depending on whether it is followed
372 * by a type or not.
374 * additional ambiguity: a "cast expression" followed by
375 * an initializer is really a postfix-expression.
377 static struct token *cast_expression(struct token *token, struct expression **tree)
379 if (match_op(token, '(')) {
380 struct token *next = token->next;
381 if (lookup_type(next)) {
382 struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
383 struct symbol *sym;
385 token = typename(next, &sym);
386 cast->cast_type = sym->ctype.base_type;
387 token = expect(token, ')', "at end of cast operator");
388 if (match_op(token, '{')) {
389 token = initializer(&cast->cast_expression, token);
390 return postfix_expression(token, tree, cast);
392 *tree = cast;
393 token = cast_expression(token, &cast->cast_expression);
394 return token;
397 return unary_expression(token, tree);
400 /* Generic left-to-right binop parsing */
401 static struct token *lr_binop_expression(struct token *token, struct expression **tree,
402 enum expression_type type, struct token *(*inner)(struct token *, struct expression **), ...)
404 struct expression *left = NULL;
405 struct token * next = inner(token, &left);
407 if (left) {
408 while (token_type(next) == TOKEN_SPECIAL) {
409 struct expression *top, *right = NULL;
410 int op = next->special;
411 va_list args;
413 va_start(args, inner);
414 for (;;) {
415 int nextop = va_arg(args, int);
416 if (!nextop)
417 goto out;
418 if (op == nextop)
419 break;
421 va_end(args);
422 top = alloc_expression(next->pos, type);
423 next = inner(next->next, &right);
424 if (!right) {
425 warn(next->pos, "No right hand side of '%s'-expression", show_special(op));
426 break;
428 top->op = op;
429 top->left = left;
430 top->right = right;
431 left = top;
434 out:
435 *tree = left;
436 return next;
439 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
441 return lr_binop_expression(token, tree, EXPR_BINOP, cast_expression, '*', '/', '%', 0);
444 static struct token *additive_expression(struct token *token, struct expression **tree)
446 return lr_binop_expression(token, tree, EXPR_BINOP, multiplicative_expression, '+', '-', 0);
449 static struct token *shift_expression(struct token *token, struct expression **tree)
451 return lr_binop_expression(token, tree, EXPR_BINOP, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0);
454 static struct token *relational_expression(struct token *token, struct expression **tree)
456 return lr_binop_expression(token, tree, EXPR_COMPARE, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0);
459 static struct token *equality_expression(struct token *token, struct expression **tree)
461 return lr_binop_expression(token, tree, EXPR_COMPARE, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0);
464 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
466 return lr_binop_expression(token, tree, EXPR_BINOP, equality_expression, '&', 0);
469 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
471 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_and_expression, '^', 0);
474 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
476 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_xor_expression, '|', 0);
479 static struct token *logical_and_expression(struct token *token, struct expression **tree)
481 return lr_binop_expression(token, tree, EXPR_LOGICAL, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0);
484 static struct token *logical_or_expression(struct token *token, struct expression **tree)
486 return lr_binop_expression(token, tree, EXPR_LOGICAL, logical_and_expression, SPECIAL_LOGICAL_OR, 0);
489 struct token *conditional_expression(struct token *token, struct expression **tree)
491 token = logical_or_expression(token, tree);
492 if (match_op(token, '?')) {
493 struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
494 expr->op = token->special;
495 expr->left = *tree;
496 *tree = expr;
497 token = parse_expression(token->next, &expr->cond_true);
498 token = expect(token, ':', "in conditional expression");
499 token = conditional_expression(token, &expr->cond_false);
501 return token;
504 struct token *assignment_expression(struct token *token, struct expression **tree)
506 token = conditional_expression(token, tree);
507 if (token_type(token) == TOKEN_SPECIAL) {
508 static const int assignments[] = {
509 '=',
510 SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
511 SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
512 SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
513 SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
514 SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN };
515 int i, op = token->special;
516 for (i = 0; i < sizeof(assignments)/sizeof(int); i++)
517 if (assignments[i] == op) {
518 struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
519 expr->left = *tree;
520 expr->op = op;
521 *tree = expr;
522 return assignment_expression(token->next, &expr->right);
525 return token;
528 static struct token *comma_expression(struct token *token, struct expression **tree)
530 return lr_binop_expression(token, tree, EXPR_COMMA, assignment_expression, ',', 0);
533 struct token *parse_expression(struct token *token, struct expression **tree)
535 return comma_expression(token,tree);