diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 13 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-a.h | 6 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-common.h | 3 | ||||
| -rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 2 |
5 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 696a78295cb..d900f71c464 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3201,6 +3201,16 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, cast<ClassTemplateSpecializationDecl>(RD); Spec->setTemplateSpecializationKind(TSK); Spec->setPointOfInstantiation(POI); + + if (Record[Idx++]) { + auto PartialSpec = + ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx); + SmallVector<TemplateArgument, 8> TemplArgs; + Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); + auto *TemplArgList = TemplateArgumentList::CreateCopy( + Reader.getContext(), TemplArgs.data(), TemplArgs.size()); + Spec->setInstantiationOf(PartialSpec, TemplArgList); + } } RD->setTagKind((TagTypeKind)Record[Idx++]); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index d335c94861f..7753986d58f 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -4531,6 +4531,19 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { auto *Spec = cast<ClassTemplateSpecializationDecl>(RD); Record.push_back(Spec->getTemplateSpecializationKind()); AddSourceLocation(Spec->getPointOfInstantiation(), Record); + + // The instantiation might have been resolved to a partial + // specialization. If so, record which one. + auto From = Spec->getInstantiatedFrom(); + if (auto PartialSpec = + From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) { + Record.push_back(true); + AddDeclRef(PartialSpec, Record); + AddTemplateArgumentList(&Spec->getTemplateInstantiationArgs(), + Record); + } else { + Record.push_back(false); + } } Record.push_back(RD->getTagKind()); AddSourceLocation(RD->getLocation(), Record); diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h index 6ecc2ca4610..04acf5929d1 100644 --- a/clang/test/Modules/Inputs/cxx-templates-a.h +++ b/clang/test/Modules/Inputs/cxx-templates-a.h @@ -50,3 +50,9 @@ template<> struct MergeSpecializations<char> { }; void InstantiateWithFriend(Std::WithFriend<int> wfi) {} + +template<typename T> struct WithPartialSpecialization<T*> { + typedef int type; + T &f() { static T t; return t; } +}; +typedef WithPartialSpecializationUse::type WithPartialSpecializationInstantiate; diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h index 4a10e358805..a31be8758cc 100644 --- a/clang/test/Modules/Inputs/cxx-templates-common.h +++ b/clang/test/Modules/Inputs/cxx-templates-common.h @@ -30,3 +30,6 @@ template<typename T> struct Outer { void g(); }; }; + +template<typename T> struct WithPartialSpecialization {}; +typedef WithPartialSpecialization<int*> WithPartialSpecializationUse; diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index ab65e3dd2d0..a880c9b2f18 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -102,6 +102,8 @@ void g() { TemplateInstantiationVisibility<char[3]> tiv3; // expected-error {{must be imported from module 'cxx_templates_b_impl'}} // expected-note@cxx-templates-b-impl.h:10 {{previous definition is here}} TemplateInstantiationVisibility<char[4]> tiv4; + + int &p = WithPartialSpecializationUse().f(); } RedeclaredAsFriend<int> raf1; |

