@@ -1593,6 +1593,9 @@ static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context,
1593
1593
/// parameter lists. This scope specifier precedes a qualified name that is
1594
1594
/// being declared.
1595
1595
///
1596
+ /// \param TemplateId The template-id following the scope specifier, if there
1597
+ /// is one. Used to check for a missing 'template<>'.
1598
+ ///
1596
1599
/// \param ParamLists the template parameter lists, from the outermost to the
1597
1600
/// innermost template parameter lists.
1598
1601
///
@@ -1611,6 +1614,7 @@ static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context,
1611
1614
/// itself a template).
1612
1615
TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
1613
1616
SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS,
1617
+ TemplateIdAnnotation *TemplateId,
1614
1618
ArrayRef<TemplateParameterList *> ParamLists, bool IsFriend,
1615
1619
bool &IsExplicitSpecialization, bool &Invalid) {
1616
1620
IsExplicitSpecialization = false;
@@ -1830,6 +1834,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
1830
1834
else
1831
1835
ExpectedTemplateLoc = DeclStartLoc;
1832
1836
1837
+ // FIXME: Don't recover this way if we SawNonEmptyTemplateParameterList.
1833
1838
Diag(DeclLoc, diag::err_template_spec_needs_header)
1834
1839
<< getRangeOfTypeInNestedNameSpecifier(Context, T, SS)
1835
1840
<< FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
@@ -1875,12 +1880,33 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
1875
1880
continue;
1876
1881
}
1877
1882
}
1878
-
1883
+
1879
1884
// If there were at least as many template-ids as there were template
1880
1885
// parameter lists, then there are no template parameter lists remaining for
1881
1886
// the declaration itself.
1882
- if (ParamIdx >= ParamLists.size())
1887
+ if (ParamIdx >= ParamLists.size()) {
1888
+ if (TemplateId && !IsFriend) {
1889
+ // FIXME: Don't recover this way if we SawNonEmptyTemplateParameterList.
1890
+ // We don't have a template header for the declaration itself, but we
1891
+ // should.
1892
+ SourceLocation ExpectedTemplateLoc;
1893
+ if (!ParamLists.empty())
1894
+ ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();
1895
+ else
1896
+ ExpectedTemplateLoc = DeclStartLoc;
1897
+ Diag(DeclLoc, diag::err_template_spec_needs_header)
1898
+ << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
1899
+ << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
1900
+ IsExplicitSpecialization = true;
1901
+
1902
+ // Fabricate an empty template parameter list for the invented header.
1903
+ return TemplateParameterList::Create(Context, SourceLocation(),
1904
+ SourceLocation(), 0, 0,
1905
+ SourceLocation());
1906
+ }
1907
+
1883
1908
return 0;
1909
+ }
1884
1910
1885
1911
// If there were too many template parameter lists, complain about that now.
1886
1912
if (ParamIdx < ParamLists.size() - 1) {
@@ -2355,6 +2381,17 @@ static bool isSameAsPrimaryTemplate(TemplateParameterList *Params,
2355
2381
return true;
2356
2382
}
2357
2383
2384
+ /// Convert the parser's template argument list representation into our form.
2385
+ static TemplateArgumentListInfo
2386
+ makeTemplateArgumentListInfo(Sema &S, TemplateIdAnnotation &TemplateId) {
2387
+ TemplateArgumentListInfo TemplateArgs(TemplateId.LAngleLoc,
2388
+ TemplateId.RAngleLoc);
2389
+ ASTTemplateArgsPtr TemplateArgsPtr(TemplateId.getTemplateArgs(),
2390
+ TemplateId.NumArgs);
2391
+ S.translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
2392
+ return TemplateArgs;
2393
+ }
2394
+
2358
2395
DeclResult Sema::ActOnVarTemplateSpecialization(
2359
2396
Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc,
2360
2397
TemplateParameterList *TemplateParams, VarDecl::StorageClass SC,
@@ -2364,13 +2401,12 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
2364
2401
"Variable template specialization is declared with a template it.");
2365
2402
2366
2403
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
2404
+ TemplateArgumentListInfo TemplateArgs =
2405
+ makeTemplateArgumentListInfo(*this, *TemplateId);
2367
2406
SourceLocation TemplateNameLoc = D.getIdentifierLoc();
2368
2407
SourceLocation LAngleLoc = TemplateId->LAngleLoc;
2369
2408
SourceLocation RAngleLoc = TemplateId->RAngleLoc;
2370
- ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
2371
- TemplateId->NumArgs);
2372
- TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
2373
- translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
2409
+
2374
2410
TemplateName Name = TemplateId->Template.get();
2375
2411
2376
2412
// The template-id must name a variable template.
@@ -5840,23 +5876,23 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
5840
5876
TagUseKind TUK,
5841
5877
SourceLocation KWLoc,
5842
5878
SourceLocation ModulePrivateLoc,
5843
- CXXScopeSpec &SS,
5844
- TemplateTy TemplateD,
5845
- SourceLocation TemplateNameLoc,
5846
- SourceLocation LAngleLoc,
5847
- ASTTemplateArgsPtr TemplateArgsIn,
5848
- SourceLocation RAngleLoc,
5879
+ TemplateIdAnnotation &TemplateId,
5849
5880
AttributeList *Attr,
5850
5881
MultiTemplateParamsArg TemplateParameterLists) {
5851
5882
assert(TUK != TUK_Reference && "References are not specializations");
5852
5883
5884
+ CXXScopeSpec &SS = TemplateId.SS;
5885
+
5853
5886
// NOTE: KWLoc is the location of the tag keyword. This will instead
5854
5887
// store the location of the outermost template keyword in the declaration.
5855
5888
SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0
5856
- ? TemplateParameterLists[0]->getTemplateLoc() : SourceLocation();
5889
+ ? TemplateParameterLists[0]->getTemplateLoc() : KWLoc;
5890
+ SourceLocation TemplateNameLoc = TemplateId.TemplateNameLoc;
5891
+ SourceLocation LAngleLoc = TemplateId.LAngleLoc;
5892
+ SourceLocation RAngleLoc = TemplateId.RAngleLoc;
5857
5893
5858
5894
// Find the class template we're specializing
5859
- TemplateName Name = TemplateD .get();
5895
+ TemplateName Name = TemplateId.Template .get();
5860
5896
ClassTemplateDecl *ClassTemplate
5861
5897
= dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl());
5862
5898
@@ -5877,8 +5913,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
5877
5913
bool Invalid = false;
5878
5914
TemplateParameterList *TemplateParams =
5879
5915
MatchTemplateParametersToScopeSpecifier(
5880
- TemplateNameLoc, TemplateNameLoc, SS, TemplateParameterLists,
5881
- TUK == TUK_Friend, isExplicitSpecialization, Invalid);
5916
+ KWLoc, TemplateNameLoc, SS, &TemplateId,
5917
+ TemplateParameterLists, TUK == TUK_Friend, isExplicitSpecialization,
5918
+ Invalid);
5882
5919
if (Invalid)
5883
5920
return true;
5884
5921
@@ -5929,11 +5966,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
5929
5966
<< SourceRange(LAngleLoc, RAngleLoc);
5930
5967
else
5931
5968
isExplicitSpecialization = true;
5932
- } else if (TUK != TUK_Friend) {
5933
- Diag(KWLoc, diag::err_template_spec_needs_header)
5934
- << FixItHint::CreateInsertion(KWLoc, "template<> ");
5935
- TemplateKWLoc = KWLoc;
5936
- isExplicitSpecialization = true;
5969
+ } else {
5970
+ assert(TUK == TUK_Friend && "should have a 'template<>' for this decl");
5937
5971
}
5938
5972
5939
5973
// Check that the specialization uses the same tag kind as the
@@ -5953,10 +5987,8 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
5953
5987
}
5954
5988
5955
5989
// Translate the parser's template argument list in our AST format.
5956
- TemplateArgumentListInfo TemplateArgs;
5957
- TemplateArgs.setLAngleLoc(LAngleLoc);
5958
- TemplateArgs.setRAngleLoc(RAngleLoc);
5959
- translateTemplateArguments(TemplateArgsIn, TemplateArgs);
5990
+ TemplateArgumentListInfo TemplateArgs =
5991
+ makeTemplateArgumentListInfo(*this, TemplateId);
5960
5992
5961
5993
// Check for unexpanded parameter packs in any of the template arguments.
5962
5994
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
@@ -7416,13 +7448,8 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
7416
7448
}
7417
7449
7418
7450
// Translate the parser's template argument list into our AST format.
7419
- TemplateArgumentListInfo TemplateArgs;
7420
- TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
7421
- TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
7422
- TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
7423
- ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
7424
- TemplateId->NumArgs);
7425
- translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
7451
+ TemplateArgumentListInfo TemplateArgs =
7452
+ makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
7426
7453
7427
7454
DeclResult Res = CheckVarTemplateId(PrevTemplate, TemplateLoc,
7428
7455
D.getIdentifierLoc(), TemplateArgs);
@@ -7492,12 +7519,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
7492
7519
bool HasExplicitTemplateArgs = false;
7493
7520
TemplateArgumentListInfo TemplateArgs;
7494
7521
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
7495
- TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
7496
- TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
7497
- TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
7498
- ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
7499
- TemplateId->NumArgs);
7500
- translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
7522
+ TemplateArgs = makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
7501
7523
HasExplicitTemplateArgs = true;
7502
7524
}
7503
7525
0 commit comments