aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
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.cpp266
-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.cpp58
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp163
-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, 349 insertions, 327 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 60f21332..9ff8e1e 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -443,8 +443,9 @@ namespace clang {
Expected<FunctionTemplateAndArgsTy>
ImportFunctionTemplateWithTemplateArgsFromSpecialization(
FunctionDecl *FromFD);
- Error ImportTemplateParameterLists(const DeclaratorDecl *FromD,
- DeclaratorDecl *ToD);
+
+ template <typename DeclTy>
+ Error ImportTemplateParameterLists(const DeclTy *FromD, DeclTy *ToD);
Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
@@ -3322,8 +3323,9 @@ ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
return ToEnumerator;
}
-Error ASTNodeImporter::ImportTemplateParameterLists(const DeclaratorDecl *FromD,
- DeclaratorDecl *ToD) {
+template <typename DeclTy>
+Error ASTNodeImporter::ImportTemplateParameterLists(const DeclTy *FromD,
+ DeclTy *ToD) {
unsigned int Num = FromD->getNumTemplateParameterLists();
if (Num == 0)
return Error::success();
@@ -6210,15 +6212,16 @@ 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()))
@@ -6228,7 +6231,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr,
*IdLocOrErr, ToTPList, ClassTemplate,
- llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()), ToTAInfo,
+ llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()),
CanonInjType,
cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
return D2;
@@ -6276,28 +6279,27 @@ 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 (auto *TSI = D->getTypeAsWritten()) {
- if (auto TInfoOrErr = import(TSI))
- D2->setTypeAsWritten(*TInfoOrErr);
- else
- return TInfoOrErr.takeError();
+ if (D->getTemplateArgsAsWritten())
+ D2->setTemplateArgsAsWritten(ToTAInfo);
- 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->getExternLoc()))
- D2->setExternLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
- }
+ if (auto LocOrErr = import(D->getExternKeywordLoc()))
+ D2->setExternKeywordLoc(*LocOrErr);
+ else
+ return LocOrErr.takeError();
if (D->getPointOfInstantiation().isValid()) {
if (auto POIOrErr = import(D->getPointOfInstantiation()))
@@ -6517,7 +6519,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
VarTemplateSpecializationDecl *D2 = nullptr;
TemplateArgumentListInfo ToTAInfo;
- if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
+ if (const auto *Args = D->getTemplateArgsAsWritten()) {
if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo))
return std::move(Err);
}
@@ -6525,14 +6527,6 @@ 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();
@@ -6541,7 +6535,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
*BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
VarTemplate, QualType(), nullptr,
- D->getStorageClass(), TemplateArgs, ArgInfos))
+ D->getStorageClass(), TemplateArgs))
return ToPartial;
if (Expected<PartVarSpecDecl *> ToInstOrErr =
@@ -6584,7 +6578,9 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
}
D2->setSpecializationKind(D->getSpecializationKind());
- D2->setTemplateArgsInfo(ToTAInfo);
+
+ if (D->getTemplateArgsAsWritten())
+ D2->setTemplateArgsAsWritten(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 599d379..c586825 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)) {
- 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());
+ 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);
}
}
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index d27a30e..d22ecc3 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -985,41 +985,67 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
SourceRange
ClassTemplateSpecializationDecl::getSourceRange() const {
- 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.
+ switch (getSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation: {
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>
- inst_from = getInstantiatedFrom();
- if (inst_from.isNull())
- return getSpecializedTemplate()->getSourceRange();
- if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
- return ctd->getSourceRange();
- return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
- ->getSourceRange();
+ Pattern = getSpecializedTemplateOrPartial();
+ assert(!Pattern.isNull() &&
+ "Class template specialization without pattern?");
+ if (const auto *CTPSD =
+ Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>())
+ return CTPSD->getSourceRange();
+ return Pattern.get<ClassTemplateDecl *>()->getSourceRange();
+ }
+ case TSK_ExplicitSpecialization: {
+ SourceRange Range = CXXRecordDecl::getSourceRange();
+ if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
+ !isThisDeclarationADefinition() && Args)
+ Range.setEnd(Args->getRAngleLoc());
+ return Range;
+ }
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition: {
+ SourceRange Range = CXXRecordDecl::getSourceRange();
+ if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
+ Range.setBegin(ExternKW);
+ else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
+ TemplateKW.isValid())
+ Range.setBegin(TemplateKW);
+ if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
+ Range.setEnd(Args->getRAngleLoc());
+ return Range;
+ }
}
+ llvm_unreachable("unhandled template specialization kind");
+}
+
+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;
+ }
+ 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;
}
//===----------------------------------------------------------------------===//
@@ -1087,43 +1113,29 @@ 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,
- const ASTTemplateArgumentListInfo *ArgInfos,
- ClassTemplatePartialSpecializationDecl *PrevDecl)
- : ClassTemplateSpecializationDecl(Context,
- ClassTemplatePartialSpecialization,
- TK, DC, StartLoc, IdLoc,
- SpecializedTemplate, Args, PrevDecl),
- TemplateParams(Params), ArgsAsWritten(ArgInfos),
- InstantiatedFromMember(nullptr, false) {
+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) {
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,
- 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);
+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);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
Result->setMayHaveOutOfDateDef(false);
@@ -1139,6 +1151,18 @@ ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
return Result;
}
+SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
+ if (const ClassTemplatePartialSpecializationDecl *MT =
+ getInstantiatedFromMember();
+ MT && !isMemberSpecialization())
+ return MT->getSourceRange();
+ SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange();
+ if (const TemplateParameterList *TPL = getTemplateParameters();
+ TPL && !getNumTemplateParameterLists())
+ Range.setBegin(TPL->getTemplateLoc());
+ return Range;
+}
+
//===----------------------------------------------------------------------===//
// FriendTemplateDecl Implementation
//===----------------------------------------------------------------------===//
@@ -1371,27 +1395,74 @@ 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 = getTemplateArgsInfo())
- return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
+ switch (getSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation: {
+ llvm::PointerUnion<VarTemplateDecl *,
+ VarTemplatePartialSpecializationDecl *>
+ Pattern = getSpecializedTemplateOrPartial();
+ assert(!Pattern.isNull() &&
+ "Variable template specialization without pattern?");
+ if (const auto *VTPSD =
+ Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>())
+ return VTPSD->getSourceRange();
+ VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>();
+ if (hasInit()) {
+ if (VarTemplateDecl *Definition = VTD->getDefinition())
+ return Definition->getSourceRange();
+ }
+ return VTD->getCanonicalDecl()->getSourceRange();
+ }
+ case TSK_ExplicitSpecialization: {
+ SourceRange Range = VarDecl::getSourceRange();
+ if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten();
+ !hasInit() && Args)
+ Range.setEnd(Args->getRAngleLoc());
+ return Range;
+ }
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition: {
+ SourceRange Range = VarDecl::getSourceRange();
+ if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid())
+ Range.setBegin(ExternKW);
+ else if (SourceLocation TemplateKW = getTemplateKeywordLoc();
+ TemplateKW.isValid())
+ Range.setBegin(TemplateKW);
+ if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten())
+ Range.setEnd(Args->getRAngleLoc());
+ return Range;
}
- return VarDecl::getSourceRange();
+ }
+ llvm_unreachable("unhandled template specialization kind");
+}
+
+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
//===----------------------------------------------------------------------===//
@@ -1402,13 +1473,11 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, TemplateParameterList *Params,
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, ArrayRef<TemplateArgument> Args,
- const ASTTemplateArgumentListInfo *ArgInfos)
+ StorageClass S, ArrayRef<TemplateArgument> Args)
: VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
DC, StartLoc, IdLoc, SpecializedTemplate, T,
TInfo, S, Args),
- TemplateParams(Params), ArgsAsWritten(ArgInfos),
- InstantiatedFromMember(nullptr, false) {
+ TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
if (AdoptTemplateParameterList(Params, DC))
setInvalidDecl();
}
@@ -1418,15 +1487,10 @@ VarTemplatePartialSpecializationDecl::Create(
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, TemplateParameterList *Params,
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
- 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);
+ StorageClass S, ArrayRef<TemplateArgument> Args) {
+ auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
+ Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
+ Args);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
return Result;
}
@@ -1438,11 +1502,15 @@ VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
}
SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
- if (isExplicitSpecialization() && !hasInit()) {
- if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
- return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
- }
- return VarDecl::getSourceRange();
+ if (const VarTemplatePartialSpecializationDecl *MT =
+ getInstantiatedFromMember();
+ MT && !isMemberSpecialization())
+ return MT->getSourceRange();
+ SourceRange Range = VarTemplateSpecializationDecl::getSourceRange();
+ if (const TemplateParameterList *TPL = getTemplateParameters();
+ TPL && !getNumTemplateParameterLists())
+ Range.setBegin(TPL->getTemplateLoc());
+ return Range;
}
static TemplateParameterList *
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 9602f44..87f0a87 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1472,21 +1472,18 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
// If this is a class template specialization, print the template
// arguments.
- 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();
- }
+ if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ const TemplateParameterList *TParams =
+ S->getSpecializedTemplate()->getTemplateParameters();
+ const ASTTemplateArgumentListInfo *TArgAsWritten =
+ S->getTemplateArgsAsWritten();
IncludeStrongLifetimeRAII Strong(Policy);
- printTemplateArgumentList(
- OS, Args, Policy,
- Spec->getSpecializedTemplate()->getTemplateParameters());
+ if (TArgAsWritten && !Policy.PrintCanonicalTypes)
+ printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
+ TParams);
+ else
+ printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
+ TParams);
}
spaceBeforePlaceHolder(OS);
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp
index 1c04aa1..8eb88f5 100644
--- a/clang/lib/Index/IndexDecl.cpp
+++ b/clang/lib/Index/IndexDecl.cpp
@@ -673,9 +673,12 @@ public:
IndexCtx.indexTagDecl(
D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
SpecializationOf));
- if (TypeSourceInfo *TSI = D->getTypeAsWritten())
- IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
- D->getLexicalDeclContext());
+ // Template specialization arguments.
+ if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
+ D->getTemplateArgsAsWritten()) {
+ for (const auto &Arg : TemplateArgInfo->arguments())
+ handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
+ }
return true;
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 7585f1c..5d6ce23 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1406,7 +1406,7 @@ void Sema::ActOnEndOfTranslationUnit() {
SourceRange DiagRange = DiagD->getLocation();
if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(DiagD)) {
if (const ASTTemplateArgumentListInfo *ASTTAL =
- VTSD->getTemplateArgsInfo())
+ VTSD->getTemplateArgsAsWritten())
DiagRange.setEnd(ASTTAL->RAngleLoc);
}
if (DiagD->isReferenced()) {
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8219d5e..c7aac06 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5300,7 +5300,8 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
VarTemplatePartialSpecializationDecl::Create(
Context, VarTemplate->getDeclContext(), TemplateKWLoc,
TemplateNameLoc, TemplateParams, VarTemplate, DI->getType(), DI, SC,
- CanonicalConverted, TemplateArgs);
+ CanonicalConverted);
+ Partial->setTemplateArgsAsWritten(TemplateArgs);
if (!PrevPartial)
VarTemplate->AddPartialSpecialization(Partial, InsertPos);
@@ -5318,7 +5319,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
Specialization = VarTemplateSpecializationDecl::Create(
Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc,
VarTemplate, DI->getType(), DI, SC, CanonicalConverted);
- Specialization->setTemplateArgsInfo(TemplateArgs);
+ Specialization->setTemplateArgsAsWritten(TemplateArgs);
if (!PrevDecl)
VarTemplate->AddSpecialization(Specialization, InsertPos);
@@ -5353,7 +5354,6 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
}
}
- Specialization->setTemplateKeywordLoc(TemplateKWLoc);
Specialization->setLexicalDeclContext(CurContext);
// Add the specialization into its lexical context, so that it can
@@ -9414,10 +9414,6 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody) {
assert(TUK != TUK_Reference && "References are not specializations");
- // NOTE: KWLoc is the location of the tag keyword. This will instead
- // store the location of the outermost template keyword in the declaration.
- SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0
- ? TemplateParameterLists[0]->getTemplateLoc() : KWLoc;
SourceLocation TemplateNameLoc = TemplateId.TemplateNameLoc;
SourceLocation LAngleLoc = TemplateId.LAngleLoc;
SourceLocation RAngleLoc = TemplateId.RAngleLoc;
@@ -9629,7 +9625,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
ClassTemplatePartialSpecializationDecl::Create(
Context, Kind, ClassTemplate->getDeclContext(), KWLoc,
TemplateNameLoc, TemplateParams, ClassTemplate, CanonicalConverted,
- TemplateArgs, CanonType, PrevPartial);
+ CanonType, PrevPartial);
+ Partial->setTemplateArgsAsWritten(TemplateArgs);
SetNestedNameSpecifier(*this, Partial, SS);
if (TemplateParameterLists.size() > 1 && SS.isSet()) {
Partial->setTemplateParameterListsInfo(
@@ -9652,6 +9649,7 @@ 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,
@@ -9735,21 +9733,6 @@ 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.
@@ -9765,6 +9748,15 @@ 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,
@@ -10999,21 +10991,10 @@ DeclResult Sema::ActOnExplicitInstantiation(
}
}
- // 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);
+ Specialization->setTemplateArgsAsWritten(TemplateArgs);
// Set source locations for keywords.
- Specialization->setExternLoc(ExternLoc);
+ Specialization->setExternKeywordLoc(ExternLoc);
Specialization->setTemplateKeywordLoc(TemplateLoc);
Specialization->setBraceRange(SourceRange());
@@ -11426,6 +11407,11 @@ 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 e0c1f81..381d79b2 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3861,15 +3861,16 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
// Substitute into the template arguments of the class template explicit
// specialization.
- 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;
+ 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;
+ }
// Check that the template argument list is well-formed for this
// class template.
@@ -3923,6 +3924,7 @@ 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.
@@ -3933,28 +3935,10 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
if (SubstQualifier(D, InstD))
return nullptr;
- // Build the canonical type that describes the converted template
- // arguments of the class template explicit specialization.
- QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
- 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->setTypeAsWritten(WrittenTy);
- InstD->setExternLoc(D->getExternLoc());
+ InstD->setExternKeywordLoc(D->getExternKeywordLoc());
InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc());
Owner->addDecl(InstD);
@@ -3988,7 +3972,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
// Substitute the current template arguments.
if (const ASTTemplateArgumentListInfo *TemplateArgsInfo =
- D->getTemplateArgsInfo()) {
+ D->getTemplateArgsAsWritten()) {
VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());
VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());
@@ -4046,7 +4030,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
VarTemplateSpecializationDecl *Var = VarTemplateSpecializationDecl::Create(
SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
VarTemplate, DI->getType(), DI, D->getStorageClass(), Converted);
- Var->setTemplateArgsInfo(TemplateArgsInfo);
+ Var->setTemplateArgsAsWritten(TemplateArgsInfo);
if (!PrevDecl) {
void *InsertPos = nullptr;
VarTemplate->findSpecialization(Converted, InsertPos);
@@ -4288,19 +4272,21 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
TemplateName(ClassTemplate), CanonicalConverted);
- // 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);
+ // 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);
if (PrevDecl) {
// We've already seen a partial specialization with the same template
@@ -4318,28 +4304,14 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
//
// Outer<int, int> outer; // error: the partial specializations of Inner
// // have the same signature.
- SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared)
- << WrittenTy->getType();
+ SemaRef.Diag(InstPartialSpec->getLocation(),
+ diag::err_partial_spec_redeclared)
+ << InstPartialSpec;
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);
@@ -4408,46 +4380,6 @@ 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,
@@ -4467,16 +4399,39 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
VarTemplatePartialSpecializationDecl::Create(
SemaRef.Context, Owner, PartialSpec->getInnerLocStart(),
PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(),
- DI, PartialSpec->getStorageClass(), CanonicalConverted,
- InstTemplateArgs);
+ DI, PartialSpec->getStorageClass(), CanonicalConverted);
+
+ InstPartialSpec->setTemplateArgsAsWritten(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);
@@ -5738,7 +5693,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
TemplateArgumentListInfo TemplateArgInfo;
if (const ASTTemplateArgumentListInfo *ArgInfo =
- VarSpec->getTemplateArgsInfo()) {
+ VarSpec->getTemplateArgsAsWritten()) {
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 089ede4..0c647086 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2548,16 +2548,17 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
}
}
- // Explicit info.
- if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) {
- auto *ExplicitInfo =
- new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = TyInfo;
- ExplicitInfo->ExternLoc = readSourceLocation();
+ // extern/template keyword locations for explicit instantiations
+ if (Record.readBool()) {
+ auto *ExplicitInfo = new (C) ExplicitInstantiationInfo;
+ ExplicitInfo->ExternKeywordLoc = readSourceLocation();
ExplicitInfo->TemplateKeywordLoc = readSourceLocation();
D->ExplicitInfo = ExplicitInfo;
}
+ if (Record.readBool())
+ D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo());
+
return Redecl;
}
@@ -2567,7 +2568,6 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
// need them for profiling
TemplateParameterList *Params = Record.readTemplateParameterList();
D->TemplateParams = Params;
- D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
@@ -2617,16 +2617,17 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
}
}
- // Explicit info.
- if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) {
- auto *ExplicitInfo =
- new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = TyInfo;
- ExplicitInfo->ExternLoc = readSourceLocation();
+ // extern/template keyword locations for explicit instantiations
+ if (Record.readBool()) {
+ auto *ExplicitInfo = new (C) ExplicitInstantiationInfo;
+ ExplicitInfo->ExternKeywordLoc = 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);
@@ -2666,7 +2667,6 @@ 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 6201d28..c2f1d1b 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1765,20 +1765,28 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
}
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
+ bool ExplicitInstantiation =
+ D->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration ||
+ D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
+ Record.push_back(ExplicitInstantiation);
+ if (ExplicitInstantiation) {
+ Record.AddSourceLocation(D->getExternKeywordLoc());
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);
@@ -1812,13 +1820,22 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
}
- // Explicit info.
- Record.AddTypeSourceInfo(D->getTypeAsWritten());
- if (D->getTypeAsWritten()) {
- Record.AddSourceLocation(D->getExternLoc());
+ bool ExplicitInstantiation =
+ D->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDeclaration ||
+ D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
+ Record.push_back(ExplicitInstantiation);
+ if (ExplicitInstantiation) {
+ Record.AddSourceLocation(D->getExternKeywordLoc());
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());
@@ -1839,7 +1856,6 @@ 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 cd02619..3e50d67f 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -735,7 +735,8 @@ public:
auto *Declaration =
cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C));
foldExplicitTemplateInstantiation(
- Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()),
+ Builder.getTemplateRange(C),
+ Builder.findToken(C->getExternKeywordLoc()),
Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C);
return true;
}