diff options
author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-03-31 10:38:49 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 20:59:55 -0700 |
commit | bdc6803647b8feb99bf35fa9d5b533351ae3dc4f (patch) | |
tree | 58cc00deeb16c86dfb481e1f32cee7dfc98630c3 | |
parent | Start doing constant strings right: do proper concatenation of strings, (diff) | |
download | sparse-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.c | 11 | ||||
-rw-r--r-- | expression.c | 2 | ||||
-rw-r--r-- | expression.h | 13 | ||||
-rw-r--r-- | parse.c | 55 | ||||
-rw-r--r-- | show-parse.c | 30 | ||||
-rw-r--r-- | symbol.h | 1 | ||||
-rw-r--r-- | test-parsing.c | 2 |
7 files changed, 82 insertions, 32 deletions
@@ -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()' */ @@ -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"); } @@ -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); |