@@ -318,7 +318,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
318318 }
319319 }
320320
321- if (isPackProducingBuiltinTemplateName (Template) && S &&
321+ if (isPackProducingBuiltinTemplateName (Template) &&
322322 S->getTemplateParamParent () == nullptr )
323323 Diag (Name.getBeginLoc (), diag::err_builtin_pack_outside_template) << TName;
324324 // Recover by returning the template, even though we would never be able to
@@ -408,7 +408,9 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope *S, CXXScopeSpec &SS,
408408 IsDependent = !LookupCtx && ObjectType->isDependentType ();
409409 assert ((IsDependent || !ObjectType->isIncompleteType () ||
410410 !ObjectType->getAs <TagType>() ||
411- ObjectType->castAs <TagType>()->getDecl ()->isEntityBeingDefined ()) &&
411+ ObjectType->castAs <TagType>()
412+ ->getOriginalDecl ()
413+ ->isEntityBeingDefined ()) &&
412414 " Caller should have completed object type" );
413415
414416 // Template names cannot appear inside an Objective-C class or object type
@@ -949,11 +951,11 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
949951
950952 switch (Arg.getKind ()) {
951953 case ParsedTemplateArgument::Type: {
952- TypeSourceInfo *TSI ;
953- QualType T = SemaRef.GetTypeFromParser (Arg.getAsType (), &TSI );
954- if (!TSI )
955- TSI = SemaRef.Context .getTrivialTypeSourceInfo (T, Arg.getNameLoc ());
956- return TemplateArgumentLoc (TemplateArgument (T), TSI );
954+ TypeSourceInfo *DI ;
955+ QualType T = SemaRef.GetTypeFromParser (Arg.getAsType (), &DI );
956+ if (!DI )
957+ DI = SemaRef.Context .getTrivialTypeSourceInfo (T, Arg.getNameLoc ());
958+ return TemplateArgumentLoc (TemplateArgument (T), DI );
957959 }
958960
959961 case ParsedTemplateArgument::NonType: {
@@ -1817,7 +1819,7 @@ class ConstraintRefersToContainingTemplateChecker
18171819 }
18181820
18191821 bool VisitTagType (const TagType *T) override {
1820- return TraverseDecl (T->getDecl ());
1822+ return TraverseDecl (T->getOriginalDecl ());
18211823 }
18221824
18231825 bool TraverseDecl (const Decl *D) override {
@@ -2788,7 +2790,7 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
27882790 // An InjectedClassNameType will never have a dependent template name,
27892791 // so no need to traverse it.
27902792 return TraverseTemplateArguments (
2791- T->getTemplateArgs (T->getDecl ()->getASTContext ()));
2793+ T->getTemplateArgs (T->getOriginalDecl ()->getASTContext ()));
27922794 }
27932795};
27942796} // end anonymous namespace
@@ -2912,7 +2914,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
29122914 if (const EnumType *EnumT = T->getAsCanonical <EnumType>()) {
29132915 // FIXME: Forward-declared enums require a TSK_ExplicitSpecialization
29142916 // check here.
2915- EnumDecl *Enum = EnumT->getDecl ();
2917+ EnumDecl *Enum = EnumT->getOriginalDecl ();
29162918
29172919 // Get to the parent type.
29182920 if (TypeDecl *Parent = dyn_cast<TypeDecl>(Enum->getParent ()))
@@ -3350,7 +3352,7 @@ static QualType builtinCommonTypeImpl(Sema &S, ElaboratedTypeKeyword Keyword,
33503352}
33513353
33523354static bool isInVkNamespace (const RecordType *RT) {
3353- DeclContext *DC = RT->getDecl ()->getDeclContext ();
3355+ DeclContext *DC = RT->getOriginalDecl ()->getDeclContext ();
33543356 if (!DC)
33553357 return false ;
33563358
@@ -3367,8 +3369,9 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
33673369 if (auto *RT = OperandArg->getAsCanonical <RecordType>()) {
33683370 bool Literal = false ;
33693371 SourceLocation LiteralLoc;
3370- if (isInVkNamespace (RT) && RT->getDecl ()->getName () == " Literal" ) {
3371- auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl ());
3372+ if (isInVkNamespace (RT) && RT->getOriginalDecl ()->getName () == " Literal" ) {
3373+ auto SpecDecl =
3374+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl ());
33723375 assert (SpecDecl);
33733376
33743377 const TemplateArgumentList &LiteralArgs = SpecDecl->getTemplateArgs ();
@@ -3379,8 +3382,9 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
33793382 }
33803383
33813384 if (RT && isInVkNamespace (RT) &&
3382- RT->getDecl ()->getName () == " integral_constant" ) {
3383- auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl ());
3385+ RT->getOriginalDecl ()->getName () == " integral_constant" ) {
3386+ auto SpecDecl =
3387+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl ());
33843388 assert (SpecDecl);
33853389
33863390 const TemplateArgumentList &ConstantArgs = SpecDecl->getTemplateArgs ();
@@ -3846,14 +3850,13 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
38463850 // within enable_if in a SFINAE context, dig out the specific
38473851 // enable_if condition that failed and present that instead.
38483852 if (isEnableIfAliasTemplate (AliasTemplate)) {
3849- if (SFINAETrap *Trap = getSFINAEContext ();
3850- TemplateDeductionInfo *DeductionInfo =
3851- Trap ? Trap->getDeductionInfo () : nullptr ) {
3852- if (DeductionInfo->hasSFINAEDiagnostic () &&
3853- DeductionInfo->peekSFINAEDiagnostic ().second .getDiagID () ==
3854- diag::err_typename_nested_not_found_enable_if &&
3855- TemplateArgs[0 ].getArgument ().getKind () ==
3856- TemplateArgument::Expression) {
3853+ if (auto DeductionInfo = isSFINAEContext ()) {
3854+ if (*DeductionInfo &&
3855+ (*DeductionInfo)->hasSFINAEDiagnostic () &&
3856+ (*DeductionInfo)->peekSFINAEDiagnostic ().second .getDiagID () ==
3857+ diag::err_typename_nested_not_found_enable_if &&
3858+ TemplateArgs[0 ].getArgument ().getKind ()
3859+ == TemplateArgument::Expression) {
38573860 Expr *FailedCond;
38583861 std::string FailedDescription;
38593862 std::tie (FailedCond, FailedDescription) =
@@ -3862,14 +3865,15 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
38623865 // Remove the old SFINAE diagnostic.
38633866 PartialDiagnosticAt OldDiag =
38643867 {SourceLocation (), PartialDiagnostic::NullDiagnostic ()};
3865- DeductionInfo->takeSFINAEDiagnostic (OldDiag);
3868+ (* DeductionInfo) ->takeSFINAEDiagnostic (OldDiag);
38663869
38673870 // Add a new SFINAE diagnostic specifying which condition
38683871 // failed.
3869- DeductionInfo->addSFINAEDiagnostic (
3870- OldDiag.first ,
3871- PDiag (diag::err_typename_nested_not_found_requirement)
3872- << FailedDescription << FailedCond->getSourceRange ());
3872+ (*DeductionInfo)->addSFINAEDiagnostic (
3873+ OldDiag.first ,
3874+ PDiag (diag::err_typename_nested_not_found_requirement)
3875+ << FailedDescription
3876+ << FailedCond->getSourceRange ());
38733877 }
38743878 }
38753879 }
@@ -3955,7 +3959,6 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
39553959
39563960 if (Decl->getSpecializationKind () == TSK_Undeclared &&
39573961 ClassTemplate->getTemplatedDecl ()->hasAttrs ()) {
3958- NonSFINAEContext _ (*this );
39593962 InstantiatingTemplate Inst (*this , TemplateLoc, Decl);
39603963 if (!Inst.isInvalid ()) {
39613964 MultiLevelTemplateArgumentList TemplateArgLists (Template,
@@ -4107,7 +4110,7 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
41074110
41084111 // Check the tag kind
41094112 if (const RecordType *RT = Result->getAs <RecordType>()) {
4110- RecordDecl *D = RT->getDecl ();
4113+ RecordDecl *D = RT->getOriginalDecl ();
41114114
41124115 IdentifierInfo *Id = D->getIdentifier ();
41134116 assert (Id && " templated class must have an identifier" );
@@ -4330,7 +4333,7 @@ void Sema::CheckDeductionGuideTemplate(FunctionTemplateDecl *TD) {
43304333}
43314334
43324335DeclResult Sema::ActOnVarTemplateSpecialization (
4333- Scope *S, Declarator &D, TypeSourceInfo *TSI , LookupResult &Previous,
4336+ Scope *S, Declarator &D, TypeSourceInfo *DI , LookupResult &Previous,
43344337 SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
43354338 StorageClass SC, bool IsPartialSpecialization) {
43364339 // D must be variable template id.
@@ -4456,8 +4459,8 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
44564459 VarTemplatePartialSpecializationDecl *Partial =
44574460 VarTemplatePartialSpecializationDecl::Create (
44584461 Context, VarTemplate->getDeclContext (), TemplateKWLoc,
4459- TemplateNameLoc, TemplateParams, VarTemplate, TSI ->getType (), TSI ,
4460- SC, CTAI.CanonicalConverted );
4462+ TemplateNameLoc, TemplateParams, VarTemplate, DI ->getType (), DI, SC ,
4463+ CTAI.CanonicalConverted );
44614464 Partial->setTemplateArgsAsWritten (TemplateArgs);
44624465
44634466 if (!PrevPartial)
@@ -4475,7 +4478,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
44754478 // this explicit specialization or friend declaration.
44764479 Specialization = VarTemplateSpecializationDecl::Create (
44774480 Context, VarTemplate->getDeclContext (), TemplateKWLoc, TemplateNameLoc,
4478- VarTemplate, TSI ->getType (), TSI , SC, CTAI.CanonicalConverted );
4481+ VarTemplate, DI ->getType (), DI , SC, CTAI.CanonicalConverted );
44794482 Specialization->setTemplateArgsAsWritten (TemplateArgs);
44804483
44814484 if (!PrevDecl)
@@ -5566,11 +5569,12 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
55665569
55675570 auto checkExpr = [&](Expr *E) -> Expr * {
55685571 TemplateArgument SugaredResult, CanonicalResult;
5572+ unsigned CurSFINAEErrors = NumSFINAEErrors;
55695573 ExprResult Res = CheckTemplateArgument (
55705574 NTTP, NTTPType, E, SugaredResult, CanonicalResult,
55715575 /* StrictCheck=*/ CTAI.MatchingTTP || CTAI.PartialOrdering , CTAK);
55725576 // If the current template argument causes an error, give up now.
5573- if (Res.isInvalid ())
5577+ if (Res.isInvalid () || CurSFINAEErrors < NumSFINAEErrors )
55745578 return nullptr ;
55755579 CTAI.SugaredConverted .push_back (SugaredResult);
55765580 CTAI.CanonicalConverted .push_back (CanonicalResult);
@@ -6379,11 +6383,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType(
63796383}
63806384
63816385bool UnnamedLocalNoLinkageFinder::VisitRecordType (const RecordType* T) {
6382- return VisitTagDecl (T->getDecl ()->getDefinitionOrSelf ());
6386+ return VisitTagDecl (T->getOriginalDecl ()->getDefinitionOrSelf ());
63836387}
63846388
63856389bool UnnamedLocalNoLinkageFinder::VisitEnumType (const EnumType* T) {
6386- return VisitTagDecl (T->getDecl ()->getDefinitionOrSelf ());
6390+ return VisitTagDecl (T->getOriginalDecl ()->getDefinitionOrSelf ());
63876391}
63886392
63896393bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType (
@@ -6408,7 +6412,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType(
64086412
64096413bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType (
64106414 const InjectedClassNameType* T) {
6411- return VisitTagDecl (T->getDecl ()->getDefinitionOrSelf ());
6415+ return VisitTagDecl (T->getOriginalDecl ()->getDefinitionOrSelf ());
64126416}
64136417
64146418bool UnnamedLocalNoLinkageFinder::VisitDependentNameType (
@@ -8421,7 +8425,7 @@ bool Sema::TemplateParameterListsAreEqual(
84218425 return true ;
84228426}
84238427
8424- bool
8428+ bool
84258429Sema::CheckTemplateDeclScope (Scope *S, TemplateParameterList *TemplateParams) {
84268430 if (!S)
84278431 return false ;
@@ -8445,35 +8449,103 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
84458449 }
84468450 Ctx = Ctx ? Ctx->getRedeclContext () : nullptr ;
84478451
8448- // C++ [temp]p2:
8449- // A template-declaration can appear only as a namespace scope or
8450- // class scope declaration.
8451- // C++ [temp.expl.spec]p3:
8452- // An explicit specialization may be declared in any scope in which the
8453- // corresponding primary template may be defined.
8454- // C++ [temp.class.spec]p6: [P2096]
8455- // A partial specialization may be declared in any scope in which the
8456- // corresponding primary template may be defined.
8452+ // Compute a SourceLocation to use for diagnostics. Prefer the explicit
8453+ // template location, but fall back to nearby Decl locations when needed.
8454+ SourceLocation Loc = TemplateParams->getTemplateLoc ();
8455+ if (Loc.isInvalid ())
8456+ Loc = TemplateParams->getSourceRange ().getBegin ();
8457+
8458+ if (Loc.isInvalid () && Ctx) {
8459+ if (const Decl *D = dyn_cast<Decl>(Ctx))
8460+ Loc = D->getBeginLoc ();
8461+ }
8462+
8463+ CXXRecordDecl *RD = Ctx ? dyn_cast<CXXRecordDecl>(Ctx) : nullptr ;
8464+ if (Loc.isInvalid () && RD)
8465+ Loc = RD->getLocation ();
8466+
84578467 if (Ctx) {
84588468 if (Ctx->isFileContext ())
84598469 return false ;
8460- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx)) {
8470+
8471+ if (RD) {
84618472 // C++ [temp.mem]p2:
84628473 // A local class shall not have member templates.
8463- if (RD->isLocalClass ())
8464- return Diag (TemplateParams->getTemplateLoc (),
8465- diag::err_template_inside_local_class)
8466- << TemplateParams->getSourceRange ();
8467- else
8474+ if (RD->isLocalClass ()) {
8475+ // check if this is an abbreviated function template (C++20 auto params).
8476+ // If so, we want to emit the 'auto not allowed' diagnostic instead.
8477+ bool isAbbrev = false ;
8478+
8479+ // find the enclosing function and check for auto parameters.
8480+ {
8481+ const Decl *d = dyn_cast<Decl>(Ctx);
8482+ const DeclContext *dc = d ? d->getDeclContext () : nullptr ;
8483+ while (dc && !dc->isFunctionOrMethod ())
8484+ dc = dc->getParent ();
8485+
8486+ if (dc && dc->isFunctionOrMethod ()) {
8487+ if (const FunctionDecl *fd = dyn_cast<FunctionDecl>(
8488+ dc->getRedeclContext ()->getPrimaryContext ())) {
8489+ for (const ParmVarDecl *p : fd->parameters ()) {
8490+ if (p && p->getType ()->getAs <AutoType>()) {
8491+ isAbbrev = true ;
8492+ break ;
8493+ }
8494+ }
8495+ }
8496+
8497+ // check function templates in this context.
8498+ if (!isAbbrev) {
8499+ for (Decl *d : dc->decls ()) {
8500+ if (const FunctionTemplateDecl *ftd = dyn_cast<FunctionTemplateDecl>(d)) {
8501+ if (const FunctionDecl *fd = ftd->getTemplatedDecl ()) {
8502+ for (const ParmVarDecl *p : fd->parameters ()) {
8503+ if (p && p->getType ()->getAs <AutoType>()) {
8504+ isAbbrev = true ;
8505+ break ;
8506+ }
8507+ }
8508+ if (isAbbrev) break ;
8509+ }
8510+ }
8511+ }
8512+ }
8513+ }
8514+ }
8515+
8516+ // fallback check methods of the local class itself.
8517+ if (!isAbbrev) {
8518+ for (const CXXMethodDecl *m : RD->methods ()) {
8519+ for (const ParmVarDecl *p : m->parameters ()) {
8520+ if (p && p->getType ()->getAs <AutoType>()) {
8521+ isAbbrev = true ;
8522+ break ;
8523+ }
8524+ }
8525+ if (isAbbrev)
8526+ break ;
8527+ }
8528+ }
8529+
8530+ if (Loc.isInvalid ())
8531+ Loc = TemplateParams->getSourceRange ().getBegin ();
8532+
8533+ if (isAbbrev)
8534+ return Diag (Loc, diag::err_auto_not_allowed);
8535+
8536+ return Diag (Loc, diag::err_template_inside_local_class)
8537+ << TemplateParams->getSourceRange ();
8538+ } else
84688539 return false ;
84698540 }
84708541 }
84718542
8472- return Diag (TemplateParams->getTemplateLoc (),
8473- diag::err_template_outside_namespace_or_class_scope)
8474- << TemplateParams->getSourceRange ();
8475- }
8543+ if (Loc.isInvalid ())
8544+ Loc = TemplateParams->getSourceRange ().getBegin ();
84768545
8546+ return Diag (Loc, diag::err_template_outside_namespace_or_class_scope)
8547+ << TemplateParams->getSourceRange ();
8548+ }
84778549// / Determine what kind of template specialization the given declaration
84788550// / is.
84798551static TemplateSpecializationKind getTemplateSpecializationKind (Decl *D) {
0 commit comments