aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-26 12:17:48 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 20:59:49 -0700
commitc37b806b9ac71d4f7359b7592f2a8113afb159f5 (patch)
tree1bc4fa3a7aedeba463130d8dcd59227a4f1ccb0a
parent90710c4bafaf5ed14975d8b6c73b9388942b4e7c (diff)
downloadsparse-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.c60
-rw-r--r--expression.c26
-rw-r--r--expression.h4
-rw-r--r--show-parse.c7
4 files changed, 78 insertions, 19 deletions
diff --git a/evaluate.c b/evaluate.c
index 7dcbd08d..2678bfa3 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -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);