Set variable declaration context

This commit is contained in:
Eugen Wissner 2025-01-04 20:24:34 +01:00
parent a7b0c53d23
commit 98c13f0be3
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
4 changed files with 103 additions and 12 deletions

View File

@ -1,5 +1,4 @@
#include "elna/gcc/elna-generic.h"
#include "elna/gcc/elna-tree.h"
#include "elna/gcc/elna-diagnostic.h"
#include "input.h"
@ -93,18 +92,16 @@ namespace gcc
build_int_cst_type(integer_type_node, 0));
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
this->current_statements = alloc_stmt_list();
empty_visitor::visit(program);
enter_scope();
empty_visitor::visit(program);
append_to_statement_list(return_stmt, &this->current_statements);
tree_symbol_mapping mapping = leave_scope();
tree new_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
tree bind_expr = build3(BIND_EXPR, void_type_node, NULL_TREE, this->current_statements, new_block);
BLOCK_SUPERCONTEXT(new_block) = this->main_fndecl;
DECL_INITIAL(this->main_fndecl) = new_block;
DECL_SAVED_TREE(this->main_fndecl) = bind_expr;
BLOCK_SUPERCONTEXT(mapping.block()) = this->main_fndecl;
DECL_INITIAL(this->main_fndecl) = mapping.block();
DECL_SAVED_TREE(this->main_fndecl) = mapping.bind_expression();
DECL_EXTERNAL(this->main_fndecl) = 0;
DECL_PRESERVE_P(this->main_fndecl) = 1;
@ -114,6 +111,22 @@ namespace gcc
cgraph_node::finalize_function(this->main_fndecl, true);
}
void generic_visitor::enter_scope()
{
this->current_statements = alloc_stmt_list();
this->variable_chain = tree_chain();
}
tree_symbol_mapping generic_visitor::leave_scope()
{
tree new_block = build_block(variable_chain.head(),
NULL_TREE, NULL_TREE, NULL_TREE);
tree bind_expr = build3(BIND_EXPR, void_type_node, variable_chain.head(),
this->current_statements, new_block);
return tree_symbol_mapping{ bind_expr, new_block };
}
void generic_visitor::visit(source::number_literal<std::int32_t> *literal)
{
this->current_expression = build_int_cst_type(integer_type_node, literal->number());
@ -304,9 +317,11 @@ namespace gcc
get_identifier(declaration->identifier().c_str()), declaration_type);
auto result = this->symbol_map.insert({ declaration->identifier(), declaration_tree });
// DECL_CONTEXT(declaration_tree) = this->main_fndecl;
if (result.second)
{
DECL_CONTEXT(declaration_tree) = this->main_fndecl;
variable_chain.append(declaration_tree);
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
void_type_node, declaration_tree);
append_to_statement_list(declaration_statement, &this->current_statements);

View File

@ -22,5 +22,45 @@ namespace gcc
return TREE_CODE(type) == POINTER_TYPE
&& TYPE_MAIN_VARIANT(TREE_TYPE(type)) == char_type_node;
}
tree tree_chain_base::head()
{
return first;
}
void tree_chain_base::append(tree t)
{
gcc_assert(t != NULL_TREE);
if (this->first == NULL_TREE)
{
this->first = this->last = t;
}
else
{
chain(t);
this->last = t;
}
}
void tree_chain::chain(tree t)
{
TREE_CHAIN(this->last) = t;
}
tree_symbol_mapping::tree_symbol_mapping(tree bind_expression, tree block)
: m_bind_expression(bind_expression), m_block(block)
{
}
tree tree_symbol_mapping::bind_expression()
{
return m_bind_expression;
}
tree tree_symbol_mapping::block()
{
return m_block;
}
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "elna/source/ast.h"
#include "elna/gcc/elna-tree.h"
#include "config.h"
#include "system.h"
@ -21,8 +22,12 @@ namespace gcc
tree current_expression{ NULL_TREE };
std::unordered_map<std::string, tree> symbol_map;
tree main_fndecl{ NULL_TREE };
tree_chain variable_chain;
tree build_label_decl (const char *name, location_t loc);
tree build_label_decl(const char *name, location_t loc);
void enter_scope();
tree_symbol_mapping leave_scope();
public:
void visit(source::program *program) override;

View File

@ -23,5 +23,36 @@ namespace gcc
{
void init_ttree();
bool is_string_type(tree type);
class tree_chain_base
{
protected:
tree first{};
tree last{};
public:
tree head();
void append(tree t);
protected:
virtual void chain(tree t) = 0;
};
class tree_chain final : public tree_chain_base
{
void chain(tree t) override;
};
class tree_symbol_mapping final
{
tree m_bind_expression;
tree m_block;
public:
tree_symbol_mapping(tree bind_expression, tree block);
tree bind_expression();
tree block();
};
}
}