diff options
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 | 266 | ||||
-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 | 58 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 163 | ||||
-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, 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; } |