aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-31 10:38:49 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 20:59:55 -0700
commitbdc6803647b8feb99bf35fa9d5b533351ae3dc4f (patch)
tree58cc00deeb16c86dfb481e1f32cee7dfc98630c3
parentStart doing constant strings right: do proper concatenation of strings, (diff)
downloadsparse-bdc6803647b8feb99bf35fa9d5b533351ae3dc4f.tar.gz
sparse-bdc6803647b8feb99bf35fa9d5b533351ae3dc4f.tar.bz2
sparse-bdc6803647b8feb99bf35fa9d5b533351ae3dc4f.zip
Parse initializers properly. We parsed them before, but we didn't
add them to the parse tree. We now do.
-rw-r--r--evaluate.c11
-rw-r--r--expression.c2
-rw-r--r--expression.h13
-rw-r--r--parse.c55
-rw-r--r--show-parse.c30
-rw-r--r--symbol.h1
-rw-r--r--test-parsing.c2
7 files changed, 82 insertions, 32 deletions
diff --git a/evaluate.c b/evaluate.c
index 56dad07..fcec95b 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -791,6 +791,17 @@ int evaluate_expression(struct expression *expr)
case EXPR_STATEMENT:
// FIXME!! Statement expression
return 0;
+ case EXPR_INITIALIZER:
+ if (!evaluate_expression_list(expr->expr_list))
+ return 0;
+ // FIXME! Figure out the type of the initializer!
+ return 0;
+ case EXPR_IDENTIFIER:
+ // FIXME!! Identifier
+ return 0;
+ case EXPR_INDEX:
+ // FIXME!! Array identifier index
+ return 0;
}
return 0;
}
diff --git a/expression.c b/expression.c
index e2d41cc..5592ccf 100644
--- a/expression.c
+++ b/expression.c
@@ -252,7 +252,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr
cast->cast_type = sym->ctype.base_type;
token = expect(token, ')', "at end of cast operator");
if (match_op(token, '{'))
- return initializer(token, &cast->cast_type->ctype);
+ return initializer(&cast->cast_expression, token);
token = cast_expression(token, &cast->cast_expression);
*tree = cast;
return token;
diff --git a/expression.h b/expression.h
index 21297b5..c0d701d 100644
--- a/expression.h
+++ b/expression.h
@@ -28,6 +28,9 @@ enum expression_type {
EXPR_COMMA,
EXPR_COMPARE,
EXPR_BITFIELD,
+ EXPR_INITIALIZER, // initializer list
+ EXPR_IDENTIFIER, // identifier in initializer
+ EXPR_INDEX, // index in initializer
};
struct expression {
@@ -85,6 +88,14 @@ struct expression {
unsigned char bitpos, nrbits;
struct expression *address;
};
+ // EXPR_INITIALIZER
+ struct expression_list *expr_list;
+ // EXPR_IDENTIFIER
+ struct ident *expr_ident;
+ // EXPR_INDEX
+ struct index_expr {
+ unsigned int idx_from, idx_to;
+ };
};
};
@@ -120,7 +131,7 @@ static inline int lookup_type(struct token *token)
/* Statement parsing */
struct statement *alloc_statement(struct token * token, int type);
-struct token *initializer(struct token *token, struct ctype *type);
+struct token *initializer(struct expression **tree, struct token *token);
struct token *compound_statement(struct token *, struct statement *);
/* The preprocessor calls this 'constant_expression()' */
diff --git a/parse.c b/parse.c
index bd5c441..ce1926e 100644
--- a/parse.c
+++ b/parse.c
@@ -719,10 +719,32 @@ struct token *compound_statement(struct token *token, struct statement *stmt)
return token;
}
-static struct token *initializer_list(struct token *token, struct ctype *type)
+static struct expression *identifier_expression(struct token *token)
+{
+ struct expression *expr = alloc_expression(token->pos, EXPR_IDENTIFIER);
+ expr->expr_ident = token->ident;
+ return expr;
+}
+
+static struct token *initializer_list(struct expression_list **list, struct token *token)
{
for (;;) {
- token = initializer(token, type);
+ struct token *next = token->next;
+ struct expression *expr;
+
+ if (match_op(token, '.') && (token_type(next) == TOKEN_IDENT) && match_op(next->next, '=')) {
+ add_expression(list, identifier_expression(next));
+ token = next->next->next;
+ } else if ((token_type(token) == TOKEN_IDENT) && match_op(next, ':')) {
+ add_expression(list, identifier_expression(token));
+ token = next->next;
+ }
+
+ expr = NULL;
+ token = initializer(&expr, token);
+ if (!expr)
+ break;
+ add_expression(list, expr);
if (!match_op(token, ','))
break;
token = token->next;
@@ -730,32 +752,15 @@ static struct token *initializer_list(struct token *token, struct ctype *type)
return token;
}
-struct token *parse_named_initializer(struct token *id, struct token *token)
+struct token *initializer(struct expression **tree, struct token *token)
{
- struct expression *expr;
-
- return assignment_expression(token, &expr);
-}
-
-struct token *initializer(struct token *token, struct ctype *type)
-{
- struct expression *expr;
- struct token *next, *name = NULL;
-
- next = token->next;
- if (match_op(token, '.') && (token_type(next) == TOKEN_IDENT) && match_op(next->next, '=')) {
- name = next;
- token = next->next->next;
- } else if ((token_type(token) == TOKEN_IDENT) && match_op(next, ':')) {
- name = token;
- token = next->next;
- }
-
if (match_op(token, '{')) {
- token = initializer_list(token->next, type);
+ struct expression *expr = alloc_expression(token->pos, EXPR_INITIALIZER);
+ *tree = expr;
+ token = initializer_list(&expr->expr_list, token->next);
return expect(token, '}', "at end of initializer");
}
- return assignment_expression(token, &expr);
+ return assignment_expression(token, tree);
}
static void declare_argument(struct symbol *sym, void *data, int flags)
@@ -809,7 +814,7 @@ static struct token *external_declaration(struct token *token, struct symbol_lis
for (;;) {
if (match_op(token, '='))
- token = initializer(token->next, &decl->ctype);
+ token = initializer(&decl->initializer, token->next);
if (!match_op(token, ','))
break;
diff --git a/show-parse.c b/show-parse.c
index 7e72093..825d311 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -53,12 +53,12 @@ const char *modifier_string(unsigned long mod)
void show_struct_member(struct symbol *sym, void *data, int flags)
{
if (flags & ITERATE_FIRST)
- printf(" { ");
+ printf(" {\n\t");
printf("%s:%d:%d at offset %ld", show_ident(sym->ident), sym->bit_size, sym->alignment, sym->offset);
if (sym->fieldwidth)
printf("[%d..%d]", sym->bit_offset, sym->bit_offset+sym->fieldwidth-1);
if (flags & ITERATE_LAST)
- printf(" } ");
+ printf("\n} ");
else
printf(", ");
}
@@ -196,21 +196,26 @@ void show_symbol(struct symbol *sym)
case SYM_STRUCT:
printf("\n");
symbol_iterate(type->symbol_list, show_struct_member, NULL);
- return;
+ break;
case SYM_UNION:
printf("\n");
symbol_iterate(type->symbol_list, show_struct_member, NULL);
- return;
+ break;
case SYM_FN:
printf("\n");
show_statement(type->stmt);
- return;
+ break;
default:
break;
}
+
+ if (sym->initializer) {
+ printf(" = ");
+ show_expression(sym->initializer);
+ }
}
/*
@@ -461,6 +466,21 @@ void show_expression(struct expression *expr)
show_expression(expr->address);
printf(")");
break;
+ case EXPR_INITIALIZER:
+ printf(" {\n\t");
+ show_expression_list(expr->expr_list, ", ");
+ printf("\n} ");
+ break;
+ case EXPR_IDENTIFIER:
+ printf("%s: ", show_ident(expr->expr_ident));
+ break;
+ case EXPR_INDEX:
+ if (expr->idx_from == expr->idx_to) {
+ printf("[%d]: ", expr->idx_from);
+ } else {
+ printf("[%d ... %d]: ", expr->idx_from, expr->idx_to);
+ }
+ break;
default:
printf("WTF");
}
diff --git a/symbol.h b/symbol.h
index 46760ec..0b94427 100644
--- a/symbol.h
+++ b/symbol.h
@@ -73,6 +73,7 @@ struct symbol {
struct symbol_list *arguments;
struct statement *stmt;
struct symbol_list *symbol_list;
+ struct expression *initializer;
long long value; /* Initial value */
int fieldwidth;
int arg_count:10, variadic:1;
diff --git a/test-parsing.c b/test-parsing.c
index a2df1f5..48f2ca5 100644
--- a/test-parsing.c
+++ b/test-parsing.c
@@ -119,6 +119,8 @@ static void clean_up_symbol(struct symbol *sym, void *_parent, int flags)
struct symbol *type;
examine_symbol_type(sym);
+ if (sym->initializer)
+ evaluate_expression(sym->initializer);
type = sym->ctype.base_type;
if (type && type->type == SYM_FN) {
symbol_iterate(type->arguments, clean_up_symbol, parent);