aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-18 12:19:13 +0200
committerEugen Wissner <belka@caraus.de>2026-09-18 12:19:13 +0200
commitdc9d03915c4b169fec749081b45d56f722105813 (patch)
tree0a0719bc95f942b675fb52865d9c5bac9e105767 /gcc
parentb575036fe804f14b78da74897a74b010cc94f730 (diff)
downloadelna-dc9d03915c4b169fec749081b45d56f722105813.tar.gz
Allow block-local variables
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/elna-generic.cc39
1 files changed, 25 insertions, 14 deletions
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index 60ed82b..f4cb3c3 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -980,7 +980,7 @@ namespace elna::gcc
if (statement->alternative != nullptr)
{
enter_scope();
- visit_statements(*statement->alternative);
+ visit_block(*statement->alternative);
result = leave_scope();
}
@@ -1001,7 +1001,7 @@ namespace elna::gcc
tree condition = this->current_expression;
enter_scope();
- visit_statements(branch.statements);
+ visit_block(branch.body);
if (goto_append != NULL_TREE)
{
append_statement(goto_append);
@@ -1032,7 +1032,7 @@ namespace elna::gcc
append_statement(build1(LABEL_EXPR, void_type_node, loop_label));
enter_scope();
- visit_statements(statement->body);
+ visit_block(statement->body);
tree repeat_binding = leave_scope();
append_statement(repeat_binding);
@@ -1077,7 +1077,7 @@ namespace elna::gcc
enter_scope();
// Declare control variable with the unqualified type. The constant_type wrapper
// is for semantic checking only, because GENERIC needs to modify the control variable.
- auto control_variable_info = statement->symbols->lookup(statement->control_variable.name());
+ auto control_variable_info = statement->body.symbols->lookup(statement->control_variable.name());
const boot::variable_info unqualified_info(
boot::resolve_underlying_type(control_variable_info->is_variable()->symbol),
control_variable_info->is_variable()->is_extern);
@@ -1087,7 +1087,7 @@ namespace elna::gcc
tree counter_declaration{ NULL_TREE };
if (statement->counter != nullptr)
{
- auto counter_info = statement->symbols->lookup(statement->counter->name());
+ auto counter_info = statement->body.symbols->lookup(statement->counter->name());
counter_declaration = declare_local_variable(*statement->counter,
*counter_info->is_variable(), elna_word_one_node);
}
@@ -1097,7 +1097,7 @@ namespace elna::gcc
// The body gets its own scope, so that defer statements in it are run on
// every iteration and not once for the whole loop.
enter_scope();
- visit_statements(statement->body);
+ visit_block(statement->body);
tree body_binding = leave_scope();
append_statement(body_binding);
@@ -1158,10 +1158,21 @@ namespace elna::gcc
}
}
+ void generic_visitor::visit_block(boot::block& body)
+ {
+ this->bag.enter(body.symbols);
+ for (boot::variable_declaration *const variable : body.variables)
+ {
+ variable->accept(this);
+ }
+ visit_statements(body.statements);
+ this->bag.leave();
+ }
+
void generic_visitor::visit(boot::defer_statement *statement)
{
enter_scope();
- visit_statements(statement->statements);
+ visit_block(statement->body);
defer(leave_scope());
}
@@ -1172,7 +1183,7 @@ namespace elna::gcc
enter_scope();
this->symbols->enter(statement->name.name(), end_label);
- visit_statements(statement->statements);
+ visit_block(statement->body);
append_statement(leave_scope());
// The label sits outside the binding, so that a break leaving the block
@@ -1216,7 +1227,7 @@ namespace elna::gcc
tree end_label_declaration = create_artificial_label(get_location(&statement->position()));
tree switch_statements = alloc_stmt_list();
- for (const boot::switch_case& case_block : statement->cases)
+ for (boot::switch_case& case_block : statement->cases)
{
for (boot::expression *const case_label : case_block.labels)
{
@@ -1230,7 +1241,7 @@ namespace elna::gcc
append_to_statement_list(case_expression, &switch_statements);
}
enter_scope();
- visit_statements(case_block.statements);
+ visit_block(case_block.body);
append_to_statement_list(leave_scope(), &switch_statements);
tree goto_end = build1(GOTO_EXPR, void_type_node, end_label_declaration);
@@ -1245,7 +1256,7 @@ namespace elna::gcc
append_to_statement_list(case_expression, &switch_statements);
enter_scope();
- visit_statements(*statement->alternative);
+ visit_block(*statement->alternative);
append_to_statement_list(leave_scope(), &switch_statements);
TREE_USED(end_label_declaration) = 1;
@@ -1267,10 +1278,10 @@ namespace elna::gcc
if (statement->alternative != nullptr)
{
enter_scope();
- visit_statements(*statement->alternative);
+ visit_block(*statement->alternative);
result = leave_scope();
}
- for (const boot::switch_case& case_block : statement->cases | std::views::reverse)
+ for (boot::switch_case& case_block : statement->cases | std::views::reverse)
{
tree case_condition = boolean_false_node;
for (boot::expression *const case_label : case_block.labels)
@@ -1285,7 +1296,7 @@ namespace elna::gcc
}
enter_scope();
- visit_statements(case_block.statements);
+ visit_block(case_block.body);
tree then_body = leave_scope();
result = build3(COND_EXPR, void_type_node, case_condition, then_body, result);