Skip to content

Commit 44e02e9

Browse files
committed
Improve binding of the base class specifiers
1 parent 936ddbd commit 44e02e9

File tree

6 files changed

+220
-114
lines changed

6 files changed

+220
-114
lines changed

src/parser/cxx/binder.cc

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,11 @@ void Binder::bind(ClassSpecifierAST* ast, DeclSpecs& declSpecs) {
272272
unit_, primaryTemplateSymbol->templateDeclaration(),
273273
templateId->templateArgumentList);
274274

275-
specialization =
276-
primaryTemplateSymbol
277-
? primaryTemplateSymbol->findSpecialization(templateArguments)
278-
: nullptr;
275+
specialization = primaryTemplateSymbol
276+
? symbol_cast<ClassSymbol>(
277+
primaryTemplateSymbol->findSpecialization(
278+
templateArguments))
279+
: nullptr;
279280

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

520521
void Binder::bind(BaseSpecifierAST* ast) {
522+
const auto checkTemplates = unit_->config().checkTypes;
523+
521524
Symbol* symbol = nullptr;
522525

523526
if (auto decltypeId = ast_cast<DecltypeIdAST>(ast->unqualifiedId)) {
524527
if (auto classType = type_cast<ClassType>(
525528
control()->remove_cv(decltypeId->decltypeSpecifier->type))) {
526529
symbol = classType->symbol();
527530
}
531+
} else {
532+
symbol =
533+
resolve(ast->nestedNameSpecifier, ast->unqualifiedId, checkTemplates);
528534
}
529535

530-
if (auto nameId = ast_cast<NameIdAST>(ast->unqualifiedId)) {
531-
symbol = Lookup{scope_}(ast->nestedNameSpecifier, nameId->identifier);
532-
}
533-
536+
// dealias
534537
if (auto typeAlias = symbol_cast<TypeAliasSymbol>(symbol)) {
535538
if (auto classType =
536539
type_cast<ClassType>(control()->remove_cv(typeAlias->type()))) {
537540
symbol = classType->symbol();
538541
}
539542
}
540543

541-
if (symbol) {
542-
auto location = ast->unqualifiedId->firstSourceLocation();
543-
auto baseClassSymbol = control()->newBaseClassSymbol(scope(), location);
544-
ast->symbol = baseClassSymbol;
544+
if (!symbol || !symbol->isClass()) {
545+
error(ast->unqualifiedId->firstSourceLocation(),
546+
"base class specifier must be a class");
547+
return;
548+
}
549+
550+
auto location = ast->unqualifiedId->firstSourceLocation();
551+
auto baseClassSymbol = control()->newBaseClassSymbol(scope(), location);
552+
ast->symbol = baseClassSymbol;
545553

546-
baseClassSymbol->setVirtual(ast->isVirtual);
547-
baseClassSymbol->setSymbol(symbol);
554+
baseClassSymbol->setVirtual(ast->isVirtual);
555+
baseClassSymbol->setSymbol(symbol);
548556

549-
if (symbol) {
550-
baseClassSymbol->setName(symbol->name());
551-
}
557+
baseClassSymbol->setName(symbol->name());
552558

553-
switch (ast->accessSpecifier) {
554-
case TokenKind::T_PRIVATE:
555-
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPrivate);
556-
break;
557-
case TokenKind::T_PROTECTED:
558-
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kProtected);
559-
break;
560-
case TokenKind::T_PUBLIC:
561-
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPublic);
562-
break;
563-
default:
564-
break;
565-
} // switch
566-
}
559+
switch (ast->accessSpecifier) {
560+
case TokenKind::T_PRIVATE:
561+
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPrivate);
562+
break;
563+
case TokenKind::T_PROTECTED:
564+
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kProtected);
565+
break;
566+
case TokenKind::T_PUBLIC:
567+
baseClassSymbol->setAccessSpecifier(AccessSpecifier::kPublic);
568+
break;
569+
default:
570+
break;
571+
} // switch
567572
}
568573

569574
void Binder::bind(NonTypeTemplateParameterAST* ast, int index, int depth) {

src/parser/cxx/symbol_printer.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ struct DumpSymbols {
6363
--depth;
6464
}
6565

66-
template <typename S>
6766
void dumpSpecializations(
68-
std::span<const TemplateSpecialization<S>> specializations) {
67+
std::span<const TemplateSpecialization> specializations) {
6968
if (specializations.empty()) return;
7069
++depth;
7170
indent();

src/parser/cxx/symbols.cc

Lines changed: 8 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -407,43 +407,6 @@ void ClassSymbol::addConversionFunction(FunctionSymbol* conversionFunction) {
407407
conversionFunctions_.push_back(conversionFunction);
408408
}
409409

410-
auto ClassSymbol::declaration() const -> SpecifierAST* { return specifier_; }
411-
412-
void ClassSymbol::setDeclaration(SpecifierAST* specifier) {
413-
specifier_ = specifier;
414-
}
415-
416-
auto ClassSymbol::templateDeclaration() const -> TemplateDeclarationAST* {
417-
return templateDeclaration_;
418-
}
419-
420-
void ClassSymbol::setTemplateDeclaration(
421-
TemplateDeclarationAST* templateDeclaration) {
422-
templateDeclaration_ = templateDeclaration;
423-
}
424-
425-
auto ClassSymbol::specializations() const
426-
-> std::span<const TemplateSpecialization<ClassSymbol>> {
427-
if (!templateInfo_) return {};
428-
return templateInfo_->specializations();
429-
}
430-
431-
auto ClassSymbol::findSpecialization(
432-
const std::vector<TemplateArgument>& arguments) const -> ClassSymbol* {
433-
if (!templateInfo_) return {};
434-
return templateInfo_->findSpecialization(arguments);
435-
}
436-
437-
void ClassSymbol::addSpecialization(std::vector<TemplateArgument> arguments,
438-
ClassSymbol* specialization) {
439-
if (!templateInfo_) {
440-
templateInfo_ = std::make_unique<TemplateInfo<ClassSymbol>>(this);
441-
}
442-
auto index = templateInfo_->specializations().size();
443-
specialization->setSpecializationInfo(this, index);
444-
templateInfo_->addSpecialization(std::move(arguments), specialization);
445-
}
446-
447410
auto ClassSymbol::buildClassLayout(Control* control)
448411
-> std::expected<bool, std::string> {
449412
int offset = 0;
@@ -726,21 +689,22 @@ void TypeAliasSymbol::setTemplateDeclaration(
726689
}
727690

728691
auto TypeAliasSymbol::specializations() const
729-
-> std::span<const TemplateSpecialization<TypeAliasSymbol>> {
692+
-> std::span<const TemplateSpecialization> {
730693
if (!templateInfo_) return {};
731694
return templateInfo_->specializations();
732695
}
733696

734697
auto TypeAliasSymbol::findSpecialization(
735698
const std::vector<TemplateArgument>& arguments) const -> TypeAliasSymbol* {
736699
if (!templateInfo_) return {};
737-
return templateInfo_->findSpecialization(arguments);
700+
return symbol_cast<TypeAliasSymbol>(
701+
templateInfo_->findSpecialization(arguments));
738702
}
739703

740704
void TypeAliasSymbol::addSpecialization(std::vector<TemplateArgument> arguments,
741705
TypeAliasSymbol* specialization) {
742706
if (!templateInfo_) {
743-
templateInfo_ = std::make_unique<TemplateInfo<TypeAliasSymbol>>(this);
707+
templateInfo_ = std::make_unique<TemplateInfo>(this);
744708
}
745709
auto index = templateInfo_->specializations().size();
746710
specialization->setSpecializationInfo(this, index);
@@ -792,21 +756,22 @@ void VariableSymbol::setTemplateDeclaration(
792756
}
793757

794758
auto VariableSymbol::specializations() const
795-
-> std::span<const TemplateSpecialization<VariableSymbol>> {
759+
-> std::span<const TemplateSpecialization> {
796760
if (!templateInfo_) return {};
797761
return templateInfo_->specializations();
798762
}
799763

800764
auto VariableSymbol::findSpecialization(
801765
const std::vector<TemplateArgument>& arguments) const -> VariableSymbol* {
802766
if (!templateInfo_) return {};
803-
return templateInfo_->findSpecialization(arguments);
767+
return symbol_cast<VariableSymbol>(
768+
templateInfo_->findSpecialization(arguments));
804769
}
805770

806771
void VariableSymbol::addSpecialization(std::vector<TemplateArgument> arguments,
807772
VariableSymbol* specialization) {
808773
if (!templateInfo_) {
809-
templateInfo_ = std::make_unique<TemplateInfo<VariableSymbol>>(this);
774+
templateInfo_ = std::make_unique<TemplateInfo>(this);
810775
}
811776
auto index = templateInfo_->specializations().size();
812777
specialization->setSpecializationInfo(this, index);

0 commit comments

Comments
 (0)