Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 36 additions & 31 deletions src/parser/cxx/binder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,11 @@ void Binder::bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs) {
unit_, primaryTemplateSymbol->templateDeclaration(),
templateId->templateArgumentList);

specialization =
primaryTemplateSymbol
? primaryTemplateSymbol->findSpecialization(templateArguments)
: nullptr;
specialization = primaryTemplateSymbol
? symbol_cast<ClassSymbol>(
primaryTemplateSymbol->findSpecialization(
templateArguments))
: nullptr;

if (specialization) {
error(location, std::format("redefinition of specialization '{}'",
Expand Down Expand Up @@ -518,52 +519,56 @@ void Binder::bind(UsingDeclaratorAST* ast, Symbol* target) {
}

void Binder::bind(BaseSpecifierAST* ast) {
const auto checkTemplates = unit_->config().checkTypes;

Symbol* symbol = nullptr;

if (auto decltypeId = ast_cast<DecltypeIdAST>(ast->unqualifiedId)) {
if (auto classType = type_cast<ClassType>(
control()->remove_cv(decltypeId->decltypeSpecifier->type))) {
symbol = classType->symbol();
}
} else {
symbol =
resolve(ast->nestedNameSpecifier, ast->unqualifiedId, checkTemplates);
}

if (auto nameId = ast_cast<NameIdAST>(ast->unqualifiedId)) {
symbol = Lookup{scope_}(ast->nestedNameSpecifier, nameId->identifier);
}

// dealias
if (auto typeAlias = symbol_cast<TypeAliasSymbol>(symbol)) {
if (auto classType =
type_cast<ClassType>(control()->remove_cv(typeAlias->type()))) {
symbol = classType->symbol();
}
}

if (symbol) {
auto location = ast->unqualifiedId->firstSourceLocation();
auto baseClassSymbol = control()->newBaseClassSymbol(scope(), location);
ast->symbol = baseClassSymbol;
if (!symbol || !symbol->isClass()) {
error(ast->unqualifiedId->firstSourceLocation(),
"base class specifier must be a class");
return;
}

auto location = ast->unqualifiedId->firstSourceLocation();
auto baseClassSymbol = control()->newBaseClassSymbol(scope(), location);
ast->symbol = baseClassSymbol;

baseClassSymbol->setVirtual(ast->isVirtual);
baseClassSymbol->setSymbol(symbol);
baseClassSymbol->setVirtual(ast->isVirtual);
baseClassSymbol->setSymbol(symbol);

if (symbol) {
baseClassSymbol->setName(symbol->name());
}
baseClassSymbol->setName(symbol->name());

switch (ast->accessSpecifier) {
case TokenKind::T_PRIVATE:
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPrivate);
break;
case TokenKind::T_PROTECTED:
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kProtected);
break;
case TokenKind::T_PUBLIC:
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPublic);
break;
default:
break;
} // switch
}
switch (ast->accessSpecifier) {
case TokenKind::T_PRIVATE:
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPrivate);
break;
case TokenKind::T_PROTECTED:
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kProtected);
break;
case TokenKind::T_PUBLIC:
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPublic);
break;
default:
break;
} // switch
}

void Binder::bind(NonTypeTemplateParameterAST* ast, int index, int depth) {
Expand Down
3 changes: 1 addition & 2 deletions src/parser/cxx/symbol_printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ struct DumpSymbols {
--depth;
}

template <typename S>
void dumpSpecializations(
std::span<const TemplateSpecialization<S>> specializations) {
std::span<const TemplateSpecialization> specializations) {
if (specializations.empty()) return;
++depth;
indent();
Expand Down
51 changes: 8 additions & 43 deletions src/parser/cxx/symbols.cc
Original file line number Diff line number Diff line change
Expand Up @@ -407,43 +407,6 @@ void ClassSymbol::addConversionFunction(FunctionSymbol* conversionFunction) {
conversionFunctions_.push_back(conversionFunction);
}

auto ClassSymbol::declaration() const -> SpecifierAST* { return specifier_; }

void ClassSymbol::setDeclaration(SpecifierAST* specifier) {
specifier_ = specifier;
}

auto ClassSymbol::templateDeclaration() const -> TemplateDeclarationAST* {
return templateDeclaration_;
}

void ClassSymbol::setTemplateDeclaration(
TemplateDeclarationAST* templateDeclaration) {
templateDeclaration_ = templateDeclaration;
}

auto ClassSymbol::specializations() const
-> std::span<const TemplateSpecialization<ClassSymbol>> {
if (!templateInfo_) return {};
return templateInfo_->specializations();
}

auto ClassSymbol::findSpecialization(
const std::vector<TemplateArgument>& arguments) const -> ClassSymbol* {
if (!templateInfo_) return {};
return templateInfo_->findSpecialization(arguments);
}

void ClassSymbol::addSpecialization(std::vector<TemplateArgument> arguments,
ClassSymbol* specialization) {
if (!templateInfo_) {
templateInfo_ = std::make_unique<TemplateInfo<ClassSymbol>>(this);
}
auto index = templateInfo_->specializations().size();
specialization->setSpecializationInfo(this, index);
templateInfo_->addSpecialization(std::move(arguments), specialization);
}

auto ClassSymbol::buildClassLayout(Control* control)
-> std::expected<bool, std::string> {
int offset = 0;
Expand Down Expand Up @@ -726,21 +689,22 @@ void TypeAliasSymbol::setTemplateDeclaration(
}

auto TypeAliasSymbol::specializations() const
-> std::span<const TemplateSpecialization<TypeAliasSymbol>> {
-> std::span<const TemplateSpecialization> {
if (!templateInfo_) return {};
return templateInfo_->specializations();
}

auto TypeAliasSymbol::findSpecialization(
const std::vector<TemplateArgument>& arguments) const -> TypeAliasSymbol* {
if (!templateInfo_) return {};
return templateInfo_->findSpecialization(arguments);
return symbol_cast<TypeAliasSymbol>(
templateInfo_->findSpecialization(arguments));
}

void TypeAliasSymbol::addSpecialization(std::vector<TemplateArgument> arguments,
TypeAliasSymbol* specialization) {
if (!templateInfo_) {
templateInfo_ = std::make_unique<TemplateInfo<TypeAliasSymbol>>(this);
templateInfo_ = std::make_unique<TemplateInfo>(this);
}
auto index = templateInfo_->specializations().size();
specialization->setSpecializationInfo(this, index);
Expand Down Expand Up @@ -792,21 +756,22 @@ void VariableSymbol::setTemplateDeclaration(
}

auto VariableSymbol::specializations() const
-> std::span<const TemplateSpecialization<VariableSymbol>> {
-> std::span<const TemplateSpecialization> {
if (!templateInfo_) return {};
return templateInfo_->specializations();
}

auto VariableSymbol::findSpecialization(
const std::vector<TemplateArgument>& arguments) const -> VariableSymbol* {
if (!templateInfo_) return {};
return templateInfo_->findSpecialization(arguments);
return symbol_cast<VariableSymbol>(
templateInfo_->findSpecialization(arguments));
}

void VariableSymbol::addSpecialization(std::vector<TemplateArgument> arguments,
VariableSymbol* specialization) {
if (!templateInfo_) {
templateInfo_ = std::make_unique<TemplateInfo<VariableSymbol>>(this);
templateInfo_ = std::make_unique<TemplateInfo>(this);
}
auto index = templateInfo_->specializations().size();
specialization->setSpecializationInfo(this, index);
Expand Down
Loading
Loading