From 72f5e82196d95008ed12c12de6bdccf24361e106 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 7 Sep 2026 22:02:15 +0200 Subject: Make module entry point more procedure like --- gcc/gcc/elna-builtins.cc | 5 ++-- gcc/gcc/elna-generic.cc | 73 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 22 deletions(-) (limited to 'gcc') diff --git a/gcc/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc index 23315e5..637e37a 100644 --- a/gcc/gcc/elna-builtins.cc +++ b/gcc/gcc/elna-builtins.cc @@ -335,8 +335,9 @@ namespace elna::gcc function_args_iter_next(¶meter_type); } DECL_ARGUMENTS(fndecl) = argument_chain; - // Elna has no exceptions. - TREE_NOTHROW(fndecl) = 1; + // Elna has no exceptions, but an extern procedure is defined elsewhere + // and may well be able to unwind. + TREE_NOTHROW(fndecl) = static_cast(!info.is_extern()); DECL_EXTERNAL(fndecl) = static_cast(info.is_extern()); // An extern procedure has C linkage whether or not Elna re-exports the name. TREE_PUBLIC(fndecl) = static_cast(info.exported || info.is_extern()); diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index b527280..9bb1e89 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -259,38 +259,71 @@ namespace elna::gcc } if (unit->entry_point.has_value()) { - tree declaration_type = build_function_type_list(elna_int_type_node, - elna_int_type_node, - build_pointer_type(build_pointer_type(unsigned_intQI_type_node)), - NULL_TREE); - tree fndecl = build_fn_decl("main", declaration_type); - - tree resdecl = build_decl(UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, integer_type_node); + const std::shared_ptr entry_point = this->bag.lookup("")->is_procedure(); + const location_t location = get_location(&entry_point->position.value()); + tree declaration_type = unit->parameters.empty() + ? build_function_type_list(integer_type_node, NULL_TREE) + : build_function_type_list(integer_type_node, + integer_type_node, + build_pointer_type(build_pointer_type(char_type_node)), + NULL_TREE); + // build_fn_decl would mark the declaration artificial, which drops the + // source coordinates from the debug information. + tree fndecl = build_decl(location, FUNCTION_DECL, get_identifier("main"), declaration_type); + TREE_PUBLIC(fndecl) = 1; + // Elna has no exceptions. + TREE_NOTHROW(fndecl) = 1; + + tree resdecl = build_decl(location, RESULT_DECL, NULL_TREE, integer_type_node); DECL_CONTEXT(resdecl) = fndecl; DECL_RESULT(fndecl) = resdecl; begin_function(fndecl); + this->bag.enter(entry_point->scope); - tree parameter_type = TYPE_ARG_TYPES(declaration_type); - for (const char *argument_name : std::array{ "count", "parameters" }) + if (!unit->parameters.empty()) { - tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL, - get_identifier(argument_name), TREE_VALUE(parameter_type)); - DECL_CONTEXT(declaration_tree) = fndecl; - DECL_ARG_TYPE(declaration_tree) = TREE_VALUE(parameter_type); - - this->symbols->enter(argument_name, declaration_tree); - DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree); - parameter_type = TREE_CHAIN(parameter_type); + constexpr std::array argument_names{ "$argc", "$argv" }; + std::array argument_declarations{}; + tree parameter_type = TYPE_ARG_TYPES(declaration_type); + + for (std::size_t i = 0; i < argument_names.size(); ++i) + { + tree declaration_tree = build_decl(UNKNOWN_LOCATION, PARM_DECL, + get_identifier(argument_names.at(i)), TREE_VALUE(parameter_type)); + DECL_CONTEXT(declaration_tree) = fndecl; + DECL_ARG_TYPE(declaration_tree) = TREE_VALUE(parameter_type); + DECL_ARTIFICIAL(declaration_tree) = 1; + + DECL_ARGUMENTS(fndecl) = chainon(DECL_ARGUMENTS(fndecl), declaration_tree); + argument_declarations.at(i) = declaration_tree; + parameter_type = TREE_CHAIN(parameter_type); + } + const boot::type& argument_type = entry_point->symbol.parameters.front(); + tree slice_type = get_inner_alias(argument_type, this->symbols); + tree ptr_field = TYPE_FIELDS(slice_type); + tree length_field = TREE_CHAIN(ptr_field); + tree slice_pointer = fold_convert(TREE_TYPE(ptr_field), argument_declarations.at(1)); + tree slice_length = fold_convert(TREE_TYPE(length_field), argument_declarations.at(0)); + tree slice = build_slice(slice_type, slice_pointer, slice_length); + const boot::variable_info argument_info(argument_type, false); + + declare_local_variable(unit->parameters.front(), argument_info, slice); + } + for (boot::variable_declaration *const variable : unit->entry_point->variables) + { + variable->accept(this); } visit_statements(unit->entry_point->statements); - tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl), - integer_zero_node); + + unit->entry_point->return_expression->accept(this); + tree return_value = fold_convert(integer_type_node, this->current_expression); + tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(fndecl), return_value); tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result); append_statement(return_stmt); this->current_expression = NULL_TREE; - DECL_EXTERNAL(fndecl) = 0; + this->bag.leave(); finish_function(fndecl); } } -- cgit v1.2.3