Skip to content

Commit 28fb2c3

Browse files
committed
Simplify binding of template symbols
1 parent 07c4c3b commit 28fb2c3

File tree

6 files changed

+172
-143
lines changed

6 files changed

+172
-143
lines changed

src/parser/cxx/ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ class AliasDeclarationAST final : public DeclarationAST {
436436
TypeIdAST* typeId = nullptr;
437437
SourceLocation semicolonLoc;
438438
const Identifier* identifier = nullptr;
439+
TypeAliasSymbol* symbol = nullptr;
439440

440441
void accept(ASTVisitor* visitor) override { visitor->visit(this); }
441442

src/parser/cxx/parser.cc

Lines changed: 125 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -3867,14 +3867,7 @@ void Parser::parse_condition(ExpressionAST*& yyast, const ExprContext& ctx) {
38673867
Decl decl{specs};
38683868
if (!parse_declarator(declarator, decl)) return false;
38693869

3870-
auto symbolType = GetDeclaratorType{this}(declarator, decl.specs.getType());
3871-
3872-
auto symbol = control_->newVariableSymbol(scope_, decl.location());
3873-
applySpecifiers(symbol, decl.specs);
3874-
symbol->setName(decl.getName());
3875-
symbol->setType(symbolType);
3876-
3877-
std::invoke(DeclareSymbol{this, scope_}, symbol);
3870+
auto symbol = declareVariable(declarator, decl, BindingContext::kCondition);
38783871

38793872
ExpressionAST* initializer = nullptr;
38803873

@@ -4521,6 +4514,7 @@ auto Parser::parse_alias_declaration(
45214514
const std::vector<TemplateDeclarationAST*>& templateDeclarations) -> bool {
45224515
SourceLocation usingLoc;
45234516
SourceLocation identifierLoc;
4517+
const Identifier* identifier = nullptr;
45244518
List<AttributeSpecifierAST*>* attributes = nullptr;
45254519
SourceLocation equalLoc;
45264520

@@ -4531,6 +4525,8 @@ auto Parser::parse_alias_declaration(
45314525

45324526
if (!match(TokenKind::T_IDENTIFIER, identifierLoc)) return false;
45334527

4528+
identifier = unit->identifier(identifierLoc);
4529+
45344530
parse_optional_attribute_specifier_seq(attributes);
45354531

45364532
if (!match(TokenKind::T_EQUAL, equalLoc)) return false;
@@ -4559,24 +4555,20 @@ auto Parser::parse_alias_declaration(
45594555

45604556
expect(TokenKind::T_SEMICOLON, semicolonLoc);
45614557

4562-
auto aliasName = unit->identifier(identifierLoc);
4563-
4564-
auto aliasSymbol = control_->newTypeAliasSymbol(scope_, identifierLoc);
4565-
aliasSymbol->setName(aliasName);
4566-
if (typeId) aliasSymbol->setType(typeId->type);
4567-
std::invoke(DeclareSymbol{this, scope_}, aliasSymbol);
4558+
auto symbol = declareTypeAlias(identifierLoc, typeId);
45684559

45694560
auto ast = make_node<AliasDeclarationAST>(pool_);
45704561
yyast = ast;
45714562

45724563
ast->usingLoc = usingLoc;
45734564
ast->identifierLoc = identifierLoc;
4574-
ast->identifier = aliasName;
4565+
ast->identifier = identifier;
45754566
ast->attributeList = attributes;
45764567
ast->equalLoc = equalLoc;
45774568
ast->gnuAttributeList = gnuAttributeList;
45784569
ast->typeId = typeId;
45794570
ast->semicolonLoc = semicolonLoc;
4571+
ast->symbol = symbol;
45804572

45814573
return true;
45824574
}
@@ -4906,11 +4898,7 @@ auto Parser::parse_simple_declaration(
49064898
to_string(functionName)));
49074899
}
49084900

4909-
functionSymbol = control_->newFunctionSymbol(scope_, decl.location());
4910-
applySpecifiers(functionSymbol, decl.specs);
4911-
functionSymbol->setName(functionName);
4912-
functionSymbol->setType(functionType);
4913-
std::invoke(DeclareSymbol{this, scope_}, functionSymbol);
4901+
functionSymbol = declareFunction(declarator, decl);
49144902
}
49154903

49164904
if (auto params = functionDeclarator->parameterDeclarationClause) {
@@ -5047,19 +5035,7 @@ auto Parser::parse_notypespec_function_definition(
50475035
getFunction(scope_, decl.getName(), functionType);
50485036

50495037
if (!functionSymbol) {
5050-
functionSymbol = control_->newFunctionSymbol(scope_, decl.location());
5051-
applySpecifiers(functionSymbol, decl.specs);
5052-
functionSymbol->setName(decl.getName());
5053-
functionSymbol->setType(functionType);
5054-
5055-
if (is_constructor(functionSymbol)) {
5056-
auto enclosingClass = symbol_cast<ClassSymbol>(scope_->owner());
5057-
if (enclosingClass) {
5058-
enclosingClass->addConstructor(functionSymbol);
5059-
}
5060-
} else {
5061-
std::invoke(DeclareSymbol{this, scope_}, functionSymbol);
5062-
}
5038+
functionSymbol = declareFunction(declarator, decl);
50635039
}
50645040

50655041
SourceLocation semicolonLoc;
@@ -6826,35 +6802,18 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
68266802
auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
68276803
DeclaratorAST* declarator, Decl& decl,
68286804
BindingContext ctx) -> bool {
6829-
Symbol* declaredSynbol = nullptr;
6805+
Symbol* symbol = nullptr;
6806+
68306807
if (auto declId = decl.declaratorId; declId) {
6831-
auto symbolType = GetDeclaratorType{this}(declarator, decl.specs.getType());
6832-
const auto name = convertName(declId->unqualifiedId);
6833-
if (name) {
6834-
if (decl.specs.isTypedef) {
6835-
auto symbol = control_->newTypeAliasSymbol(scope_, decl.location());
6836-
symbol->setName(name);
6837-
symbol->setType(symbolType);
6838-
std::invoke(DeclareSymbol{this, scope_}, symbol);
6839-
declaredSynbol = symbol;
6840-
} else if (getFunctionPrototype(declarator)) {
6841-
auto functionSymbol =
6842-
control_->newFunctionSymbol(scope_, decl.location());
6843-
applySpecifiers(functionSymbol, decl.specs);
6844-
functionSymbol->setName(name);
6845-
functionSymbol->setType(symbolType);
6846-
std::invoke(DeclareSymbol{this, scope_}, functionSymbol);
6847-
declaredSynbol = functionSymbol;
6848-
} else {
6849-
auto symbol = control_->newVariableSymbol(scope_, decl.location());
6850-
applySpecifiers(symbol, decl.specs);
6851-
symbol->setName(name);
6852-
symbol->setType(symbolType);
6853-
if (ctx != BindingContext::kInitStatement) {
6854-
std::invoke(DeclareSymbol{this, scope_}, symbol);
6855-
}
6856-
declaredSynbol = symbol;
6857-
}
6808+
if (decl.specs.isTypedef) {
6809+
auto typedefSymbol = declareTypedef(declarator, decl);
6810+
symbol = typedefSymbol;
6811+
} else if (getFunctionPrototype(declarator)) {
6812+
auto functionSymbol = declareFunction(declarator, decl);
6813+
symbol = functionSymbol;
6814+
} else {
6815+
auto variableSymbol = declareVariable(declarator, decl, ctx);
6816+
symbol = variableSymbol;
68586817
}
68596818
}
68606819

@@ -6872,7 +6831,7 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
68726831
ast->declarator = declarator;
68736832
ast->requiresClause = requiresClause;
68746833
ast->initializer = initializer;
6875-
ast->symbol = declaredSynbol;
6834+
ast->symbol = symbol;
68766835

68776836
return true;
68786837
}
@@ -9294,8 +9253,9 @@ auto Parser::parse_class_head(ClassHead& classHead) -> bool {
92949253
classSymbol = control_->newClassSymbol(scope_, location);
92959254
classSymbol->setIsUnion(isUnion);
92969255
classSymbol->setName(identifier);
9256+
classSymbol->setTemplateParameters(currentTemplateParameters());
92979257

9298-
std::invoke(DeclareSymbol{this, scope_}, classSymbol);
9258+
std::invoke(DeclareSymbol{this, declaringScope()}, classSymbol);
92999259
}
93009260

93019261
classHead.symbol = classSymbol;
@@ -9458,14 +9418,7 @@ auto Parser::parse_member_declaration_helper(DeclarationAST*& yyast) -> bool {
94589418

94599419
lookahead.commit();
94609420

9461-
auto functionType =
9462-
GetDeclaratorType{this}(declarator, decl.specs.getType());
9463-
9464-
auto functionSymbol = control_->newFunctionSymbol(scope_, decl.location());
9465-
applySpecifiers(functionSymbol, decl.specs);
9466-
functionSymbol->setName(decl.getName());
9467-
functionSymbol->setType(functionType);
9468-
std::invoke(DeclareSymbol{this, scope_}, functionSymbol);
9421+
auto functionSymbol = declareFunction(declarator, decl);
94699422

94709423
ScopeGuard scopeGuard{this};
94719424

@@ -9604,41 +9557,102 @@ auto Parser::parse_member_declarator(InitDeclaratorAST*& yyast,
96049557
return parse_member_declarator(yyast, declarator, decl);
96059558
}
96069559

9560+
auto Parser::declareTypeAlias(SourceLocation identifierLoc, TypeIdAST* typeId)
9561+
-> TypeAliasSymbol* {
9562+
auto name = unit->identifier(identifierLoc);
9563+
auto symbol = control_->newTypeAliasSymbol(scope_, identifierLoc);
9564+
symbol->setName(name);
9565+
if (typeId) symbol->setType(typeId->type);
9566+
symbol->setTemplateParameters(currentTemplateParameters());
9567+
std::invoke(DeclareSymbol{this, declaringScope()}, symbol);
9568+
return symbol;
9569+
}
9570+
9571+
auto Parser::declareTypedef(DeclaratorAST* declarator, const Decl& decl)
9572+
-> TypeAliasSymbol* {
9573+
auto name = decl.getName();
9574+
auto type = GetDeclaratorType{this}(declarator, decl.specs.getType());
9575+
auto typedefSymbol = control_->newTypeAliasSymbol(scope_, decl.location());
9576+
typedefSymbol->setName(name);
9577+
typedefSymbol->setType(type);
9578+
std::invoke(DeclareSymbol{this, scope_}, typedefSymbol);
9579+
return typedefSymbol;
9580+
}
9581+
9582+
auto Parser::declareFunction(DeclaratorAST* declarator, const Decl& decl)
9583+
-> FunctionSymbol* {
9584+
auto name = decl.getName();
9585+
auto type = GetDeclaratorType{this}(declarator, decl.specs.getType());
9586+
auto functionSymbol = control_->newFunctionSymbol(scope_, decl.location());
9587+
applySpecifiers(functionSymbol, decl.specs);
9588+
functionSymbol->setName(name);
9589+
functionSymbol->setType(type);
9590+
functionSymbol->setTemplateParameters(currentTemplateParameters());
9591+
9592+
if (is_constructor(functionSymbol)) {
9593+
auto enclosingClass = symbol_cast<ClassSymbol>(scope_->owner());
9594+
9595+
if (enclosingClass) {
9596+
enclosingClass->addConstructor(functionSymbol);
9597+
}
9598+
} else {
9599+
std::invoke(DeclareSymbol{this, declaringScope()}, functionSymbol);
9600+
}
9601+
9602+
return functionSymbol;
9603+
}
9604+
9605+
auto Parser::declareField(DeclaratorAST* declarator, const Decl& decl)
9606+
-> FieldSymbol* {
9607+
auto name = decl.getName();
9608+
auto type = GetDeclaratorType{this}(declarator, decl.specs.getType());
9609+
auto fieldSymbol = control_->newFieldSymbol(scope_, decl.location());
9610+
applySpecifiers(fieldSymbol, decl.specs);
9611+
fieldSymbol->setName(name);
9612+
fieldSymbol->setType(type);
9613+
std::invoke(DeclareSymbol{this, scope_}, fieldSymbol);
9614+
return fieldSymbol;
9615+
}
9616+
9617+
auto Parser::declareVariable(DeclaratorAST* declarator, const Decl& decl,
9618+
const BindingContext& ctx) -> VariableSymbol* {
9619+
auto name = decl.getName();
9620+
auto symbol = control_->newVariableSymbol(scope_, decl.location());
9621+
auto type = GetDeclaratorType{this}(declarator, decl.specs.getType());
9622+
applySpecifiers(symbol, decl.specs);
9623+
symbol->setName(name);
9624+
symbol->setType(type);
9625+
symbol->setTemplateParameters(currentTemplateParameters());
9626+
if (ctx != BindingContext::kInitStatement) {
9627+
std::invoke(DeclareSymbol{this, declaringScope()}, symbol);
9628+
}
9629+
return symbol;
9630+
}
9631+
9632+
auto Parser::declareMemberSymbol(DeclaratorAST* declarator, const Decl& decl)
9633+
-> Symbol* {
9634+
if (decl.specs.isTypedef) return declareTypedef(declarator, decl);
9635+
9636+
if (getFunctionPrototype(declarator))
9637+
return declareFunction(declarator, decl);
9638+
9639+
return declareField(declarator, decl);
9640+
}
9641+
96079642
auto Parser::parse_member_declarator(InitDeclaratorAST*& yyast,
96089643
DeclaratorAST* declarator,
96099644
const Decl& decl) -> bool {
96109645
if (!declarator) {
96119646
return false;
96129647
}
96139648

9614-
auto symbolType = GetDeclaratorType{this}(declarator, decl.specs.getType());
9615-
9616-
if (decl.specs.isTypedef) {
9617-
auto typedefSymbol = control_->newTypeAliasSymbol(scope_, decl.location());
9618-
typedefSymbol->setName(decl.getName());
9619-
typedefSymbol->setType(symbolType);
9620-
std::invoke(DeclareSymbol{this, scope_}, typedefSymbol);
9621-
} else {
9622-
if (auto functionDeclarator = getFunctionPrototype(declarator)) {
9623-
auto functionSymbol =
9624-
control_->newFunctionSymbol(scope_, decl.location());
9625-
applySpecifiers(functionSymbol, decl.specs);
9626-
functionSymbol->setName(decl.getName());
9627-
functionSymbol->setType(symbolType);
9628-
std::invoke(DeclareSymbol{this, scope_}, functionSymbol);
9629-
} else {
9630-
auto fieldSymbol = control_->newFieldSymbol(scope_, decl.location());
9631-
applySpecifiers(fieldSymbol, decl.specs);
9632-
fieldSymbol->setName(decl.getName());
9633-
fieldSymbol->setType(symbolType);
9634-
std::invoke(DeclareSymbol{this, scope_}, fieldSymbol);
9635-
}
9636-
}
9649+
auto symbol = declareMemberSymbol(declarator, decl);
96379650

96389651
auto ast = make_node<InitDeclaratorAST>(pool_);
96399652
yyast = ast;
96409653

96419654
ast->declarator = declarator;
9655+
ast->symbol = symbol;
96429656

96439657
if (auto functionDeclarator = getFunctionPrototype(declarator)) {
96449658
RequiresClauseAST* requiresClause = nullptr;
@@ -10208,8 +10222,6 @@ auto Parser::parse_template_declaration(
1020810222
control_->newTemplateParametersSymbol(scope_, {});
1020910223
ast->symbol = templateParametersSymbol;
1021010224

10211-
std::invoke(DeclareSymbol{this, scope_}, templateParametersSymbol);
10212-
1021310225
setScope(ast->symbol);
1021410226

1021510227
templateDeclarations.push_back(ast);
@@ -10954,9 +10966,13 @@ auto Parser::parse_concept_definition(DeclarationAST*& yyast) -> bool {
1095410966
expect(TokenKind::T_IDENTIFIER, ast->identifierLoc);
1095510967
ast->identifier = unit->identifier(ast->identifierLoc);
1095610968

10969+
auto templateParameters = currentTemplateParameters();
10970+
1095710971
auto symbol = control_->newConceptSymbol(scope_, ast->identifierLoc);
1095810972
symbol->setName(ast->identifier);
10959-
std::invoke(DeclareSymbol{this, scope_}, symbol);
10973+
symbol->setTemplateParameters(templateParameters);
10974+
10975+
std::invoke(DeclareSymbol{this, declaringScope()}, symbol);
1096010976

1096110977
if (ast->identifierLoc) {
1096210978
concept_names_.insert(ast->identifier);
@@ -11253,6 +11269,18 @@ void Parser::setScope(Scope* scope) { scope_ = scope; }
1125311269

1125411270
void Parser::setScope(ScopedSymbol* symbol) { setScope(symbol->scope()); }
1125511271

11272+
auto Parser::currentTemplateParameters() const -> TemplateParametersSymbol* {
11273+
auto templateParameters =
11274+
symbol_cast<TemplateParametersSymbol>(scope_->owner());
11275+
11276+
return templateParameters;
11277+
}
11278+
11279+
auto Parser::declaringScope() const -> Scope* {
11280+
if (!scope_->isTemplateParametersScope()) return scope_;
11281+
return scope_->enclosingNonTemplateParametersScope();
11282+
}
11283+
1125611284
void Parser::completeFunctionDefinition(FunctionDefinitionAST* ast) {
1125711285
if (!ast->functionBody) return;
1125811286

src/parser/cxx/parser.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,11 @@ class Parser final {
785785
void setScope(Scope* scope);
786786
void setScope(ScopedSymbol* symbol);
787787

788+
[[nodiscard]] auto currentTemplateParameters() const
789+
-> TemplateParametersSymbol*;
790+
791+
[[nodiscard]] auto declaringScope() const -> Scope*;
792+
788793
// lookup
789794
[[nodiscard]] auto convertName(UnqualifiedIdAST* id) -> const Name*;
790795

@@ -797,6 +802,26 @@ class Parser final {
797802

798803
void enterFunctionScope(FunctionDeclaratorChunkAST* functionDeclarator);
799804

805+
[[nodiscard]] auto declareMemberSymbol(DeclaratorAST* declarator,
806+
const Decl& decl) -> Symbol*;
807+
808+
[[nodiscard]] auto declareTypeAlias(SourceLocation identifierLoc,
809+
TypeIdAST* typeId) -> TypeAliasSymbol*;
810+
811+
[[nodiscard]] auto declareTypedef(DeclaratorAST* declarator, const Decl& decl)
812+
-> TypeAliasSymbol*;
813+
814+
[[nodiscard]] auto declareFunction(DeclaratorAST* declarator,
815+
const Decl& decl) -> FunctionSymbol*;
816+
817+
[[nodiscard]] auto declareField(DeclaratorAST* declarator, const Decl& decl)
818+
-> FieldSymbol*;
819+
820+
[[nodiscard]] auto declareVariable(DeclaratorAST* declarator,
821+
const Decl& decl,
822+
const BindingContext& ctx)
823+
-> VariableSymbol*;
824+
800825
[[nodiscard]] auto instantiate(SimpleTemplateIdAST* templateId) -> Symbol*;
801826

802827
void applySpecifiers(FunctionSymbol* symbol, const DeclSpecs& specs);

0 commit comments

Comments
 (0)