Set variable declaration context
This commit is contained in:
parent
a7b0c53d23
commit
98c13f0be3
@ -1,5 +1,4 @@
|
|||||||
#include "elna/gcc/elna-generic.h"
|
#include "elna/gcc/elna-generic.h"
|
||||||
#include "elna/gcc/elna-tree.h"
|
|
||||||
#include "elna/gcc/elna-diagnostic.h"
|
#include "elna/gcc/elna-diagnostic.h"
|
||||||
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
@ -93,18 +92,16 @@ namespace gcc
|
|||||||
build_int_cst_type(integer_type_node, 0));
|
build_int_cst_type(integer_type_node, 0));
|
||||||
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
|
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
|
||||||
|
|
||||||
this->current_statements = alloc_stmt_list();
|
enter_scope();
|
||||||
|
|
||||||
empty_visitor::visit(program);
|
empty_visitor::visit(program);
|
||||||
|
|
||||||
append_to_statement_list(return_stmt, &this->current_statements);
|
append_to_statement_list(return_stmt, &this->current_statements);
|
||||||
|
|
||||||
tree new_block = build_block(NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
|
tree_symbol_mapping mapping = leave_scope();
|
||||||
tree bind_expr = build3(BIND_EXPR, void_type_node, NULL_TREE, this->current_statements, new_block);
|
|
||||||
|
|
||||||
BLOCK_SUPERCONTEXT(new_block) = this->main_fndecl;
|
BLOCK_SUPERCONTEXT(mapping.block()) = this->main_fndecl;
|
||||||
DECL_INITIAL(this->main_fndecl) = new_block;
|
DECL_INITIAL(this->main_fndecl) = mapping.block();
|
||||||
DECL_SAVED_TREE(this->main_fndecl) = bind_expr;
|
DECL_SAVED_TREE(this->main_fndecl) = mapping.bind_expression();
|
||||||
|
|
||||||
DECL_EXTERNAL(this->main_fndecl) = 0;
|
DECL_EXTERNAL(this->main_fndecl) = 0;
|
||||||
DECL_PRESERVE_P(this->main_fndecl) = 1;
|
DECL_PRESERVE_P(this->main_fndecl) = 1;
|
||||||
@ -114,6 +111,22 @@ namespace gcc
|
|||||||
cgraph_node::finalize_function(this->main_fndecl, true);
|
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)
|
void generic_visitor::visit(source::number_literal<std::int32_t> *literal)
|
||||||
{
|
{
|
||||||
this->current_expression = build_int_cst_type(integer_type_node, literal->number());
|
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);
|
get_identifier(declaration->identifier().c_str()), declaration_type);
|
||||||
auto result = this->symbol_map.insert({ declaration->identifier(), declaration_tree });
|
auto result = this->symbol_map.insert({ declaration->identifier(), declaration_tree });
|
||||||
|
|
||||||
// DECL_CONTEXT(declaration_tree) = this->main_fndecl;
|
|
||||||
if (result.second)
|
if (result.second)
|
||||||
{
|
{
|
||||||
|
DECL_CONTEXT(declaration_tree) = this->main_fndecl;
|
||||||
|
variable_chain.append(declaration_tree);
|
||||||
|
|
||||||
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
|
auto declaration_statement = build1_loc(declaration_location, DECL_EXPR,
|
||||||
void_type_node, declaration_tree);
|
void_type_node, declaration_tree);
|
||||||
append_to_statement_list(declaration_statement, &this->current_statements);
|
append_to_statement_list(declaration_statement, &this->current_statements);
|
||||||
|
@ -22,5 +22,45 @@ namespace gcc
|
|||||||
return TREE_CODE(type) == POINTER_TYPE
|
return TREE_CODE(type) == POINTER_TYPE
|
||||||
&& TYPE_MAIN_VARIANT(TREE_TYPE(type)) == char_type_node;
|
&& 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "elna/source/ast.h"
|
#include "elna/source/ast.h"
|
||||||
|
#include "elna/gcc/elna-tree.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
@ -21,9 +22,13 @@ namespace gcc
|
|||||||
tree current_expression{ NULL_TREE };
|
tree current_expression{ NULL_TREE };
|
||||||
std::unordered_map<std::string, tree> symbol_map;
|
std::unordered_map<std::string, tree> symbol_map;
|
||||||
tree main_fndecl{ NULL_TREE };
|
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:
|
public:
|
||||||
void visit(source::program *program) override;
|
void visit(source::program *program) override;
|
||||||
void visit(source::call_statement *statement) override;
|
void visit(source::call_statement *statement) override;
|
||||||
|
@ -23,5 +23,36 @@ namespace gcc
|
|||||||
{
|
{
|
||||||
void init_ttree();
|
void init_ttree();
|
||||||
bool is_string_type(tree type);
|
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();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user