diff options
author | Adrian Prantl <aprantl@apple.com> | 2024-05-07 13:02:17 -0700 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2024-05-07 13:03:14 -0700 |
commit | c6855ab24e63feb432aac4f86eb70ac16d76c921 (patch) | |
tree | d9c3f525aac1bb609dffce6f664b3a56ae9822fa /clang/lib | |
parent | 2e4abfae57f81e2bb23fc654d6edbaeae51ae10a (diff) | |
download | llvm-c6855ab24e63feb432aac4f86eb70ac16d76c921.zip llvm-c6855ab24e63feb432aac4f86eb70ac16d76c921.tar.gz llvm-c6855ab24e63feb432aac4f86eb70ac16d76c921.tar.bz2 |
Revert "[Clang] Unify interface for accessing template arguments as written for class/variable template specializations (#81642)"
This reverts commit 7115ed0fff027b65fa76fdfae215ed1382ed1473.
This commit broke several LLDB tests.
https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/3480/
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 68 | ||||
-rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 18 | ||||
-rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 198 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 25 | ||||
-rw-r--r-- | clang/lib/Index/IndexDecl.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 54 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 157 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 28 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 36 | ||||
-rw-r--r-- | clang/lib/Tooling/Syntax/BuildTree.cpp | 3 |
11 files changed, 306 insertions, 292 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 9ff8e1e..60f21332 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -443,9 +443,8 @@ namespace clang { Expected<FunctionTemplateAndArgsTy> ImportFunctionTemplateWithTemplateArgsFromSpecialization( FunctionDecl *FromFD); - - template <typename DeclTy> - Error ImportTemplateParameterLists(const DeclTy *FromD, DeclTy *ToD); + Error ImportTemplateParameterLists(const DeclaratorDecl *FromD, + DeclaratorDecl *ToD); Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD); @@ -3323,9 +3322,8 @@ ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) { return ToEnumerator; } -template <typename DeclTy> -Error ASTNodeImporter::ImportTemplateParameterLists(const DeclTy *FromD, - DeclTy *ToD) { +Error ASTNodeImporter::ImportTemplateParameterLists(const DeclaratorDecl *FromD, + DeclaratorDecl *ToD) { unsigned int Num = FromD->getNumTemplateParameterLists(); if (Num == 0) return Error::success(); @@ -6212,16 +6210,15 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( if (!IdLocOrErr) return IdLocOrErr.takeError(); - // Import TemplateArgumentListInfo. - TemplateArgumentListInfo ToTAInfo; - if (const auto *ASTTemplateArgs = D->getTemplateArgsAsWritten()) { - if (Error Err = ImportTemplateArgumentListInfo(*ASTTemplateArgs, ToTAInfo)) - return std::move(Err); - } - // Create the specialization. ClassTemplateSpecializationDecl *D2 = nullptr; if (PartialSpec) { + // Import TemplateArgumentListInfo. + TemplateArgumentListInfo ToTAInfo; + const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten(); + if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo)) + return std::move(Err); + QualType CanonInjType; if (Error Err = importInto( CanonInjType, PartialSpec->getInjectedSpecializationType())) @@ -6231,7 +6228,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>( D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr, *IdLocOrErr, ToTPList, ClassTemplate, - llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()), + llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()), ToTAInfo, CanonInjType, cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl))) return D2; @@ -6279,27 +6276,28 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( else return BraceRangeOrErr.takeError(); - if (Error Err = ImportTemplateParameterLists(D, D2)) - return std::move(Err); - // Import the qualifier, if any. if (auto LocOrErr = import(D->getQualifierLoc())) D2->setQualifierInfo(*LocOrErr); else return LocOrErr.takeError(); - if (D->getTemplateArgsAsWritten()) - D2->setTemplateArgsAsWritten(ToTAInfo); + if (auto *TSI = D->getTypeAsWritten()) { + if (auto TInfoOrErr = import(TSI)) + D2->setTypeAsWritten(*TInfoOrErr); + else + return TInfoOrErr.takeError(); - if (auto LocOrErr = import(D->getTemplateKeywordLoc())) - D2->setTemplateKeywordLoc(*LocOrErr); - else - return LocOrErr.takeError(); + if (auto LocOrErr = import(D->getTemplateKeywordLoc())) + D2->setTemplateKeywordLoc(*LocOrErr); + else + return LocOrErr.takeError(); - if (auto LocOrErr = import(D->getExternKeywordLoc())) - D2->setExternKeywordLoc(*LocOrErr); - else - return LocOrErr.takeError(); + if (auto LocOrErr = import(D->getExternLoc())) + D2->setExternLoc(*LocOrErr); + else + return LocOrErr.takeError(); + } if (D->getPointOfInstantiation().isValid()) { if (auto POIOrErr = import(D->getPointOfInstantiation())) @@ -6519,7 +6517,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl( VarTemplateSpecializationDecl *D2 = nullptr; TemplateArgumentListInfo ToTAInfo; - if (const auto *Args = D->getTemplateArgsAsWritten()) { + if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) { if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo)) return std::move(Err); } @@ -6527,6 +6525,14 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl( using PartVarSpecDecl = VarTemplatePartialSpecializationDecl; // Create a new specialization. if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) { + // Import TemplateArgumentListInfo + TemplateArgumentListInfo ArgInfos; + const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten(); + // NOTE: FromTAArgsAsWritten and template parameter list are non-null. + if (Error Err = + ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos)) + return std::move(Err); + auto ToTPListOrErr = import(FromPartial->getTemplateParameters()); if (!ToTPListOrErr) return ToTPListOrErr.takeError(); @@ -6535,7 +6541,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl( if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC, *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, VarTemplate, QualType(), nullptr, - D->getStorageClass(), TemplateArgs)) + D->getStorageClass(), TemplateArgs, ArgInfos)) return ToPartial; if (Expected<PartVarSpecDecl *> ToInstOrErr = @@ -6578,9 +6584,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl( } D2->setSpecializationKind(D->getSpecializationKind()); - - if (D->getTemplateArgsAsWritten()) - D2->setTemplateArgsAsWritten(ToTAInfo); + D2->setTemplateArgsInfo(ToTAInfo); if (auto LocOrErr = import(D->getQualifierLoc())) D2->setQualifierInfo(*LocOrErr); diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index c586825..599d379 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -1083,15 +1083,15 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { NNS->print(Out, Policy); Out << *D; - if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateParameterList *TParams = - S->getSpecializedTemplate()->getTemplateParameters(); - const ASTTemplateArgumentListInfo *TArgAsWritten = - S->getTemplateArgsAsWritten(); - if (TArgAsWritten && !Policy.PrintCanonicalTypes) - printTemplateArguments(TArgAsWritten->arguments(), TParams); - else - printTemplateArguments(S->getTemplateArgs().asArray(), TParams); + if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) { + ArrayRef<TemplateArgument> Args = S->getTemplateArgs().asArray(); + if (!Policy.PrintCanonicalTypes) + if (const auto* TSI = S->getTypeAsWritten()) + if (const auto *TST = + dyn_cast<TemplateSpecializationType>(TSI->getType())) + Args = TST->template_arguments(); + printTemplateArguments( + Args, S->getSpecializedTemplate()->getTemplateParameters()); } } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index af2d8d72..d27a30e 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -985,63 +985,41 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const { SourceRange ClassTemplateSpecializationDecl::getSourceRange() const { - if (getSpecializationKind() == TSK_ExplicitInstantiationDeclaration) { - return SourceRange(getExternKeywordLoc(), - getTemplateArgsAsWritten()->getRAngleLoc()); - } else if (getSpecializationKind() == TSK_ExplicitInstantiationDefinition) { - return SourceRange(getTemplateKeywordLoc(), - getTemplateArgsAsWritten()->getRAngleLoc()); - } else if (!isExplicitSpecialization()) { + if (ExplicitInfo) { + SourceLocation Begin = getTemplateKeywordLoc(); + if (Begin.isValid()) { + // Here we have an explicit (partial) specialization or instantiation. + assert(getSpecializationKind() == TSK_ExplicitSpecialization || + getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || + getSpecializationKind() == TSK_ExplicitInstantiationDefinition); + if (getExternLoc().isValid()) + Begin = getExternLoc(); + SourceLocation End = getBraceRange().getEnd(); + if (End.isInvalid()) + End = getTypeAsWritten()->getTypeLoc().getEndLoc(); + return SourceRange(Begin, End); + } + // An implicit instantiation of a class template partial specialization + // uses ExplicitInfo to record the TypeAsWritten, but the source + // locations should be retrieved from the instantiation pattern. + using CTPSDecl = ClassTemplatePartialSpecializationDecl; + auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this)); + CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); + assert(inst_from != nullptr); + return inst_from->getSourceRange(); + } + else { // No explicit info available. llvm::PointerUnion<ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *> - InstFrom = getInstantiatedFrom(); - if (InstFrom.isNull()) + inst_from = getInstantiatedFrom(); + if (inst_from.isNull()) return getSpecializedTemplate()->getSourceRange(); - if (const auto *CTD = InstFrom.dyn_cast<ClassTemplateDecl *>()) - return CTD->getSourceRange(); - return InstFrom.get<ClassTemplatePartialSpecializationDecl *>() - ->getSourceRange(); - } - SourceLocation Begin = TagDecl::getOuterLocStart(); - if (const auto *CTPSD = - dyn_cast<ClassTemplatePartialSpecializationDecl>(this)) { - if (const auto *InstFrom = CTPSD->getInstantiatedFromMember()) - return InstFrom->getSourceRange(); - else if (!getNumTemplateParameterLists()) - Begin = CTPSD->getTemplateParameters()->getTemplateLoc(); - } - SourceLocation End = getBraceRange().getEnd(); - if (End.isInvalid()) - End = getTemplateArgsAsWritten()->getRAngleLoc(); - return SourceRange(Begin, End); -} - -void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); - if (!Info) { - // Don't allocate if the location is invalid. - if (Loc.isInvalid()) - return; - Info = new (getASTContext()) ExplicitInstantiationInfo; - Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); - ExplicitInfo = Info; + if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>()) + return ctd->getSourceRange(); + return inst_from.get<ClassTemplatePartialSpecializationDecl *>() + ->getSourceRange(); } - Info->ExternKeywordLoc = Loc; -} - -void ClassTemplateSpecializationDecl::setTemplateKeywordLoc( - SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); - if (!Info) { - // Don't allocate if the location is invalid. - if (Loc.isInvalid()) - return; - Info = new (getASTContext()) ExplicitInstantiationInfo; - Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); - ExplicitInfo = Info; - } - Info->TemplateKeywordLoc = Loc; } //===----------------------------------------------------------------------===// @@ -1109,29 +1087,43 @@ void ImplicitConceptSpecializationDecl::setTemplateArguments( //===----------------------------------------------------------------------===// void ClassTemplatePartialSpecializationDecl::anchor() {} -ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl( - ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, TemplateParameterList *Params, - ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, - ClassTemplatePartialSpecializationDecl *PrevDecl) - : ClassTemplateSpecializationDecl( - Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc, - SpecializedTemplate, Args, PrevDecl), - TemplateParams(Params), InstantiatedFromMember(nullptr, false) { +ClassTemplatePartialSpecializationDecl:: +ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, + DeclContext *DC, + SourceLocation StartLoc, + SourceLocation IdLoc, + TemplateParameterList *Params, + ClassTemplateDecl *SpecializedTemplate, + ArrayRef<TemplateArgument> Args, + const ASTTemplateArgumentListInfo *ArgInfos, + ClassTemplatePartialSpecializationDecl *PrevDecl) + : ClassTemplateSpecializationDecl(Context, + ClassTemplatePartialSpecialization, + TK, DC, StartLoc, IdLoc, + SpecializedTemplate, Args, PrevDecl), + TemplateParams(Params), ArgsAsWritten(ArgInfos), + InstantiatedFromMember(nullptr, false) { if (AdoptTemplateParameterList(Params, this)) setInvalidDecl(); } ClassTemplatePartialSpecializationDecl * -ClassTemplatePartialSpecializationDecl::Create( - ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, - SourceLocation IdLoc, TemplateParameterList *Params, - ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, - QualType CanonInjectedType, - ClassTemplatePartialSpecializationDecl *PrevDecl) { - auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl( - Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args, - PrevDecl); +ClassTemplatePartialSpecializationDecl:: +Create(ASTContext &Context, TagKind TK,DeclContext *DC, + SourceLocation StartLoc, SourceLocation IdLoc, + TemplateParameterList *Params, + ClassTemplateDecl *SpecializedTemplate, + ArrayRef<TemplateArgument> Args, + const TemplateArgumentListInfo &ArgInfos, + QualType CanonInjectedType, + ClassTemplatePartialSpecializationDecl *PrevDecl) { + const ASTTemplateArgumentListInfo *ASTArgInfos = + ASTTemplateArgumentListInfo::Create(Context, ArgInfos); + + auto *Result = new (Context, DC) + ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, + Params, SpecializedTemplate, Args, + ASTArgInfos, PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1379,47 +1371,26 @@ VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { return SpecializedTemplate.get<VarTemplateDecl *>(); } +void VarTemplateSpecializationDecl::setTemplateArgsInfo( + const TemplateArgumentListInfo &ArgsInfo) { + TemplateArgsInfo = + ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo); +} + +void VarTemplateSpecializationDecl::setTemplateArgsInfo( + const ASTTemplateArgumentListInfo *ArgsInfo) { + TemplateArgsInfo = + ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo); +} + SourceRange VarTemplateSpecializationDecl::getSourceRange() const { if (isExplicitSpecialization() && !hasInit()) { - if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten()) + if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo()) return SourceRange(getOuterLocStart(), Info->getRAngleLoc()); - } else if (getTemplateSpecializationKind() == - TSK_ExplicitInstantiationDeclaration) { - if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten()) - return SourceRange(getExternKeywordLoc(), Info->getRAngleLoc()); - } else if (getTemplateSpecializationKind() == - TSK_ExplicitInstantiationDefinition) { - if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten()) - return SourceRange(getTemplateKeywordLoc(), Info->getRAngleLoc()); } return VarDecl::getSourceRange(); } -void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); - if (!Info) { - // Don't allocate if the location is invalid. - if (Loc.isInvalid()) - return; - Info = new (getASTContext()) ExplicitInstantiationInfo; - Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); - ExplicitInfo = Info; - } - Info->ExternKeywordLoc = Loc; -} - -void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) { - auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); - if (!Info) { - // Don't allocate if the location is invalid. - if (Loc.isInvalid()) - return; - Info = new (getASTContext()) ExplicitInstantiationInfo; - Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); - ExplicitInfo = Info; - } - Info->TemplateKeywordLoc = Loc; -} //===----------------------------------------------------------------------===// // VarTemplatePartialSpecializationDecl Implementation @@ -1431,11 +1402,13 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, ArrayRef<TemplateArgument> Args) + StorageClass S, ArrayRef<TemplateArgument> Args, + const ASTTemplateArgumentListInfo *ArgInfos) : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, DC, StartLoc, IdLoc, SpecializedTemplate, T, TInfo, S, Args), - TemplateParams(Params), InstantiatedFromMember(nullptr, false) { + TemplateParams(Params), ArgsAsWritten(ArgInfos), + InstantiatedFromMember(nullptr, false) { if (AdoptTemplateParameterList(Params, DC)) setInvalidDecl(); } @@ -1445,10 +1418,15 @@ VarTemplatePartialSpecializationDecl::Create( ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, ArrayRef<TemplateArgument> Args) { - auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl( - Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S, - Args); + StorageClass S, ArrayRef<TemplateArgument> Args, + const TemplateArgumentListInfo &ArgInfos) { + const ASTTemplateArgumentListInfo *ASTArgInfos + = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); + + auto *Result = + new (Context, DC) VarTemplatePartialSpecializationDecl( + Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, + S, Args, ASTArgInfos); Result->setSpecializationKind(TSK_ExplicitSpecialization); return Result; } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 87f0a87..9602f44 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1472,18 +1472,21 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) { // If this is a class template specialization, print the template // arguments. - if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) { - const TemplateParameterList *TParams = - S->getSpecializedTemplate()->getTemplateParameters(); - const ASTTemplateArgumentListInfo *TArgAsWritten = - S->getTemplateArgsAsWritten(); + if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) { + ArrayRef<TemplateArgument> Args; + TypeSourceInfo *TAW = Spec->getTypeAsWritten(); + if (!Policy.PrintCanonicalTypes && TAW) { + const TemplateSpecializationType *TST = + cast<TemplateSpecializationType>(TAW->getType()); + Args = TST->template_arguments(); + } else { + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + Args = TemplateArgs.asArray(); + } IncludeStrongLifetimeRAII Strong(Policy); - if (TArgAsWritten && !Policy.PrintCanonicalTypes) - printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy, - TParams); - else - printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy, - TParams); + printTemplateArgumentList( + OS, Args, Policy, + Spec->getSpecializedTemplate()->getTemplateParameters()); } spaceBeforePlaceHolder(OS); diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index 8eb88f5..1c04aa1 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -673,12 +673,9 @@ public: IndexCtx.indexTagDecl( D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf), SpecializationOf)); - // Template specialization arguments. - if (const ASTTemplateArgumentListInfo *TemplateArgInfo = - D->getTemplateArgsAsWritten()) { - for (const auto &Arg : TemplateArgInfo->arguments()) - handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext()); - } + if (TypeSourceInfo *TSI = D->getTypeAsWritten()) + IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr, + D->getLexicalDeclContext()); return true; } diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 0febf4e..a1e32d3 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1408,7 +1408,7 @@ void Sema::ActOnEndOfTranslationUnit() { SourceRange DiagRange = DiagD->getLocation(); if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(DiagD)) { if (const ASTTemplateArgumentListInfo *ASTTAL = - VTSD->getTemplateArgsAsWritten()) + VTSD->getTemplateArgsInfo()) DiagRange.setEnd(ASTTAL->RAngleLoc); } if (DiagD->isReferenced()) { diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index b268d7c..5c72270 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5166,8 +5166,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( VarTemplatePartialSpecializationDecl::Create( Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc, TemplateParams, VarTemplate, DI->getType(), DI, SC, - CanonicalConverted); - Partial->setTemplateArgsAsWritten(TemplateArgs); + CanonicalConverted, TemplateArgs); if (!PrevPartial) VarTemplate->AddPartialSpecialization(Partial, InsertPos); @@ -5185,7 +5184,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( Specialization = VarTemplateSpecializationDecl::Create( Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc, VarTemplate, DI->getType(), DI, SC, CanonicalConverted); - Specialization->setTemplateArgsAsWritten(TemplateArgs); + Specialization->setTemplateArgsInfo(TemplateArgs); if (!PrevDecl) VarTemplate->AddSpecialization(Specialization, InsertPos); @@ -5220,6 +5219,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization( } } + Specialization->setTemplateKeywordLoc(TemplateKWLoc); Specialization->setLexicalDeclContext(CurContext); // Add the specialization into its lexical context, so that it can @@ -9489,8 +9489,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( ClassTemplatePartialSpecializationDecl::Create( Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc, TemplateParams, ClassTemplate, CanonicalConverted, - CanonType, PrevPartial); - Partial->setTemplateArgsAsWritten(TemplateArgs); + TemplateArgs, CanonType, PrevPartial); SetNestedNameSpecifier(*this, Partial, SS); if (TemplateParameterLists.size() > 1 && SS.isSet()) { Partial->setTemplateParameterListsInfo( @@ -9513,7 +9512,6 @@ DeclResult Sema::ActOnClassTemplateSpecialization( Specialization = ClassTemplateSpecializationDecl::Create( Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc, ClassTemplate, CanonicalConverted, PrevDecl); - Specialization->setTemplateArgsAsWritten(TemplateArgs); SetNestedNameSpecifier(*this, Specialization, SS); if (TemplateParameterLists.size() > 0) { Specialization->setTemplateParameterListsInfo(Context, @@ -9597,6 +9595,21 @@ DeclResult Sema::ActOnClassTemplateSpecialization( << (isPartialSpecialization? 1 : 0) << FixItHint::CreateRemoval(ModulePrivateLoc); + // Build the fully-sugared type for this class template + // specialization as the user wrote in the specialization + // itself. This means that we'll pretty-print the type retrieved + // from the specialization's declaration the way that the user + // actually wrote the specialization, rather than formatting the + // name based on the "canonical" representation used to store the + // template arguments in the specialization. + TypeSourceInfo *WrittenTy + = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc, + TemplateArgs, CanonType); + if (TUK != TUK_Friend) { + Specialization->setTypeAsWritten(WrittenTy); + Specialization->setTemplateKeywordLoc(TemplateKWLoc); + } + // C++ [temp.expl.spec]p9: // A template explicit specialization is in the scope of the // namespace in which the template was defined. @@ -9612,15 +9625,6 @@ DeclResult Sema::ActOnClassTemplateSpecialization( Specialization->startDefinition(); if (TUK == TUK_Friend) { - // Build the fully-sugared type for this class template - // specialization as the user wrote in the specialization - // itself. This means that we'll pretty-print the type retrieved - // from the specialization's declaration the way that the user - // actually wrote the specialization, rather than formatting the - // name based on the "canonical" representation used to store the - // template arguments in the specialization. - TypeSourceInfo *WrittenTy = Context.getTemplateSpecializationTypeInfo( - Name, TemplateNameLoc, TemplateArgs, CanonType); FriendDecl *Friend = FriendDecl::Create(Context, CurContext, TemplateNameLoc, WrittenTy, @@ -10826,10 +10830,21 @@ DeclResult Sema::ActOnExplicitInstantiation( } } - Specialization->setTemplateArgsAsWritten(TemplateArgs); + // Build the fully-sugared type for this explicit instantiation as + // the user wrote in the explicit instantiation itself. This means + // that we'll pretty-print the type retrieved from the + // specialization's declaration the way that the user actually wrote + // the explicit instantiation, rather than formatting the name based + // on the "canonical" representation used to store the template + // arguments in the specialization. + TypeSourceInfo *WrittenTy + = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc, + TemplateArgs, + Context.getTypeDeclType(Specialization)); + Specialization->setTypeAsWritten(WrittenTy); // Set source locations for keywords. - Specialization->setExternKeywordLoc(ExternLoc); + Specialization->setExternLoc(ExternLoc); Specialization->setTemplateKeywordLoc(TemplateLoc); Specialization->setBraceRange(SourceRange()); @@ -11242,11 +11257,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S, if (!HasNoEffect) { // Instantiate static data member or variable template. Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); - if (auto *VTSD = dyn_cast<VarTemplatePartialSpecializationDecl>(Prev)) { - VTSD->setExternKeywordLoc(ExternLoc); - VTSD->setTemplateKeywordLoc(TemplateLoc); - } - // Merge attributes. ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes()); if (PrevTemplate) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5315b14..d544cfa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3858,16 +3858,15 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( // Substitute into the template arguments of the class template explicit // specialization. - TemplateArgumentListInfo InstTemplateArgs; - if (const ASTTemplateArgumentListInfo *TemplateArgsInfo = - D->getTemplateArgsAsWritten()) { - InstTemplateArgs.setLAngleLoc(TemplateArgsInfo->getLAngleLoc()); - InstTemplateArgs.setRAngleLoc(TemplateArgsInfo->getRAngleLoc()); - - if (SemaRef.SubstTemplateArguments(TemplateArgsInfo->arguments(), - TemplateArgs, InstTemplateArgs)) - return nullptr; - } + TemplateSpecializationTypeLoc Loc = D->getTypeAsWritten()->getTypeLoc(). + castAs<TemplateSpecializationTypeLoc>(); + TemplateArgumentListInfo InstTemplateArgs(Loc.getLAngleLoc(), + Loc.getRAngleLoc()); + SmallVector<TemplateArgumentLoc, 4> ArgLocs; + for (unsigned I = 0; I != Loc.getNumArgs(); ++I) + ArgLocs.push_back(Loc.getArgLoc(I)); + if (SemaRef.SubstTemplateArguments(ArgLocs, TemplateArgs, InstTemplateArgs)) + return nullptr; // Check that the template argument list is well-formed for this // class template. @@ -3921,7 +3920,6 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( ClassTemplateSpecializationDecl::Create( SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(), D->getLocation(), InstClassTemplate, CanonicalConverted, PrevDecl); - InstD->setTemplateArgsAsWritten(InstTemplateArgs); // Add this partial specialization to the set of class template partial // specializations. @@ -3938,10 +3936,22 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl( TemplateName(InstClassTemplate), CanonicalConverted, SemaRef.Context.getRecordType(InstD)); + // Build the fully-sugared type for this class template + // specialization as the user wrote in the specialization + // itself. This means that we'll pretty-print the type retrieved + // from the specialization's declaration the way that the user + // actually wrote the specialization, rather than formatting the + // name based on the "canonical" representation used to store the + // template arguments in the specialization. + TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo( + TemplateName(InstClassTemplate), D->getLocation(), InstTemplateArgs, + CanonType); + InstD->setAccess(D->getAccess()); InstD->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation); InstD->setSpecializationKind(D->getSpecializationKind()); - InstD->setExternKeywordLoc(D->getExternKeywordLoc()); + InstD->setTypeAsWritten(WrittenTy); + InstD->setExternLoc(D->getExternLoc()); InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc()); Owner->addDecl(InstD); @@ -3975,7 +3985,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( // Substitute the current template arguments. if (const ASTTemplateArgumentListInfo *TemplateArgsInfo = - D->getTemplateArgsAsWritten()) { + D->getTemplateArgsInfo()) { VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc()); VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc()); @@ -4033,7 +4043,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl( VarTemplateSpecializationDecl *Var = VarTemplateSpecializationDecl::Create( SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(), VarTemplate, DI->getType(), DI, D->getStorageClass(), Converted); - Var->setTemplateArgsAsWritten(TemplateArgsInfo); + Var->setTemplateArgsInfo(TemplateArgsInfo); if (!PrevDecl) { void *InsertPos = nullptr; VarTemplate->findSpecialization(Converted, InsertPos); @@ -4275,21 +4285,19 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( QualType CanonType = SemaRef.Context.getTemplateSpecializationType( TemplateName(ClassTemplate), CanonicalConverted); - // Create the class template partial specialization declaration. - ClassTemplatePartialSpecializationDecl *InstPartialSpec = - ClassTemplatePartialSpecializationDecl::Create( - SemaRef.Context, PartialSpec->getTagKind(), Owner, - PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams, - ClassTemplate, CanonicalConverted, CanonType, - /*PrevDecl=*/nullptr); - - InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs); - - // Substitute the nested name specifier, if any. - if (SubstQualifier(PartialSpec, InstPartialSpec)) - return nullptr; - - InstPartialSpec->setInstantiatedFromMember(PartialSpec); + // Build the fully-sugared type for this class template + // specialization as the user wrote in the specialization + // itself. This means that we'll pretty-print the type retrieved + // from the specialization's declaration the way that the user + // actually wrote the specialization, rather than formatting the + // name based on the "canonical" representation used to store the + // template arguments in the specialization. + TypeSourceInfo *WrittenTy + = SemaRef.Context.getTemplateSpecializationTypeInfo( + TemplateName(ClassTemplate), + PartialSpec->getLocation(), + InstTemplateArgs, + CanonType); if (PrevDecl) { // We've already seen a partial specialization with the same template @@ -4307,14 +4315,28 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // // Outer<int, int> outer; // error: the partial specializations of Inner // // have the same signature. - SemaRef.Diag(InstPartialSpec->getLocation(), - diag::err_partial_spec_redeclared) - << InstPartialSpec; + SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared) + << WrittenTy->getType(); SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here) << SemaRef.Context.getTypeDeclType(PrevDecl); return nullptr; } + + // Create the class template partial specialization declaration. + ClassTemplatePartialSpecializationDecl *InstPartialSpec = + ClassTemplatePartialSpecializationDecl::Create( + SemaRef.Context, PartialSpec->getTagKind(), Owner, + PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams, + ClassTemplate, CanonicalConverted, InstTemplateArgs, CanonType, + nullptr); + // Substitute the nested name specifier, if any. + if (SubstQualifier(PartialSpec, InstPartialSpec)) + return nullptr; + + InstPartialSpec->setInstantiatedFromMember(PartialSpec); + InstPartialSpec->setTypeAsWritten(WrittenTy); + // Check the completed partial specialization. SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec); @@ -4383,6 +4405,46 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( VarTemplate->findPartialSpecialization(CanonicalConverted, InstParams, InsertPos); + // Build the canonical type that describes the converted template + // arguments of the variable template partial specialization. + QualType CanonType = SemaRef.Context.getTemplateSpecializationType( + TemplateName(VarTemplate), CanonicalConverted); + + // Build the fully-sugared type for this variable template + // specialization as the user wrote in the specialization + // itself. This means that we'll pretty-print the type retrieved + // from the specialization's declaration the way that the user + // actually wrote the specialization, rather than formatting the + // name based on the "canonical" representation used to store the + // template arguments in the specialization. + TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo( + TemplateName(VarTemplate), PartialSpec->getLocation(), InstTemplateArgs, + CanonType); + + if (PrevDecl) { + // We've already seen a partial specialization with the same template + // parameters and template arguments. This can happen, for example, when + // substituting the outer template arguments ends up causing two + // variable template partial specializations of a member variable template + // to have identical forms, e.g., + // + // template<typename T, typename U> + // struct Outer { + // template<typename X, typename Y> pair<X,Y> p; + // template<typename Y> pair<T, Y> p; + // template<typename Y> pair<U, Y> p; + // }; + // + // Outer<int, int> outer; // error: the partial specializations of Inner + // // have the same signature. + SemaRef.Diag(PartialSpec->getLocation(), + diag::err_var_partial_spec_redeclared) + << WrittenTy->getType(); + SemaRef.Diag(PrevDecl->getLocation(), + diag::note_var_prev_partial_spec_here); + return nullptr; + } + // Do substitution on the type of the declaration TypeSourceInfo *DI = SemaRef.SubstType( PartialSpec->getTypeSourceInfo(), TemplateArgs, @@ -4402,39 +4464,16 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization( VarTemplatePartialSpecializationDecl::Create( SemaRef.Context, Owner, PartialSpec->getInnerLocStart(), PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(), - DI, PartialSpec->getStorageClass(), CanonicalConverted); - - InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs); + DI, PartialSpec->getStorageClass(), CanonicalConverted, + InstTemplateArgs); // Substitute the nested name specifier, if any. if (SubstQualifier(PartialSpec, InstPartialSpec)) return nullptr; InstPartialSpec->setInstantiatedFromMember(PartialSpec); + InstPartialSpec->setTypeAsWritten(WrittenTy); - if (PrevDecl) { - // We've already seen a partial specialization with the same template - // parameters and template arguments. This can happen, for example, when - // substituting the outer template arguments ends up causing two - // variable template partial specializations of a member variable template - // to have identical forms, e.g., - // - // template<typename T, typename U> - // struct Outer { - // template<typename X, typename Y> pair<X,Y> p; - // template<typename Y> pair<T, Y> p; - // template<typename Y> pair<U, Y> p; - // }; - // - // Outer<int, int> outer; // error: the partial specializations of Inner - // // have the same signature. - SemaRef.Diag(PartialSpec->getLocation(), - diag::err_var_partial_spec_redeclared) - << InstPartialSpec; - SemaRef.Diag(PrevDecl->getLocation(), - diag::note_var_prev_partial_spec_here); - return nullptr; - } // Check the completed partial specialization. SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec); @@ -5696,7 +5735,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, TemplateArgumentListInfo TemplateArgInfo; if (const ASTTemplateArgumentListInfo *ArgInfo = - VarSpec->getTemplateArgsAsWritten()) { + VarSpec->getTemplateArgsInfo()) { TemplateArgInfo.setLAngleLoc(ArgInfo->getLAngleLoc()); TemplateArgInfo.setRAngleLoc(ArgInfo->getRAngleLoc()); for (const TemplateArgumentLoc &Arg : ArgInfo->arguments()) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 0c647086..089ede4 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2548,17 +2548,16 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( } } - // extern/template keyword locations for explicit instantiations - if (Record.readBool()) { - auto *ExplicitInfo = new (C) ExplicitInstantiationInfo; - ExplicitInfo->ExternKeywordLoc = readSourceLocation(); + // Explicit info. + if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) { + auto *ExplicitInfo = + new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = TyInfo; + ExplicitInfo->ExternLoc = readSourceLocation(); ExplicitInfo->TemplateKeywordLoc = readSourceLocation(); D->ExplicitInfo = ExplicitInfo; } - if (Record.readBool()) - D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo()); - return Redecl; } @@ -2568,6 +2567,7 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl( // need them for profiling TemplateParameterList *Params = Record.readTemplateParameterList(); D->TemplateParams = Params; + D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D); @@ -2617,17 +2617,16 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( } } - // extern/template keyword locations for explicit instantiations - if (Record.readBool()) { - auto *ExplicitInfo = new (C) ExplicitInstantiationInfo; - ExplicitInfo->ExternKeywordLoc = readSourceLocation(); + // Explicit info. + if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) { + auto *ExplicitInfo = + new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo; + ExplicitInfo->TypeAsWritten = TyInfo; + ExplicitInfo->ExternLoc = readSourceLocation(); ExplicitInfo->TemplateKeywordLoc = readSourceLocation(); D->ExplicitInfo = ExplicitInfo; } - if (Record.readBool()) - D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo()); - SmallVector<TemplateArgument, 8> TemplArgs; Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs); @@ -2667,6 +2666,7 @@ void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl( VarTemplatePartialSpecializationDecl *D) { TemplateParameterList *Params = Record.readTemplateParameterList(); D->TemplateParams = Params; + D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo(); RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index c2f1d1b..6201d28 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1765,28 +1765,20 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl()); } - bool ExplicitInstantiation = - D->getTemplateSpecializationKind() == - TSK_ExplicitInstantiationDeclaration || - D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; - Record.push_back(ExplicitInstantiation); - if (ExplicitInstantiation) { - Record.AddSourceLocation(D->getExternKeywordLoc()); + // Explicit info. + Record.AddTypeSourceInfo(D->getTypeAsWritten()); + if (D->getTypeAsWritten()) { + Record.AddSourceLocation(D->getExternLoc()); Record.AddSourceLocation(D->getTemplateKeywordLoc()); } - const ASTTemplateArgumentListInfo *ArgsWritten = - D->getTemplateArgsAsWritten(); - Record.push_back(!!ArgsWritten); - if (ArgsWritten) - Record.AddASTTemplateArgumentListInfo(ArgsWritten); - Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION; } void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl( ClassTemplatePartialSpecializationDecl *D) { Record.AddTemplateParameterList(D->getTemplateParameters()); + Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten()); VisitClassTemplateSpecializationDecl(D); @@ -1820,22 +1812,13 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl( Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs()); } - bool ExplicitInstantiation = - D->getTemplateSpecializationKind() == - TSK_ExplicitInstantiationDeclaration || - D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition; - Record.push_back(ExplicitInstantiation); - if (ExplicitInstantiation) { - Record.AddSourceLocation(D->getExternKeywordLoc()); + // Explicit info. + Record.AddTypeSourceInfo(D->getTypeAsWritten()); + if (D->getTypeAsWritten()) { + Record.AddSourceLocation(D->getExternLoc()); Record.AddSourceLocation(D->getTemplateKeywordLoc()); } - const ASTTemplateArgumentListInfo *ArgsWritten = - D->getTemplateArgsAsWritten(); - Record.push_back(!!ArgsWritten); - if (ArgsWritten) - Record.AddASTTemplateArgumentListInfo(ArgsWritten); - Record.AddTemplateArgumentList(&D->getTemplateArgs()); Record.AddSourceLocation(D->getPointOfInstantiation()); Record.push_back(D->getSpecializationKind()); @@ -1856,6 +1839,7 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl( void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl( VarTemplatePartialSpecializationDecl *D) { Record.AddTemplateParameterList(D->getTemplateParameters()); + Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten()); VisitVarTemplateSpecializationDecl(D); diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp index 3e50d67f..cd02619 100644 --- a/clang/lib/Tooling/Syntax/BuildTree.cpp +++ b/clang/lib/Tooling/Syntax/BuildTree.cpp @@ -735,8 +735,7 @@ public: auto *Declaration = cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C)); foldExplicitTemplateInstantiation( - Builder.getTemplateRange(C), - Builder.findToken(C->getExternKeywordLoc()), + Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()), Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C); return true; } |