diff --git a/src/parser/cxx/symbols.cc b/src/parser/cxx/symbols.cc index bb49ef21..f02c264e 100644 --- a/src/parser/cxx/symbols.cc +++ b/src/parser/cxx/symbols.cc @@ -522,14 +522,6 @@ FunctionSymbol::FunctionSymbol(ScopeSymbol* enclosingScope) FunctionSymbol::~FunctionSymbol() {} -auto FunctionSymbol::declaration() const -> DeclarationAST* { - return declaration_; -} - -void FunctionSymbol::setDeclaration(DeclarationAST* declaration) { - declaration_ = declaration; -} - auto FunctionSymbol::isDefined() const -> bool { return isDefined_; } void FunctionSymbol::setDefined(bool isDefined) { isDefined_ = isDefined; } @@ -679,38 +671,6 @@ TypeAliasSymbol::TypeAliasSymbol(ScopeSymbol* enclosingScope) TypeAliasSymbol::~TypeAliasSymbol() {} -auto TypeAliasSymbol::templateDeclaration() const -> TemplateDeclarationAST* { - return templateDeclaration_; -} - -void TypeAliasSymbol::setTemplateDeclaration( - TemplateDeclarationAST* declaration) { - templateDeclaration_ = declaration; -} - -auto TypeAliasSymbol::specializations() const - -> std::span { - if (!templateInfo_) return {}; - return templateInfo_->specializations(); -} - -auto TypeAliasSymbol::findSpecialization( - const std::vector& arguments) const -> TypeAliasSymbol* { - if (!templateInfo_) return {}; - return symbol_cast( - templateInfo_->findSpecialization(arguments)); -} - -void TypeAliasSymbol::addSpecialization(std::vector arguments, - TypeAliasSymbol* specialization) { - if (!templateInfo_) { - templateInfo_ = std::make_unique(this); - } - auto index = templateInfo_->specializations().size(); - specialization->setSpecializationInfo(this, index); - templateInfo_->addSpecialization(std::move(arguments), specialization); -} - VariableSymbol::VariableSymbol(ScopeSymbol* enclosingScope) : Symbol(Kind, enclosingScope) {} @@ -746,38 +706,6 @@ auto VariableSymbol::isInline() const -> bool { return isInline_; } void VariableSymbol::setInline(bool isInline) { isInline_ = isInline; } -auto VariableSymbol::templateDeclaration() const -> TemplateDeclarationAST* { - return templateDeclaration_; -} - -void VariableSymbol::setTemplateDeclaration( - TemplateDeclarationAST* declaration) { - templateDeclaration_ = declaration; -} - -auto VariableSymbol::specializations() const - -> std::span { - if (!templateInfo_) return {}; - return templateInfo_->specializations(); -} - -auto VariableSymbol::findSpecialization( - const std::vector& arguments) const -> VariableSymbol* { - if (!templateInfo_) return {}; - return symbol_cast( - templateInfo_->findSpecialization(arguments)); -} - -void VariableSymbol::addSpecialization(std::vector arguments, - VariableSymbol* specialization) { - if (!templateInfo_) { - templateInfo_ = std::make_unique(this); - } - auto index = templateInfo_->specializations().size(); - specialization->setSpecializationInfo(this, index); - templateInfo_->addSpecialization(std::move(arguments), specialization); -} - auto VariableSymbol::initializer() const -> ExpressionAST* { return initializer_; } diff --git a/src/parser/cxx/symbols.h b/src/parser/cxx/symbols.h index bea935be..93a752bb 100644 --- a/src/parser/cxx/symbols.h +++ b/src/parser/cxx/symbols.h @@ -52,19 +52,26 @@ class TemplateSpecialization { const std::vector& args2) -> bool; -class TemplateInfo { - public: - explicit TemplateInfo(Symbol* templateSymbol) - : templateSymbol_(templateSymbol) {} +template +class MaybeTemplate { + struct Template { + std::vector specializations_; + D* declaration_ = nullptr; + TemplateDeclarationAST* templateDeclaration_ = nullptr; + }; - [[nodiscard]] auto specializations() const - -> std::span { - return specializations_; - } + struct TemplateSpecializationRef { + S* primaryTemplateSymbol_ = nullptr; + int templateSepcializationIndex_ = 0; + }; + // todo: using std::variant + struct TemplateData : Template, TemplateSpecializationRef {}; + + public: [[nodiscard]] auto findSpecialization( const std::vector& arguments) const -> Symbol* { - for (const auto& specialization : specializations_) { + for (const auto& specialization : specializations()) { const std::vector& args = specialization.arguments; if (args == arguments) return specialization.symbol; if (args.size() != arguments.size()) continue; @@ -76,15 +83,84 @@ class TemplateInfo { return nullptr; } + [[nodiscard]] auto templateDeclaration() const -> TemplateDeclarationAST* { + if (!template_) return nullptr; + return template_->templateDeclaration_; + } + + void setTemplateDeclaration(TemplateDeclarationAST* templateDeclaration) { + ensure_template(); + template_->templateDeclaration_ = templateDeclaration; + } + + [[nodiscard]] auto isSpecialization() const -> bool { + if (!template_) return false; + return template_->primaryTemplateSymbol_ != nullptr; + } + void addSpecialization(std::vector arguments, - Symbol* specialization) { - specializations_.push_back( - {templateSymbol_, std::move(arguments), specialization}); + S* specialization) { + ensure_template(); + + auto index = int(template_->specializations_.size()); + + specialization->setSpecializationInfo(static_cast(this), index); + + template_->specializations_.push_back({template_->primaryTemplateSymbol_, + std::move(arguments), + specialization}); + } + + [[nodiscard]] auto declaration() const -> D* { + if (!template_) return nullptr; + return template_->declaration_; + } + + void setDeclaration(D* ast) { + ensure_template(); + template_->declaration_ = ast; + } + + [[nodiscard]] auto specializations() const + -> std::span { + if (!template_) return {}; + return template_->specializations_; + } + + [[nodiscard]] auto templateArguments() const + -> std::span { + if (!template_) return {}; + if (!template_->primaryTemplateSymbol_) return {}; + + return template_->primaryTemplateSymbol_ + ->specializations()[template_->templateSepcializationIndex_] + .arguments; + } + + [[nodiscard]] auto primaryTemplateSymbol() const -> S* { + if (!template_) return nullptr; + return template_->primaryTemplateSymbol_; } private: - Symbol* templateSymbol_ = nullptr; - std::vector specializations_; + void setSpecializationInfo(S* primaryTemplateSymbol, std::size_t index) { + ensure_template(); + template_->primaryTemplateSymbol_ = primaryTemplateSymbol; + template_->templateSepcializationIndex_ = index; + } + + [[nodiscard]] auto templateSepcializationIndex() const -> std::size_t { + if (!template_) return 0; + return template_->templateSepcializationIndex_; + } + + private: + void ensure_template() { + if (template_) return; + template_ = std::make_unique(); + } + + std::unique_ptr template_; }; class Symbol { @@ -263,16 +339,8 @@ class BaseClassSymbol final : public Symbol { bool isVirtual_ = false; }; -class Template { - public: - std::unique_ptr templateInfo_; - SpecifierAST* declaration_ = nullptr; - TemplateDeclarationAST* templateDeclaration_ = nullptr; - ClassSymbol* templateClass_ = nullptr; - int templateSepcializationIndex_ = 0; -}; - -class ClassSymbol final : public ScopeSymbol { +class ClassSymbol final : public ScopeSymbol, + public MaybeTemplate { public: constexpr static auto Kind = SymbolKind::kClass; @@ -314,95 +382,9 @@ class ClassSymbol final : public ScopeSymbol { [[nodiscard]] auto flags() const -> std::uint32_t; void setFlags(std::uint32_t flags); - [[nodiscard]] auto declaration() const -> SpecifierAST* { - if (!template_) return nullptr; - return template_->declaration_; - } - - void setDeclaration(SpecifierAST* ast) { - ensure_template(); - template_->declaration_ = ast; - } - - [[nodiscard]] auto templateDeclaration() const -> TemplateDeclarationAST* { - if (!template_) return nullptr; - return template_->templateDeclaration_; - } - - void setTemplateDeclaration(TemplateDeclarationAST* templateDeclaration) { - ensure_template(); - template_->templateDeclaration_ = templateDeclaration; - } - - [[nodiscard]] auto specializations() const - -> std::span { - if (!template_) return {}; - if (!template_->templateInfo_) return {}; - return template_->templateInfo_->specializations(); - } - - [[nodiscard]] auto findSpecialization( - const std::vector& arguments) const -> Symbol* { - if (!template_) return {}; - if (!template_->templateInfo_) return {}; - return template_->templateInfo_->findSpecialization(arguments); - } - - void addSpecialization(std::vector arguments, - ClassSymbol* specialization) { - ensure_template(); - - if (!template_->templateInfo_) { - template_->templateInfo_ = std::make_unique(this); - } - - auto index = int(template_->templateInfo_->specializations().size()); - - specialization->setSpecializationInfo(this, index); - - template_->templateInfo_->addSpecialization(std::move(arguments), - specialization); - } - - [[nodiscard]] auto isSpecialization() const -> bool { - if (!template_) return false; - return template_->templateClass_ != nullptr; - } - - [[nodiscard]] auto templateArguments() const - -> std::span { - if (!template_) return {}; - if (!template_->templateClass_) return {}; - - return template_->templateClass_ - ->specializations()[template_->templateSepcializationIndex_] - .arguments; - } - - void setSpecializationInfo(ClassSymbol* templateClass, std::size_t index) { - ensure_template(); - template_->templateClass_ = templateClass; - template_->templateSepcializationIndex_ = index; - } - - [[nodiscard]] auto templateClass() const -> ClassSymbol* { - if (!template_) return nullptr; - return template_->templateClass_; - } - - [[nodiscard]] auto templateSepcializationIndex() const -> std::size_t { - if (!template_) return 0; - return template_->templateSepcializationIndex_; - } - [[nodiscard]] auto buildClassLayout(Control* control) -> std::expected; - void ensure_template() { - if (template_) return; - template_ = std::make_unique