aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2024-05-07 13:02:17 -0700
committerAdrian Prantl <aprantl@apple.com>2024-05-07 13:03:14 -0700
commitc6855ab24e63feb432aac4f86eb70ac16d76c921 (patch)
treed9c3f525aac1bb609dffce6f664b3a56ae9822fa /clang/lib
parent2e4abfae57f81e2bb23fc654d6edbaeae51ae10a (diff)
downloadllvm-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.cpp68
-rw-r--r--clang/lib/AST/DeclPrinter.cpp18
-rw-r--r--clang/lib/AST/DeclTemplate.cpp198
-rw-r--r--clang/lib/AST/TypePrinter.cpp25
-rw-r--r--clang/lib/Index/IndexDecl.cpp9
-rw-r--r--clang/lib/Sema/Sema.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp54
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp157
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp28
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp36
-rw-r--r--clang/lib/Tooling/Syntax/BuildTree.cpp3
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;
}