From e676e74efbbbf62887b9442326399eebccc4d108 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 17 Jul 2026 16:16:23 +0200 Subject: Handle base type constness --- boot/symbol.cc | 289 +++++++++++++-------------------------------------------- 1 file changed, 65 insertions(+), 224 deletions(-) (limited to 'boot/symbol.cc') diff --git a/boot/symbol.cc b/boot/symbol.cc index bd6ec49..6ad89b7 100644 --- a/boot/symbol.cc +++ b/boot/symbol.cc @@ -19,224 +19,72 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - type::type() - { - } - type::type(std::shared_ptr alias) - : tag(type_tag::alias), alias(alias) + : payload(alias) { } type::type(std::shared_ptr primitive) - : tag(type_tag::primitive), primitive(primitive) + : payload(primitive) { } type::type(std::shared_ptr record) - : tag(type_tag::record), record(record) + : payload(record) { } type::type(std::shared_ptr pointer) - : tag(type_tag::pointer), pointer(pointer) + : payload(pointer) { } type::type(std::shared_ptr constant) - : tag(type_tag::constant), constant(constant) + : payload(constant) { } type::type(std::shared_ptr array) - : tag(type_tag::array), array(array) + : payload(array) { } type::type(std::shared_ptr procedure) - : tag(type_tag::procedure), procedure(procedure) + : payload(procedure) { } type::type(std::shared_ptr enumeration) - : tag(type_tag::enumeration), enumeration(enumeration) + : payload(enumeration) { } - void type::copy(const type& other) + template + std::shared_ptr type::get() const { - switch (other.tag) + if constexpr (std::is_same_v) { - case type_tag::empty: - break; - case type_tag::alias: - new (&alias) std::weak_ptr(other.alias); - break; - case type_tag::primitive: - new (&primitive) std::shared_ptr(other.primitive); - break; - case type_tag::record: - new (&record) std::shared_ptr(other.record); - break; - case type_tag::pointer: - new (&pointer) std::shared_ptr(other.pointer); - break; - case type_tag::constant: - new (&constant) std::shared_ptr(other.constant); - break; - case type_tag::array: - new (&array) std::shared_ptr(other.array); - break; - case type_tag::procedure: - new (&procedure) std::shared_ptr(other.procedure); - break; - case type_tag::enumeration: - new (&enumeration) std::shared_ptr(other.enumeration); - break; + if (auto *wp = std::get_if>(&payload)) + return wp->lock(); + return nullptr; } - } - - type::type(const type& other) - : tag(other.tag) - { - copy(other); - } - - void type::move(type&& other) - { - switch (other.tag) - { - case type_tag::empty: - break; - case type_tag::alias: - new (&alias) std::weak_ptr(std::move(other.alias)); - break; - case type_tag::primitive: - new (&primitive) std::shared_ptr(std::move(other.primitive)); - break; - case type_tag::record: - new (&record) std::shared_ptr(std::move(other.record)); - break; - case type_tag::pointer: - new (&pointer) std::shared_ptr(std::move(other.pointer)); - break; - case type_tag::constant: - new (&constant) std::shared_ptr(std::move(other.constant)); - break; - case type_tag::array: - new (&array) std::shared_ptr(std::move(other.array)); - break; - case type_tag::procedure: - new (&procedure) std::shared_ptr(std::move(other.procedure)); - break; - case type_tag::enumeration: - new (&enumeration) std::shared_ptr(std::move(other.enumeration)); - break; - } - } - - type& type::operator=(const type& other) - { - this->~type(); - this->tag = other.tag; - copy(other); - return *this; - } - - type::type(type&& other) - : tag(other.tag) - { - move(std::move(other)); - } - - type& type::operator=(type&& other) - { - this->~type(); - this->tag = other.tag; - move(std::move(other)); - return *this; - } - - type::~type() - { - switch (tag) + else { - case type_tag::empty: - break; - case type_tag::alias: - this->alias.~weak_ptr(); - break; - case type_tag::primitive: - this->primitive.~shared_ptr(); - break; - case type_tag::record: - this->record.~shared_ptr(); - break; - case type_tag::pointer: - this->pointer.~shared_ptr(); - break; - case type_tag::constant: - this->constant.~shared_ptr(); - break; - case type_tag::array: - this->array.~shared_ptr(); - break; - case type_tag::procedure: - this->procedure.~shared_ptr(); - break; - case type_tag::enumeration: - this->enumeration.~shared_ptr(); - break; + if (auto *sp = std::get_if>(&payload)) + return *sp; + return nullptr; } } - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::alias ? this->alias.lock() : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::primitive ? this->primitive : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::record ? this->record : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::pointer ? this->pointer : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::array ? this->array : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::constant ? this->constant : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::procedure ? this->procedure : nullptr; - } - - template<> - std::shared_ptr type::get() const - { - return tag == type_tag::enumeration ? this->enumeration : nullptr; - } + // Explicit instantiation for all types used by callers. + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; + template std::shared_ptr type::get() const; bool type::operator==(const std::nullptr_t&) const { @@ -293,61 +141,54 @@ namespace elna::boot bool type::empty() const { - return tag == type_tag::empty; + return std::holds_alternative(payload); } std::string type::to_string() const { - switch (tag) - { - case type_tag::empty: + return std::visit([](const auto& p) -> std::string { + using T = std::decay_t; + if constexpr (std::is_same_v) return ""; - case type_tag::alias: - return alias.lock()->name; - case type_tag::primitive: - return primitive->identifier; - case type_tag::pointer: - return "^" + pointer->base.to_string(); - case type_tag::constant: - return "const " + constant->unqualified.to_string(); - case type_tag::array: - return "[" + std::to_string(array->size) + "]" + array->base.to_string(); - case type_tag::record: - if (record->base.empty()) - { + else if constexpr (std::is_same_v>) + return p.lock()->name; + else if constexpr (std::is_same_v>) + return p->identifier; + else if constexpr (std::is_same_v>) + return "^" + p->base.to_string(); + else if constexpr (std::is_same_v>) + return "const " + p->unqualified.to_string(); + else if constexpr (std::is_same_v>) + return "[" + std::to_string(p->size) + "]" + p->base.to_string(); + else if constexpr (std::is_same_v>) + { + if (p->base.empty()) return "record ... end"; - } else + return "record(" + p->base.to_string() + ") ... end"; + } + else if constexpr (std::is_same_v>) + { + std::string result = "proc("; + for (std::size_t i = 0; i < p->parameters.size(); ++i) { - return "record(" + record->base.to_string() + ") ... end"; - } - case type_tag::procedure: - { - std::string result = "proc("; - for (std::size_t i = 0; i < procedure->parameters.size(); ++i) - { - if (i > 0) result += ", "; - result += procedure->parameters[i].to_string(); - } - result += ")"; - if (procedure->return_type.no_return) - { - result += ": !"; - } - else if (!procedure->return_type.proper_type.empty()) - { - result += ": " + procedure->return_type.proper_type.to_string(); - } - return result; + if (i > 0) result += ", "; + result += p->parameters[i].to_string(); } - case type_tag::enumeration: + result += ")"; + if (p->return_type.no_return) + result += ": !"; + else if (!p->return_type.proper_type.empty()) + result += ": " + p->return_type.proper_type.to_string(); + return result; + } + else if constexpr (std::is_same_v>) return "(enumeration)"; - } - __builtin_unreachable(); + }, payload); } alias_type::alias_type(const std::string& name) - : name(name), reference() + : name(name), referent() { } @@ -517,7 +358,7 @@ namespace elna::boot { auto unresolved_declaration = this->unresolved.at(symbol_name); - unresolved_declaration->reference = resolution; + unresolved_declaration->referent = resolution; return unresolved_declaration; } @@ -544,7 +385,7 @@ namespace elna::boot type resolve_underlying_type(std::shared_ptr alias) { - return resolve_underlying_type(alias->reference); + return resolve_underlying_type(alias->referent); } type resolve_underlying_type(const type& alias) @@ -565,7 +406,7 @@ namespace elna::boot { if (auto alias = checked.get()) { - return resolve_aliases(alias->reference); + return resolve_aliases(alias->referent); } return checked; } -- cgit v1.2.3