From 128a564be05afb1cb2ec76884a81c2bd536899fd Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 3 Oct 2026 00:46:51 +0200 Subject: Replace noreturn type with an attribute --- boot/name_analysis.cc | 76 ++++++++++++--------------------------------------- 1 file changed, 18 insertions(+), 58 deletions(-) (limited to 'boot/name_analysis.cc') diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 20f08ee..1a87927 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -90,6 +90,8 @@ namespace elna::boot return "Attribute '" + this->name + "' takes no arguments"; case missing_parameter: return "Attribute '" + this->name + "' requires at least one parameter"; + case return_type: + return "Attribute '" + this->name + "' cannot be used with a return type"; default: __builtin_unreachable(); } @@ -317,53 +319,6 @@ namespace elna::boot { } - procedure_type::return_t resolving_visitor::build_return_type( - const procedure_type_expression::return_t& return_type) - { - if (return_type.no_return) - { - return procedure_type::return_t(std::monostate{}); - } - else if (return_type.proper_type != nullptr) - { - return procedure_type::return_t(resolve_type(*return_type.proper_type)); - } - else - { - return procedure_type::return_t(); - } - } - - std::pair> resolving_visitor::build_procedure( - procedure_type_expression& expression, const bool variadic_supported) - { - const procedure_type::return_t result_return = build_return_type(expression.return_type); - std::pair> result_type{ - procedure_type(result_return), std::vector() - }; - for (const auto& [parameter_names, parameters_type] : expression.parameters) - { - const type parameter_type = resolve_type(*parameters_type); - - for (const auto& parameter_name : parameter_names) - { - evaluate_attributes<>(parameter_name.attributes); - result_type.first.parameters.push_back(parameter_type); - result_type.second.push_back(parameter_name.name()); - } - } - result_type.first.variadic = variadic_supported - ? evaluate_attributes(expression.attributes).variadic - : evaluate_attributes<>(expression.attributes).variadic; - - if (result_type.first.variadic && result_type.first.parameters.empty()) - { - add_error(expression.position(), "varargs", - attribute_error::kind::missing_parameter); - } - return result_type; - } - std::optional resolving_visitor::parse_attribute(const std::string& name) { if (name == "aligned") @@ -374,6 +329,10 @@ namespace elna::boot { return attribute_kind::varargs; } + if (name == "noreturn") + { + return attribute_kind::noreturn; + } return std::nullopt; } @@ -676,16 +635,15 @@ namespace elna::boot ordered_map field_names; collect_field_names(result_type->base, field_names); result_type->fields = build_composite_type(expression->fields, field_names, type(result_type)); - result_type->alignment = - evaluate_attributes(expression->attributes).alignment; + result_type->alignment = evaluate_attributes(expression->attributes).alignment; this->current_type = type(result_type); } void resolving_visitor::visit(procedure_type_expression *expression) { - std::shared_ptr const result_type = - std::make_shared(std::move(build_procedure(*expression, true).first)); + const std::shared_ptr result_type = + std::make_shared(build_procedure(*expression).heading); this->current_type = type(result_type); } @@ -851,7 +809,7 @@ namespace elna::boot call->callable().accept(this); if (const auto procedure = call->callable().type_decoration.get()) { - call->type_decoration = procedure->return_type.proper_type; + call->type_decoration = procedure->return_type; } visit_all(this, call->arguments); this->current_type = type(); @@ -1290,10 +1248,10 @@ namespace elna::boot return false; } } - if (!link->return_type.proper_type.empty()) + if (!link->return_type.empty()) { alias_path.resize(saved_path); - return find_alias_cycle(being_resolved, link->return_type.proper_type, alias_path, state); + return find_alias_cycle(being_resolved, link->return_type, alias_path, state); } return true; } @@ -1328,8 +1286,7 @@ namespace elna::boot if (unit->entry_point.has_value()) { const type word8_primitive = lookup_primitive_type("Word8"); - const procedure_type::return_t result_return = procedure_type::return_t(word8_primitive); - auto heading = procedure_type(result_return); + auto heading = procedure_type(word8_primitive); std::shared_ptr info; if (unit->parameters.size() > 1) @@ -1451,8 +1408,9 @@ namespace elna::boot // is why the body sees them too. const std::shared_ptr scope = this->bag.enter(); const std::vector type_parameters = enter_parameters(declaration->parameters); - auto [heading, parameter_names] = - build_procedure(declaration->heading(), !declaration->body.has_value()); + auto [heading, parameter_names, noreturn] = !declaration->body.has_value() + ? build_procedure(declaration->heading()) + : build_procedure(declaration->heading()); std::shared_ptr info_object; if (declaration->body.has_value()) @@ -1480,6 +1438,8 @@ namespace elna::boot info_object->exported = declaration->identifier.exported(); info_object->position.emplace(declaration->position()); info_object->file = this->module_file; + info_object->noreturn = noreturn; + if (!this->bag.enter(declaration->identifier.name(), info_object)) { const std::shared_ptr original = this->bag.lookup(declaration->identifier.name()); -- cgit v1.2.3