diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-26 12:17:48 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 20:59:49 -0700 |
| commit | c37b806b9ac71d4f7359b7592f2a8113afb159f5 (patch) | |
| tree | 1bc4fa3a7aedeba463130d8dcd59227a4f1ccb0a | |
| parent | 90710c4bafaf5ed14975d8b6c73b9388942b4e7c (diff) | |
| download | sparse-dev-c37b806b9ac71d4f7359b7592f2a8113afb159f5.tar.gz | |
Give comma expressions and comparison expressions different types,
even though they parse like other binops: they have different semantic
type behaviour, and should be evaluated separately.
Show bitfield symbol types.
| -rw-r--r-- | evaluate.c | 60 | ||||
| -rw-r--r-- | expression.c | 26 | ||||
| -rw-r--r-- | expression.h | 4 | ||||
| -rw-r--r-- | show-parse.c | 7 |
4 files changed, 78 insertions, 19 deletions
@@ -125,11 +125,23 @@ static struct expression * promote(struct expression *old, struct symbol *type) return expr; } -static int evaluate_binop(struct expression *expr) +static struct symbol * compatible_binop(struct expression *expr) { struct expression *left = expr->left, *right = expr->right; struct symbol *ltype = left->ctype, *rtype = right->ctype; + /* Pointer types? */ + if (ltype->type == SYM_PTR || rtype->type == SYM_PTR) { + /* NULL pointer? */ + if (left->type == EXPR_VALUE && !left->value) + return &ptr_ctype; + if (right->type == EXPR_VALUE && !right->value) + return &ptr_ctype; + + // FIXME!! + return ltype; + } + /* Integer promotion? */ if (ltype->ctype.base_type == &int_type && rtype->ctype.base_type == &int_type) { struct symbol *ctype = bigger_int_type(ltype, rtype); @@ -139,11 +151,37 @@ static int evaluate_binop(struct expression *expr) expr->left = promote(left, ctype); if (rtype->bit_size != ctype->bit_size) expr->right = promote(right, ctype); - expr->ctype = ctype; - return 1; + return ctype; } - warn(expr->token, "unexpected types for operation"); - return 0; + + warn(expr->token, "incompatible types for operation"); + return NULL; +} + +static int evaluate_binop(struct expression *expr) +{ + struct symbol *ctype; + // FIXME! handle int + ptr and ptr - ptr here + + ctype = compatible_binop(expr); + if (!ctype) + return 0; + expr->ctype = ctype; + return 1; +} + +static int evaluate_comma(struct expression *expr) +{ + expr->ctype = expr->right->ctype; + return 1; +} + +static int evaluate_compare(struct expression *expr) +{ + if (!compatible_binop(expr)) + return 0; + expr->ctype = &bool_ctype; + return 1; } static int evaluate_assignment(struct expression *expr) @@ -362,6 +400,18 @@ int evaluate_expression(struct expression *expr) if (!evaluate_expression(expr->right)) return 0; return evaluate_binop(expr); + case EXPR_COMMA: + if (!evaluate_expression(expr->left)) + return 0; + if (!evaluate_expression(expr->right)) + return 0; + return evaluate_comma(expr); + case EXPR_COMPARE: + if (!evaluate_expression(expr->left)) + return 0; + if (!evaluate_expression(expr->right)) + return 0; + return evaluate_compare(expr); case EXPR_ASSIGNMENT: if (!evaluate_lvalue_expression(expr->left)) return 0; diff --git a/expression.c b/expression.c index 0d3f66f7..62f196a9 100644 --- a/expression.c +++ b/expression.c @@ -231,7 +231,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr /* Generic left-to-right binop parsing */ static struct token *lr_binop_expression(struct token *token, struct expression **tree, - struct token *(*inner)(struct token *, struct expression **), ...) + enum expression_type type, struct token *(*inner)(struct token *, struct expression **), ...) { struct expression *left = NULL; struct token * next = inner(token, &left); @@ -251,7 +251,7 @@ static struct token *lr_binop_expression(struct token *token, struct expression break; } va_end(args); - top = alloc_expression(next, EXPR_BINOP); + top = alloc_expression(next, type); next = inner(next->next, &right); if (!right) { warn(next, "No right hand side of '%s'-expression", show_special(op)); @@ -270,52 +270,52 @@ out: static struct token *multiplicative_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, cast_expression, '*', '/', '%', 0); + return lr_binop_expression(token, tree, EXPR_BINOP, cast_expression, '*', '/', '%', 0); } static struct token *additive_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, multiplicative_expression, '+', '-', 0); + return lr_binop_expression(token, tree, EXPR_BINOP, multiplicative_expression, '+', '-', 0); } static struct token *shift_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0); + return lr_binop_expression(token, tree, EXPR_BINOP, additive_expression, SPECIAL_LEFTSHIFT, SPECIAL_RIGHTSHIFT, 0); } static struct token *relational_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0); + return lr_binop_expression(token, tree, EXPR_COMPARE, shift_expression, '<', '>', SPECIAL_LTE, SPECIAL_GTE, 0); } static struct token *equality_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0); + return lr_binop_expression(token, tree, EXPR_COMPARE, relational_expression, SPECIAL_EQUAL, SPECIAL_NOTEQUAL, 0); } static struct token *bitwise_and_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, equality_expression, '&', 0); + return lr_binop_expression(token, tree, EXPR_BINOP, equality_expression, '&', 0); } static struct token *bitwise_xor_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, bitwise_and_expression, '^', 0); + return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_and_expression, '^', 0); } static struct token *bitwise_or_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, bitwise_xor_expression, '|', 0); + return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_xor_expression, '|', 0); } static struct token *logical_and_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0); + return lr_binop_expression(token, tree, EXPR_BINOP, bitwise_or_expression, SPECIAL_LOGICAL_AND, 0); } static struct token *logical_or_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, logical_and_expression, SPECIAL_LOGICAL_OR, 0); + return lr_binop_expression(token, tree, EXPR_BINOP, logical_and_expression, SPECIAL_LOGICAL_OR, 0); } struct token *conditional_expression(struct token *token, struct expression **tree) @@ -358,7 +358,7 @@ struct token *assignment_expression(struct token *token, struct expression **tre static struct token *comma_expression(struct token *token, struct expression **tree) { - return lr_binop_expression(token, tree, assignment_expression, ',', 0); + return lr_binop_expression(token, tree, EXPR_COMMA, assignment_expression, ',', 0); } struct token *parse_expression(struct token *token, struct expression **tree) diff --git a/expression.h b/expression.h index 56a1d7df..3b0bd635 100644 --- a/expression.h +++ b/expression.h @@ -24,6 +24,8 @@ enum expression_type { EXPR_CONDITIONAL, EXPR_STATEMENT, EXPR_CALL, + EXPR_COMMA, + EXPR_COMPARE, }; struct expression { @@ -43,7 +45,7 @@ struct expression { // EXPR_STATEMENT struct statement *statement; - // EXPR_BINOP and EXPR_ASSIGNMENT + // EXPR_BINOP, EXPR_COMMA, EXPR_COMPARE and EXPR_ASSIGNMENT struct binop_arg { struct expression *left, *right; }; diff --git a/show-parse.c b/show-parse.c index b3badd2c..99ade4c3 100644 --- a/show-parse.c +++ b/show-parse.c @@ -159,6 +159,11 @@ void show_type(struct symbol *sym) return; } + case SYM_BITFIELD: + show_type(sym->ctype.base_type); + printf(":%d", sym->fieldwidth); + return; + default: printf("strange type %d '%s' of type ", sym->type, show_token(sym->token)); show_type(sym->ctype.base_type); @@ -372,6 +377,8 @@ void show_expression(struct expression *expr) show_expression(expr->right); break; case EXPR_BINOP: + case EXPR_COMMA: + case EXPR_COMPARE: show_expression(expr->left); printf(" %s ", show_special(expr->op)); show_expression(expr->right); |
