@@ -3715,12 +3715,14 @@ auto Parser::parse_maybe_module() -> bool {
37153715 return is_module;
37163716}
37173717
3718- auto Parser::parse_template_declaration_body (DeclarationAST*& yyast) -> bool {
3719- if (parse_deduction_guide (yyast)) return true ;
3720- if (parse_export_declaration (yyast)) return true ;
3721- if (parse_opaque_enum_declaration (yyast)) return true ;
3722- if (parse_alias_declaration (yyast)) return true ;
3723- return parse_simple_declaration (yyast, BindingContext::kTemplate );
3718+ auto Parser::parse_template_declaration_body (
3719+ DeclarationAST*& yyast, TemplateDeclarationAST* templateHead) -> bool {
3720+ if (parse_deduction_guide (yyast, templateHead)) return true ;
3721+ if (parse_export_declaration (yyast, templateHead)) return true ;
3722+ if (parse_opaque_enum_declaration (yyast, templateHead)) return true ;
3723+ if (parse_alias_declaration (yyast, templateHead)) return true ;
3724+ return parse_simple_declaration (yyast, BindingContext::kTemplate ,
3725+ templateHead);
37243726}
37253727
37263728auto Parser::parse_declaration (DeclarationAST*& yyast, BindingContext ctx)
@@ -3755,7 +3757,9 @@ auto Parser::parse_block_declaration(DeclarationAST*& yyast, BindingContext ctx)
37553757 return parse_simple_declaration (yyast, ctx);
37563758}
37573759
3758- auto Parser::parse_alias_declaration (DeclarationAST*& yyast) -> bool {
3760+ auto Parser::parse_alias_declaration (DeclarationAST*& yyast,
3761+ TemplateDeclarationAST* templateHead)
3762+ -> bool {
37593763 SourceLocation usingLoc;
37603764 SourceLocation identifierLoc;
37613765 const Identifier* identifier = nullptr ;
@@ -3795,6 +3799,7 @@ auto Parser::parse_alias_declaration(DeclarationAST*& yyast) -> bool {
37953799 expect (TokenKind::T_SEMICOLON, semicolonLoc);
37963800
37973801 auto symbol = binder_.declareTypeAlias (identifierLoc, typeId);
3802+ symbol->setTemplateDeclaration (templateHead);
37983803
37993804 if (is_template (symbol)) {
38003805 mark_maybe_template_name (identifier);
@@ -3813,8 +3818,6 @@ auto Parser::parse_alias_declaration(DeclarationAST*& yyast) -> bool {
38133818 ast->semicolonLoc = semicolonLoc;
38143819 ast->symbol = symbol;
38153820
3816- ast->symbol ->setDeclaration (ast);
3817-
38183821 return true ;
38193822}
38203823
@@ -3919,7 +3922,7 @@ auto Parser::parse_notypespec_function_definition(
39193922auto Parser::parse_type_or_forward_declaration (
39203923 DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
39213924 List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
3922- BindingContext ctx) -> bool {
3925+ BindingContext ctx, TemplateDeclarationAST* templateHead ) -> bool {
39233926 if (ctx == BindingContext::kInitStatement ) return false ;
39243927
39253928 LookaheadParser lookahead{this };
@@ -3995,7 +3998,9 @@ auto Parser::parse_structured_binding(DeclarationAST*& yyast,
39953998}
39963999
39974000auto Parser::parse_simple_declaration (DeclarationAST*& yyast,
3998- BindingContext ctx) -> bool {
4001+ BindingContext ctx,
4002+ TemplateDeclarationAST* templateHead)
4003+ -> bool {
39994004 SourceLocation extensionLoc;
40004005
40014006 match (TokenKind::T___EXTENSION__, extensionLoc);
@@ -4035,22 +4040,21 @@ auto Parser::parse_simple_declaration(DeclarationAST*& yyast,
40354040 if (!lookat_decl_specifiers ()) return false ;
40364041
40374042 if (parse_type_or_forward_declaration (yyast, attributes, declSpecifierList,
4038- specs, ctx))
4043+ specs, ctx, templateHead ))
40394044 return true ;
40404045
4041- if (parse_structured_binding (yyast, attributes, declSpecifierList, specs ,
4042- ctx))
4046+ if (!templateHead && parse_structured_binding (yyast, attributes,
4047+ declSpecifierList, specs, ctx))
40434048 return true ;
40444049
40454050 return parse_simple_declaration (yyast, attributes, declSpecifierList, specs,
4046- ctx);
4051+ ctx, templateHead );
40474052}
40484053
4049- auto Parser::parse_simple_declaration (DeclarationAST*& yyast,
4050- List<AttributeSpecifierAST*>* attributes,
4051- List<SpecifierAST*>* declSpecifierList,
4052- const DeclSpecs& specs,
4053- BindingContext ctx) -> bool {
4054+ auto Parser::parse_simple_declaration (
4055+ DeclarationAST*& yyast, List<AttributeSpecifierAST*>* attributes,
4056+ List<SpecifierAST*>* declSpecifierList, const DeclSpecs& specs,
4057+ BindingContext ctx, TemplateDeclarationAST* templateHead) -> bool {
40544058 DeclaratorAST* declarator = nullptr ;
40554059 Decl decl{specs};
40564060 if (!parse_declarator (declarator, decl)) return false ;
@@ -4136,7 +4140,8 @@ auto Parser::parse_simple_declaration(DeclarationAST*& yyast,
41364140 auto declIt = &initDeclaratorList;
41374141
41384142 InitDeclaratorAST* initDeclarator = nullptr ;
4139- if (!parse_init_declarator (initDeclarator, declarator, decl, ctx))
4143+ if (!parse_init_declarator (initDeclarator, declarator, decl, ctx,
4144+ templateHead))
41404145 return false ;
41414146
41424147 if (ctx == BindingContext::kTemplate ) {
@@ -4152,7 +4157,8 @@ auto Parser::parse_simple_declaration(DeclarationAST*& yyast,
41524157
41534158 while (match (TokenKind::T_COMMA, commaLoc)) {
41544159 InitDeclaratorAST* initDeclarator = nullptr ;
4155- if (!parse_init_declarator (initDeclarator, specs, ctx)) return false ;
4160+ if (!parse_init_declarator (initDeclarator, specs, ctx, templateHead))
4161+ return false ;
41564162
41574163 *declIt = make_list_node (pool_, initDeclarator);
41584164 declIt = &(*declIt)->next ;
@@ -5206,7 +5212,8 @@ auto Parser::parse_placeholder_type_specifier(SpecifierAST*& yyast,
52065212}
52075213
52085214auto Parser::parse_init_declarator (InitDeclaratorAST*& yyast,
5209- const DeclSpecs& specs, BindingContext ctx)
5215+ const DeclSpecs& specs, BindingContext ctx,
5216+ TemplateDeclarationAST* templateHead)
52105217 -> bool {
52115218 DeclaratorAST* declarator = nullptr ;
52125219 Decl decl{specs};
@@ -5217,7 +5224,9 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
52175224
52185225auto Parser::parse_init_declarator (InitDeclaratorAST*& yyast,
52195226 DeclaratorAST* declarator, Decl& decl,
5220- BindingContext ctx) -> bool {
5227+ BindingContext ctx,
5228+ TemplateDeclarationAST* templateHead)
5229+ -> bool {
52215230 Symbol* symbol = nullptr ;
52225231
52235232 if (auto declId = decl.declaratorId ; declId) {
@@ -5229,6 +5238,7 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
52295238 symbol = functionSymbol;
52305239 } else {
52315240 auto variableSymbol = binder_.declareVariable (declarator, decl);
5241+ variableSymbol->setTemplateDeclaration (templateHead);
52325242 symbol = variableSymbol;
52335243 }
52345244 }
@@ -5249,6 +5259,10 @@ auto Parser::parse_init_declarator(InitDeclaratorAST*& yyast,
52495259 ast->initializer = initializer;
52505260 ast->symbol = symbol;
52515261
5262+ if (auto var = symbol_cast<VariableSymbol>(ast->symbol )) {
5263+ var->setInitializer (initializer);
5264+ }
5265+
52525266 return true ;
52535267}
52545268
@@ -6186,7 +6200,9 @@ auto Parser::parse_enum_head_name(NestedNameSpecifierAST*& nestedNameSpecifier,
61866200 return true ;
61876201}
61886202
6189- auto Parser::parse_opaque_enum_declaration (DeclarationAST*& yyast) -> bool {
6203+ auto Parser::parse_opaque_enum_declaration (DeclarationAST*& yyast,
6204+ TemplateDeclarationAST* templateHead)
6205+ -> bool {
61906206 SourceLocation enumLoc;
61916207 SourceLocation classLoc;
61926208 List<AttributeSpecifierAST*>* attributes = nullptr ;
@@ -7255,7 +7271,9 @@ auto Parser::parse_module_partition(ModulePartitionAST*& yyast) -> bool {
72557271 return true ;
72567272}
72577273
7258- auto Parser::parse_export_declaration (DeclarationAST*& yyast) -> bool {
7274+ auto Parser::parse_export_declaration (DeclarationAST*& yyast,
7275+ TemplateDeclarationAST* templateHead)
7276+ -> bool {
72597277 SourceLocation exportLoc;
72607278
72617279 if (!match (TokenKind::T_EXPORT, exportLoc)) return false ;
@@ -8284,7 +8302,8 @@ auto Parser::parse_literal_operator_id(LiteralOperatorIdAST*& yyast) -> bool {
82848302 return true ;
82858303}
82868304
8287- auto Parser::parse_template_declaration (TemplateDeclarationAST*& yyast)
8305+ auto Parser::parse_template_declaration (TemplateDeclarationAST*& yyast,
8306+ TemplateDeclarationAST* templateHead)
82888307 -> bool {
82898308 if (!lookat (TokenKind::T_TEMPLATE, TokenKind::T_LESS)) return false ;
82908309
@@ -8294,6 +8313,8 @@ auto Parser::parse_template_declaration(TemplateDeclarationAST*& yyast)
82948313 auto ast = make_node<TemplateDeclarationAST>(pool_);
82958314 yyast = ast;
82968315
8316+ if (!templateHead) templateHead = ast;
8317+
82978318 auto templateParametersSymbol =
82988319 control_->newTemplateParametersSymbol (scope (), {});
82998320 ast->symbol = templateParametersSymbol;
@@ -8312,7 +8333,7 @@ auto Parser::parse_template_declaration(TemplateDeclarationAST*& yyast)
83128333
83138334 if (lookat (TokenKind::T_TEMPLATE, TokenKind::T_LESS)) {
83148335 TemplateDeclarationAST* templateDeclaration = nullptr ;
8315- (void )parse_template_declaration (templateDeclaration);
8336+ (void )parse_template_declaration (templateDeclaration, templateHead );
83168337 ast->declaration = templateDeclaration;
83178338 return true ;
83188339 }
@@ -8321,7 +8342,7 @@ auto Parser::parse_template_declaration(TemplateDeclarationAST*& yyast)
83218342 return true ;
83228343 }
83238344
8324- if (!parse_template_declaration_body (ast->declaration ))
8345+ if (!parse_template_declaration_body (ast->declaration , templateHead ))
83258346 parse_error (" expected a declaration" );
83268347
83278348 return true ;
@@ -8910,7 +8931,9 @@ auto Parser::parse_constraint_expression(ExpressionAST*& yyast) -> bool {
89108931 return parse_logical_or_expression (yyast, exprContext);
89118932}
89128933
8913- auto Parser::parse_deduction_guide (DeclarationAST*& yyast) -> bool {
8934+ auto Parser::parse_deduction_guide (DeclarationAST*& yyast,
8935+ TemplateDeclarationAST* templateHead)
8936+ -> bool {
89148937 SpecifierAST* explicitSpecifier = nullptr ;
89158938 SourceLocation identifierLoc;
89168939 SourceLocation lparenLoc;
0 commit comments