aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2003-05-19 13:13:45 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:00:42 -0700
commit920bc36ceb09117937d01131ca743efe44478c67 (patch)
tree83acf28b0d2f0ebb9848417f270915fef0b7e9ac
parentClean up for/while/do parsing by separating them out (diff)
downloadsparse-920bc36ceb09117937d01131ca743efe44478c67.tar.gz
sparse-920bc36ceb09117937d01131ca743efe44478c67.tar.bz2
sparse-920bc36ceb09117937d01131ca743efe44478c67.zip
Parse C99 style 'for()' statements with variable declarations.
-rw-r--r--parse.c17
-rw-r--r--parse.h1
-rw-r--r--show-parse.c17
3 files changed, 25 insertions, 10 deletions
diff --git a/parse.c b/parse.c
index ba17fd3..e6a9ec8 100644
--- a/parse.c
+++ b/parse.c
@@ -24,6 +24,7 @@
#include "expression.h"
static struct token *statement(struct token *token, struct statement **tree);
+static struct token *external_declaration(struct token *token, struct symbol_list **list);
struct statement *alloc_statement(struct position pos, int type)
{
@@ -678,19 +679,29 @@ static void add_case_statement(struct statement *stmt)
static struct token *parse_for_statement(struct token *token, struct statement *stmt)
{
+ struct symbol_list *syms;
struct expression *e1, *e2, *e3;
struct statement *iterator;
start_iterator(stmt);
token = expect(token->next, '(', "after 'for'");
- token = parse_expression(token, &e1);
- token = expect(token, ';', "in 'for'");
+
+ syms = NULL;
+ e1 = NULL;
+ /* C99 variable declaration? */
+ if (lookup_type(token)) {
+ token = external_declaration(token, &syms);
+ } else {
+ token = parse_expression(token, &e1);
+ token = expect(token, ';', "in 'for'");
+ }
token = parse_expression(token, &e2);
token = expect(token, ';', "in 'for'");
token = parse_expression(token, &e3);
token = expect(token, ')', "in 'for'");
token = statement(token, &iterator);
+ stmt->iterator_syms = syms;
stmt->iterator_pre_statement = make_statement(e1);
stmt->iterator_pre_condition = e2;
stmt->iterator_post_statement = make_statement(e3);
@@ -885,8 +896,6 @@ static struct token *parameter_type_list(struct token *token, struct symbol *fn)
return token;
}
-static struct token *external_declaration(struct token *token, struct symbol_list **list);
-
struct token *compound_statement(struct token *token, struct statement *stmt)
{
while (!eof_token(token)) {
diff --git a/parse.h b/parse.h
index b5de862..42fa081 100644
--- a/parse.h
+++ b/parse.h
@@ -61,6 +61,7 @@ struct statement {
struct iterator_struct {
struct symbol *iterator_break;
struct symbol *iterator_continue;
+ struct symbol_list *iterator_syms;
struct statement *iterator_pre_statement;
struct expression *iterator_pre_condition;
diff --git a/show-parse.c b/show-parse.c
index ea24001..556e01e 100644
--- a/show-parse.c
+++ b/show-parse.c
@@ -383,6 +383,14 @@ static void show_switch_statement(struct statement *stmt)
printf(".L%p:\n", stmt->switch_break);
}
+static void show_symbol_decl(struct symbol_list *syms)
+{
+ struct symbol *sym;
+ FOR_EACH_PTR(syms, sym) {
+ show_symbol_init(sym);
+ } END_FOR_EACH_PTR;
+}
+
/*
* Print out a statement
*/
@@ -394,14 +402,10 @@ int show_statement(struct statement *stmt)
case STMT_RETURN:
return show_return_stmt(stmt);
case STMT_COMPOUND: {
- struct symbol *sym;
struct statement *s;
- int last;
-
- FOR_EACH_PTR(stmt->syms, sym) {
- show_symbol_init(sym);
- } END_FOR_EACH_PTR;
+ int last = 0;
+ show_symbol_decl(stmt->syms);
FOR_EACH_PTR(stmt->stmts, s) {
last = show_statement(s);
} END_FOR_EACH_PTR;
@@ -452,6 +456,7 @@ int show_statement(struct statement *stmt)
struct expression *post_condition = stmt->iterator_post_condition;
int val, loop_top = 0, loop_bottom = 0;
+ show_symbol_decl(stmt->iterator_syms);
show_statement(pre_statement);
if (pre_condition) {
if (pre_condition->type == EXPR_VALUE) {