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;
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);
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();
struct if_statement_t {
statement_base_t base;
+ scope_t scope;
expression_t *condition;
statement_t *true_statement;
statement_t *false_statement;
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. */
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;
};
#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; \
eat(T_if);
PUSH_PARENT(statement);
+ PUSH_SCOPE_STATEMENT(&statement->ifs.scope);
add_anchor_token(T_else);
warningf(WARN_PARENTHESES, pos, "suggest explicit braces to avoid ambiguous 'else'");
}
+ POP_SCOPE();
POP_PARENT();
return statement;
}
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);
}
check_enum_cases(&statement->switchs);
+ POP_SCOPE();
POP_PARENT();
return statement;
}
eat(T_while);
PUSH_PARENT(statement);
+ PUSH_SCOPE_STATEMENT(&statement->whiles.scope);
expression_t *const cond = parse_condition();
statement->whiles.condition = cond;
statement->whiles.body = parse_loop_body(statement);
+ POP_SCOPE();
POP_PARENT();
return statement;
}
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);
semantic_condition(cond, "condition of 'do-while'-statement");
expect(';');
+ POP_SCOPE();
POP_PARENT();
return statement;
}
eat(T_for);
PUSH_PARENT(statement);
- PUSH_SCOPE(&statement->fors.scope);
+ PUSH_SCOPE_STATEMENT(&statement->fors.scope);
expect('(');
add_anchor_token(')');