[PATCH] line-splicing fixes in sparse
[smatch.git] / expression.c
blob9e2863e5721bb7fa7352042f8f654f8300f85915
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_fp_value(struct expression *expr, struct token *token)
93 static int fp_warned;
95 expr->ctype = &double_ctype;
96 expr->value = 0;
97 if (!fp_warned) {
98 warn(token->pos, "FP values not yet implemented");
99 fp_warned = 1;
103 static void get_number_value(struct expression *expr, struct token *token)
105 const char *str = token->number;
106 unsigned long long value = 0;
107 unsigned int base = 10, digit, bits;
108 unsigned long modifiers, extramod;
110 if (str[0] == '0') {
111 switch (str[1]) {
112 case 'x': case 'X':
113 base = 18; // the -= 2 for the octal case will
114 str++; // skip the '0'
115 /* fallthrough */
116 case '0'...'7':
117 str++; // skip the '0' or 'x/X'
118 base -= 2; // the fall-through will make this 8
121 for (;;) {
122 char c = *str++;
123 if (c == '_')
124 continue;
125 digit = hexval(c);
126 if (digit >= base)
127 break;
128 value = value * base + digit;
130 str--;
131 modifiers = 0;
132 for (;;) {
133 char c = *str++;
134 if (c == 'u' || c == 'U') {
135 modifiers |= MOD_UNSIGNED;
136 continue;
138 if (c == 'l' || c == 'L') {
139 if (modifiers & MOD_LONG)
140 modifiers |= MOD_LONGLONG;
141 modifiers |= MOD_LONG;
142 continue;
144 if (c) {
145 get_fp_value(expr, token);
146 return;
148 break;
151 bits = bits_in_longlong;
152 extramod = 0;
153 if (!(modifiers & MOD_LONGLONG)) {
154 if (value & (~1ULL << (bits_in_long-1))) {
155 extramod = MOD_LONGLONG | MOD_LONG;
156 } else {
157 bits = bits_in_long;
158 if (!(modifiers & MOD_LONG)) {
159 if (value & (~1ULL << (bits_in_int-1))) {
160 extramod = MOD_LONG;
161 } else
162 bits = bits_in_int;
166 if (!(modifiers & MOD_UNSIGNED)) {
167 if (value & (1ULL << (bits-1))) {
168 extramod |= MOD_UNSIGNED;
171 if (extramod) {
173 * Special case: "int" gets promoted directly to "long"
174 * for normal decimal numbers..
176 modifiers |= extramod;
177 if (base == 10 && modifiers == MOD_UNSIGNED) {
178 modifiers = MOD_LONG;
179 if (bits_in_long == bits_in_int)
180 modifiers = MOD_LONG | MOD_UNSIGNED;
183 /* Hex or octal constants don't complain about missing signedness */
184 if (base == 10 || extramod != MOD_UNSIGNED)
185 warn(expr->pos, "constant %s is so big it is%s%s%s",
186 show_token(token),
187 (modifiers & MOD_UNSIGNED) ? " unsigned":"",
188 (modifiers & MOD_LONG) ? " long":"",
189 (modifiers & MOD_LONGLONG) ? " long":"");
192 expr->type = EXPR_VALUE;
193 expr->ctype = ctype_integer(modifiers);
194 expr->value = value;
197 struct token *primary_expression(struct token *token, struct expression **tree)
199 struct expression *expr = NULL;
201 switch (token_type(token)) {
202 case TOKEN_CHAR:
203 expr = alloc_expression(token->pos, EXPR_VALUE);
204 expr->ctype = &int_ctype;
205 expr->value = (unsigned char) token->character;
206 token = token->next;
207 break;
209 case TOKEN_NUMBER:
210 expr = alloc_expression(token->pos, EXPR_VALUE);
211 get_number_value(expr, token);
212 token = token->next;
213 break;
215 case TOKEN_IDENT: {
216 struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
217 struct token *next = token->next;
219 expr = alloc_expression(token->pos, EXPR_SYMBOL);
222 * We support types as real first-class citizens, with type
223 * comparisons etc:
225 * if (typeof(a) == int) ..
227 if (sym && sym->namespace == NS_TYPEDEF) {
228 warn(token->pos, "typename in expression");
229 sym = NULL;
231 expr->symbol_name = token->ident;
232 expr->symbol = sym;
233 token = next;
234 break;
237 case TOKEN_STRING: {
238 expr = alloc_expression(token->pos, EXPR_STRING);
239 token = string_expression(token, expr);
240 break;
243 case TOKEN_SPECIAL:
244 if (token->special == '(') {
245 expr = alloc_expression(token->pos, EXPR_PREOP);
246 expr->op = '(';
247 token = parens_expression(token, &expr->unop, "in expression");
248 break;
250 if (token->special == '[' && lookup_type(token->next)) {
251 expr = alloc_expression(token->pos, EXPR_TYPE);
252 token = typename(token->next, &expr->symbol);
253 token = expect(token, ']', "in type expression");
254 break;
257 default:
260 *tree = expr;
261 return token;
264 static struct token *expression_list(struct token *token, struct expression_list **list)
266 while (!match_op(token, ')')) {
267 struct expression *expr = NULL;
268 token = assignment_expression(token, &expr);
269 if (!expr)
270 break;
271 add_expression(list, expr);
272 if (!match_op(token, ','))
273 break;
274 token = token->next;
276 return token;
280 * extend to deal with the ambiguous C grammar for parsing
281 * a cast expressions followed by an initializer.
283 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
285 struct expression *expr = cast_init_expr;
287 if (!expr)
288 token = primary_expression(token, &expr);
290 while (expr && token_type(token) == TOKEN_SPECIAL) {
291 switch (token->special) {
292 case '[': { /* Array dereference */
293 struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
294 struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
296 deref->op = '*';
297 deref->unop = add;
299 add->op = '+';
300 add->left = expr;
301 token = parse_expression(token->next, &add->right);
302 token = expect(token, ']', "at end of array dereference");
303 expr = deref;
304 continue;
306 case SPECIAL_INCREMENT: /* Post-increment */
307 case SPECIAL_DECREMENT: { /* Post-decrement */
308 struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
309 post->op = token->special;
310 post->unop = expr;
311 expr = post;
312 token = token->next;
313 continue;
315 case SPECIAL_DEREFERENCE: { /* Structure pointer member dereference */
316 /* "x->y" is just shorthand for "(*x).y" */
317 struct expression *inner = alloc_expression(token->pos, EXPR_PREOP);
318 inner->op = '*';
319 inner->unop = expr;
320 expr = inner;
322 /* Fallthrough!! */
323 case '.': { /* Structure member dereference */
324 struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
325 deref->op = '.';
326 deref->deref = expr;
327 token = token->next;
328 if (token_type(token) != TOKEN_IDENT) {
329 warn(token->pos, "Expected member name");
330 break;
332 deref->member = token->ident;
333 token = token->next;
334 expr = deref;
335 continue;
338 case '(': { /* Function call */
339 struct expression *call = alloc_expression(token->pos, EXPR_CALL);
340 call->op = '(';
341 call->fn = expr;
342 token = expression_list(token->next, &call->args);
343 token = expect(token, ')', "in function call");
344 expr = call;
345 continue;
348 default:
349 break;
351 break;
353 *tree = expr;
354 return token;
357 static struct token *cast_expression(struct token *token, struct expression **tree);
358 static struct token *unary_expression(struct token *token, struct expression **tree)
360 if (token_type(token) == TOKEN_IDENT &&
361 (token->ident == &sizeof_ident ||
362 token->ident == &__alignof___ident)) {
363 struct expression *sizeof_ex = alloc_expression(token->pos, EXPR_SIZEOF);
364 *tree = sizeof_ex;
365 tree = &sizeof_ex->unop;
366 token = token->next;
367 if (!match_op(token, '(') || !lookup_type(token->next))
368 return unary_expression(token, &sizeof_ex->cast_expression);
369 token = typename(token->next, &sizeof_ex->cast_type);
370 return expect(token, ')', "at end of sizeof type-name");
373 if (token_type(token) == TOKEN_SPECIAL) {
374 if (match_oplist(token->special,
375 SPECIAL_INCREMENT, SPECIAL_DECREMENT,
376 '&', '*', '+', '-', '~', '!', 0)) {
377 struct expression *unop;
378 struct expression *unary;
379 struct token *next;
381 next = cast_expression(token->next, &unop);
382 if (!unop) {
383 warn(token->pos, "Syntax error in unary expression");
384 return next;
386 unary = alloc_expression(token->pos, EXPR_PREOP);
387 unary->op = token->special;
388 unary->unop = unop;
389 *tree = unary;
390 return next;
393 /* Gcc extension: &&label gives the address of a label */
394 if (match_op(token, SPECIAL_LOGICAL_AND) &&
395 token_type(token->next) == TOKEN_IDENT) {
396 struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
397 label->label_symbol = label_symbol(token->next);
398 *tree = label;
399 return token->next->next;
404 return postfix_expression(token, tree, NULL);
408 * Ambiguity: a '(' can be either a cast-expression or
409 * a primary-expression depending on whether it is followed
410 * by a type or not.
412 * additional ambiguity: a "cast expression" followed by
413 * an initializer is really a postfix-expression.
415 static struct token *cast_expression(struct token *token, struct expression **tree)
417 if (match_op(token, '(')) {
418 struct token *next = token->next;
419 if (lookup_type(next)) {
420 struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
421 struct symbol *sym;
423 token = typename(next, &sym);
424 cast->cast_type = sym;
425 token = expect(token, ')', "at end of cast operator");
426 if (match_op(token, '{')) {
427 token = initializer(&cast->cast_expression, token);
428 return postfix_expression(token, tree, cast);
430 *tree = cast;
431 token = cast_expression(token, &cast->cast_expression);
432 return token;
435 return unary_expression(token, tree);
438 /* Generic left-to-right binop parsing */
439 static struct token *lr_binop_expression(struct token *token, struct expression **tree,
440 enum expression_type type, struct token *(*inner)(struct token *, struct expression **), ...)
442 struct expression *left = NULL;
443 struct token * next = inner(token, &left);
445 if (left) {
446 while (token_type(next) == TOKEN_SPECIAL) {
447 struct expression *top, *right = NULL;
448 int op = next->special;
449 va_list args;
451 va_start(args, inner);
452 for (;;) {
453 int nextop = va_arg(args, int);
454 if (!nextop)
455 goto out;
456 if (op == nextop)
457 break;
459 va_end(args);
460 top = alloc_expression(next->pos, type);
461 next = inner(next->next, &right);
462 if (!right) {
463 warn(next->pos, "No right hand side of '%s'-expression", show_special(op));
464 break;
466 top->op = op;
467 top->left = left;
468 top->right = right;
469 left = top;
472 out:
473 *tree = left;
474 return next;
477 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
479 return lr_binop_expression(token, tree, EXPR_BINOP, cast_expression, '*', '/', '%', 0);
482 static struct token *additive_expression(struct token *token, struct expression **tree)
484 return lr_binop_expression(token, tree, EXPR_BINOP, multiplicative_expression, '+', '-', 0);
487 static struct token *shift_expression(struct token *token, struct expression **tree)
489 return lr_binop_expression(token, tree, EXPR_BINOP, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0);
492 static struct token *relational_expression(struct token *token, struct expression **tree)
494 return lr_binop_expression(token, tree, EXPR_COMPARE, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0);
497 static struct token *equality_expression(struct token *token, struct expression **tree)
499 return lr_binop_expression(token, tree, EXPR_COMPARE, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0);
502 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
504 return lr_binop_expression(token, tree, EXPR_BINOP, equality_expression, '&', 0);
507 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
509 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_and_expression, '^', 0);
512 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
514 return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_xor_expression, '|', 0);
517 static struct token *logical_and_expression(struct token *token, struct expression **tree)
519 return lr_binop_expression(token, tree, EXPR_LOGICAL, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0);
522 static struct token *logical_or_expression(struct token *token, struct expression **tree)
524 return lr_binop_expression(token, tree, EXPR_LOGICAL, logical_and_expression, SPECIAL_LOGICAL_OR, 0);
527 struct token *conditional_expression(struct token *token, struct expression **tree)
529 token = logical_or_expression(token, tree);
530 if (match_op(token, '?')) {
531 struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
532 expr->op = token->special;
533 expr->left = *tree;
534 *tree = expr;
535 token = parse_expression(token->next, &expr->cond_true);
536 token = expect(token, ':', "in conditional expression");
537 token = conditional_expression(token, &expr->cond_false);
539 return token;
542 struct token *assignment_expression(struct token *token, struct expression **tree)
544 token = conditional_expression(token, tree);
545 if (token_type(token) == TOKEN_SPECIAL) {
546 static const int assignments[] = {
547 '=',
548 SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
549 SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
550 SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
551 SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
552 SPECIAL_OR_ASSIGN, SPECIAL_XOR_ASSIGN };
553 int i, op = token->special;
554 for (i = 0; i < sizeof(assignments)/sizeof(int); i++)
555 if (assignments[i] == op) {
556 struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
557 expr->left = *tree;
558 expr->op = op;
559 *tree = expr;
560 return assignment_expression(token->next, &expr->right);
563 return token;
566 static struct token *comma_expression(struct token *token, struct expression **tree)
568 return lr_binop_expression(token, tree, EXPR_COMMA, assignment_expression, ',', 0);
571 struct token *parse_expression(struct token *token, struct expression **tree)
573 return comma_expression(token,tree);