Implement argument passing

This commit is contained in:
2025-01-15 01:48:09 +01:00
parent 5cb0e18a87
commit 1e45d66359
7 changed files with 106 additions and 92 deletions

View File

@ -87,10 +87,17 @@ namespace gcc
}
else if (symbol)
{
tree fndecl_type = build_function_type_list(integer_type_node, NULL_TREE);
tree fndecl_type = build_function_type(void_type_node, TYPE_ARG_TYPES(symbol->payload));
tree printf_fn = build1(ADDR_EXPR, build_pointer_type(fndecl_type), symbol->payload);
tree stmt = build_call_nary(integer_type_node, printf_fn, 0);
std::vector<tree> arguments(statement->arguments().size());
for (std::size_t i = 0; i < statement->arguments().size(); ++i)
{
statement->arguments().at(i)->accept(this);
arguments[i] = this->current_expression;
}
tree stmt = build_call_array_loc(get_location(&statement->position()),
void_type_node, printf_fn, arguments.size(), arguments.data());
append_to_statement_list(stmt, &this->current_statements);
this->current_expression = NULL_TREE;
@ -122,7 +129,7 @@ namespace gcc
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(main_fndecl),
build_int_cst_type(integer_type_node, 0));
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
enter_scope();
for (const auto& definition : program->value_definitions)
@ -133,29 +140,29 @@ namespace gcc
append_to_statement_list(return_stmt, &this->current_statements);
tree_symbol_mapping mapping = leave_scope();
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;
gimplify_function_tree(this->main_fndecl);
cgraph_node::finalize_function(this->main_fndecl, true);
}
void generic_visitor::visit(source::procedure_definition *definition)
{
tree *parameter_types = reinterpret_cast<tree *>(xmalloc(definition->parameters().size() * sizeof(tree)));
std::vector<tree> parameter_types(definition->parameters().size());
for (std::size_t i = 0; i < definition->parameters().size(); ++i)
{
parameter_types[i] = build_type(definition->parameters().at(i)->type());
}
tree declaration_type = build_function_type_array(void_type_node,
definition->parameters().size(), parameter_types);
definition->parameters().size(), parameter_types.data());
this->main_fndecl = build_fn_decl(definition->identifier().c_str(), declaration_type);
this->symbol_map->enter(definition->identifier(), source::make_info(this->main_fndecl));
@ -166,6 +173,21 @@ namespace gcc
DECL_RESULT(this->main_fndecl) = resdecl;
enter_scope();
gcc::tree_chain argument_chain;
for (std::size_t i = 0; i < definition->parameters().size(); ++i)
{
auto parameter = definition->parameters().at(i);
tree declaration_tree = build_decl(get_location(&parameter->position()), PARM_DECL,
get_identifier(parameter->identifier().c_str()), parameter_types[i]);
DECL_CONTEXT(declaration_tree) = this->main_fndecl;
DECL_ARG_TYPE(declaration_tree) = parameter_types[i];
this->symbol_map->enter(parameter->identifier(), source::make_info(declaration_tree));
argument_chain.append(declaration_tree);
}
DECL_ARGUMENTS(this->main_fndecl) = argument_chain.head();
definition->body().accept(this);
tree_symbol_mapping mapping = leave_scope();
@ -180,8 +202,6 @@ namespace gcc
gimplify_function_tree(this->main_fndecl);
cgraph_node::finalize_function(this->main_fndecl, true);
free(parameter_types);
}
void generic_visitor::enter_scope()
@ -227,9 +247,9 @@ namespace gcc
this->current_expression = build_int_cst_type(boolean_type_node, boolean->number());
}
void generic_visitor::visit(source::char_literal *character)
void generic_visitor::visit(source::number_literal<unsigned char> *character)
{
this->current_expression = build_int_cstu(elna_char_type_node, character->character());
this->current_expression = build_int_cstu(elna_char_type_node, character->number());
}
void generic_visitor::visit(source::string_literal *string)
@ -385,15 +405,15 @@ namespace gcc
void generic_visitor::visit(source::constant_definition *definition)
{
location_t definition_location = get_location(&definition->position());
definition->body().accept(this);
tree definition_tree = build_decl(definition_location, CONST_DECL,
get_identifier(definition->identifier().c_str()), integer_type_node);
get_identifier(definition->identifier().c_str()), TREE_TYPE(this->current_expression));
auto result = this->symbol_map->enter(definition->identifier(), source::make_info(definition_tree));
if (result)
{
definition->body().accept(this);
DECL_INITIAL(definition_tree) = build_int_cst_type(integer_type_node, definition->body().number());
DECL_INITIAL(definition_tree) = this->current_expression;
TREE_CONSTANT(definition_tree) = 1;
TREE_READONLY(definition_tree) = 1;