Add scopes to iteration and selection statements.
authorChristoph Mallon <christoph.mallon@gmx.de>
Fri, 4 May 2012 07:30:53 +0000 (09:30 +0200)
committerChristoph Mallon <christoph.mallon@gmx.de>
Fri, 4 May 2012 07:30:53 +0000 (09:30 +0200)
ast2firm.c
ast_t.h
parser.c

index 9d4844d..e490d9b 100644 (file)
@@ -4634,6 +4634,8 @@ static ir_node *declaration_statement_to_firm(declaration_statement_t *statement
 
 static ir_node *if_statement_to_firm(if_statement_t *statement)
 {
+       create_local_declarations(statement->scope.entities);
+
        /* Create the condition. */
        ir_node *true_block  = NULL;
        ir_node *false_block = NULL;
@@ -4697,6 +4699,8 @@ static void jump_if_reachable(ir_node *const target_block)
 
 static ir_node *while_statement_to_firm(while_statement_t *statement)
 {
+       create_local_declarations(statement->scope.entities);
+
        /* Create the header block */
        ir_node *const header_block = new_immBlock();
        jump_to(header_block);
@@ -4756,6 +4760,8 @@ static ir_node *get_break_label(void)
 
 static ir_node *do_while_statement_to_firm(do_while_statement_t *statement)
 {
+       create_local_declarations(statement->scope.entities);
+
        /* create the header block */
        ir_node *header_block = new_immBlock();
 
diff --git a/ast_t.h b/ast_t.h
index dfe84fa..4b94ca2 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -535,6 +535,7 @@ struct declaration_statement_t {
 
 struct if_statement_t {
        statement_base_t  base;
+       scope_t           scope;
        expression_t     *condition;
        statement_t      *true_statement;
        statement_t      *false_statement;
@@ -542,6 +543,7 @@ struct if_statement_t {
 
 struct switch_statement_t {
        statement_base_t        base;
+       scope_t                 scope;
        expression_t           *expression;
        statement_t            *body;
        case_label_statement_t *first_case, *last_case; /**< List of all cases, including default. */
@@ -586,23 +588,25 @@ struct expression_statement_t {
 
 struct while_statement_t {
        statement_base_t  base;
+       scope_t           scope;
        expression_t     *condition;
        statement_t      *body;
 };
 
 struct do_while_statement_t {
        statement_base_t  base;
+       scope_t           scope;
        expression_t     *condition;
        statement_t      *body;
 };
 
 struct for_statement_t {
        statement_base_t  base;
+       scope_t           scope;
        expression_t     *initialisation;
        expression_t     *condition;
        expression_t     *step;
        statement_t      *body;
-       scope_t           scope;
        bool              condition_reachable:1;
        bool              step_reachable:1;
 };
index a04e664..7d8afab 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -118,8 +118,9 @@ static elf_visibility_tag_t default_visibility = ELF_VISIBILITY_DEFAULT;
 #define PUSH_SCOPE(scope) \
        size_t   const top       = environment_top(); \
        scope_t *const new_scope = (scope); \
-       scope_t *const old_scope = scope_push(new_scope)
-#define POP_SCOPE() (assert(current_scope == new_scope), scope_pop(old_scope), environment_pop_to(top))
+       scope_t *const old_scope = (new_scope ? scope_push(new_scope) : NULL)
+#define PUSH_SCOPE_STATEMENT(scope) PUSH_SCOPE(c_mode & (_C99 | _CXX) ? (scope) : NULL)
+#define POP_SCOPE() (new_scope ? assert(current_scope == new_scope), scope_pop(old_scope), environment_pop_to(top) : (void)0)
 
 #define PUSH_EXTENSION() \
        (void)0; \
@@ -9230,6 +9231,7 @@ static statement_t *parse_if(void)
        eat(T_if);
 
        PUSH_PARENT(statement);
+       PUSH_SCOPE_STATEMENT(&statement->ifs.scope);
 
        add_anchor_token(T_else);
 
@@ -9261,6 +9263,7 @@ static statement_t *parse_if(void)
                warningf(WARN_PARENTHESES, pos, "suggest explicit braces to avoid ambiguous 'else'");
        }
 
+       POP_SCOPE();
        POP_PARENT();
        return statement;
 }
@@ -9318,6 +9321,7 @@ static statement_t *parse_switch(void)
        eat(T_switch);
 
        PUSH_PARENT(statement);
+       PUSH_SCOPE_STATEMENT(&statement->switchs.scope);
 
        expression_t *const expr = parse_condition();
        type_t       *      type = skip_typeref(expr->base.type);
@@ -9343,6 +9347,7 @@ static statement_t *parse_switch(void)
        }
        check_enum_cases(&statement->switchs);
 
+       POP_SCOPE();
        POP_PARENT();
        return statement;
 }
@@ -9368,6 +9373,7 @@ static statement_t *parse_while(void)
        eat(T_while);
 
        PUSH_PARENT(statement);
+       PUSH_SCOPE_STATEMENT(&statement->whiles.scope);
 
        expression_t *const cond = parse_condition();
        statement->whiles.condition = cond;
@@ -9377,6 +9383,7 @@ static statement_t *parse_while(void)
 
        statement->whiles.body = parse_loop_body(statement);
 
+       POP_SCOPE();
        POP_PARENT();
        return statement;
 }
@@ -9391,6 +9398,7 @@ static statement_t *parse_do(void)
        eat(T_do);
 
        PUSH_PARENT(statement);
+       PUSH_SCOPE_STATEMENT(&statement->do_while.scope);
 
        add_anchor_token(T_while);
        statement->do_while.body = parse_loop_body(statement);
@@ -9404,6 +9412,7 @@ static statement_t *parse_do(void)
        semantic_condition(cond, "condition of 'do-while'-statement");
        expect(';');
 
+       POP_SCOPE();
        POP_PARENT();
        return statement;
 }
@@ -9418,7 +9427,7 @@ static statement_t *parse_for(void)
        eat(T_for);
 
        PUSH_PARENT(statement);
-       PUSH_SCOPE(&statement->fors.scope);
+       PUSH_SCOPE_STATEMENT(&statement->fors.scope);
 
        expect('(');
        add_anchor_token(')');