Support variable declaration initializer

This commit is contained in:
2025-08-19 22:58:39 +02:00
parent 569139d44a
commit 0c2a396320
10 changed files with 175 additions and 102 deletions

View File

@@ -745,40 +745,57 @@ namespace elna::gcc
void generic_visitor::visit(boot::variable_declaration *declaration)
{
this->current_expression = get_inner_alias(
this->bag.lookup(declaration->identifier.identifier)->is_variable()->symbol,
this->symbols);
for (const auto& variable_identifier : declaration->identifiers)
{
this->current_expression = get_inner_alias(
this->bag.lookup(variable_identifier.identifier)->is_variable()->symbol,
this->symbols);
location_t declaration_location = get_location(&declaration->position());
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
get_identifier(declaration->identifier.identifier.c_str()), this->current_expression);
bool result = this->symbols->enter(declaration->identifier.identifier, declaration_tree);
location_t declaration_location = get_location(&declaration->position());
tree declaration_tree = build_decl(declaration_location, VAR_DECL,
get_identifier(variable_identifier.identifier.c_str()), this->current_expression);
bool result = this->symbols->enter(variable_identifier.identifier, declaration_tree);
if (POINTER_TYPE_P(this->current_expression))
{
DECL_INITIAL(declaration_tree) = elna_pointer_nil_node;
}
TREE_PUBLIC(declaration_tree) = declaration->identifier.exported;
this->current_expression = NULL_TREE;
if (!result)
{
error_at(declaration_location, "Variable '%s' already declared in this scope",
declaration->identifier.identifier.c_str());
}
else if (lang_hooks.decls.global_bindings_p())
{
TREE_STATIC(declaration_tree) = 1;
varpool_node::get_create(declaration_tree);
varpool_node::finalize_decl(declaration_tree);
}
else
{
DECL_CONTEXT(declaration_tree) = current_function_decl;
f_names = chainon(f_names, declaration_tree);
if (declaration->body != nullptr)
{
declaration->body->accept(this);
if (is_assignable_from(TREE_TYPE(declaration_tree), this->current_expression))
{
DECL_INITIAL(declaration_tree) = this->current_expression;
}
else
{
error_at(declaration_location, "Cannot initialize variable of type '%s' with a value of type '%s'",
print_type(TREE_TYPE(declaration_tree)).c_str(),
print_type(TREE_TYPE(this->current_expression)).c_str());
}
}
else if (POINTER_TYPE_P(this->current_expression))
{
DECL_INITIAL(declaration_tree) = elna_pointer_nil_node;
}
TREE_PUBLIC(declaration_tree) = variable_identifier.exported;
this->current_expression = NULL_TREE;
if (!result)
{
error_at(declaration_location, "Variable '%s' already declared in this scope",
variable_identifier.identifier.c_str());
}
else if (lang_hooks.decls.global_bindings_p())
{
TREE_STATIC(declaration_tree) = 1;
varpool_node::get_create(declaration_tree);
varpool_node::finalize_decl(declaration_tree);
}
else
{
DECL_CONTEXT(declaration_tree) = current_function_decl;
f_names = chainon(f_names, declaration_tree);
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
void_type_node, declaration_tree);
append_statement(declaration_statement);
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
void_type_node, declaration_tree);
append_statement(declaration_statement);
}
}
}