diff options
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 15 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-a.h | 1 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-b.h | 3 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-common.h | 2 |
4 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 46f6106c13a..dcb747fe8d7 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2391,8 +2391,14 @@ static DeclContext *getPrimaryContextForMerging(DeclContext *DC) { if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC)) return ND->getOriginalNamespace(); + // There is one tricky case here: if DC is a class with no definition, then + // we're merging a declaration whose definition is added by an update record, + // but we've not yet loaded that update record. In this case, we use the + // canonical declaration for merging until we get a real definition. + // FIXME: When we add a definition, we may need to move the partial lookup + // information from the canonical declaration onto the chosen definition. if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) - return RD->getDefinition(); + return RD->getPrimaryContext(); if (EnumDecl *ED = dyn_cast<EnumDecl>(DC)) return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition() @@ -3361,7 +3367,12 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx); auto *TemplArgList = TemplateArgumentList::CreateCopy( Reader.getContext(), TemplArgs.data(), TemplArgs.size()); - Spec->setInstantiationOf(PartialSpec, TemplArgList); + + // FIXME: If we already have a partial specialization set, + // check that it matches. + if (!Spec->getSpecializedTemplateOrPartial() + .is<ClassTemplatePartialSpecializationDecl *>()) + Spec->setInstantiationOf(PartialSpec, TemplArgList); } } diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h index 1ade811d71d..f3150398e7a 100644 --- a/clang/test/Modules/Inputs/cxx-templates-a.h +++ b/clang/test/Modules/Inputs/cxx-templates-a.h @@ -58,6 +58,7 @@ template<typename T> struct WithPartialSpecialization<T*> { T &f() { static T t; return t; } }; typedef WithPartialSpecializationUse::type WithPartialSpecializationInstantiate; +typedef WithPartialSpecialization<void(int)>::type WithPartialSpecializationInstantiate2; template<> struct WithExplicitSpecialization<int> { int n; diff --git a/clang/test/Modules/Inputs/cxx-templates-b.h b/clang/test/Modules/Inputs/cxx-templates-b.h index 77a2c2333ac..8b97d22a370 100644 --- a/clang/test/Modules/Inputs/cxx-templates-b.h +++ b/clang/test/Modules/Inputs/cxx-templates-b.h @@ -57,6 +57,8 @@ template<int> struct UseInt; template<typename T> void UseRedeclaredEnum(UseInt<T() + CommonTemplate<char>::a>); constexpr void (*UseRedeclaredEnumB)(UseInt<1>) = UseRedeclaredEnum<int>; +typedef WithPartialSpecialization<void(int)>::type WithPartialSpecializationInstantiate3; + template<typename> struct MergeSpecializations; template<typename T> struct MergeSpecializations<T&> { typedef int partially_specialized_in_b; @@ -76,4 +78,5 @@ void TriggerInstantiation() { UseDefinedInBImpl<void>(); Std::f<int>(); PartiallyInstantiatePartialSpec<int*>::foo(); + WithPartialSpecialization<void(int)>::type x; } diff --git a/clang/test/Modules/Inputs/cxx-templates-common.h b/clang/test/Modules/Inputs/cxx-templates-common.h index 074cc8f9007..f7c083249f8 100644 --- a/clang/test/Modules/Inputs/cxx-templates-common.h +++ b/clang/test/Modules/Inputs/cxx-templates-common.h @@ -32,7 +32,9 @@ template<typename T> struct Outer { }; template<typename T> struct WithPartialSpecialization {}; +template<typename T> struct WithPartialSpecialization<void(T)> { typedef int type; }; typedef WithPartialSpecialization<int*> WithPartialSpecializationUse; +typedef WithPartialSpecialization<void(int)> WithPartialSpecializationUse2; template<typename T> struct WithExplicitSpecialization; typedef WithExplicitSpecialization<int> WithExplicitSpecializationUse; |

