diff options
-rw-r--r-- | clang/include/clang/AST/DeclTemplate.h | 18 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 15 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/merge-template-members/def.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/merge-template-members/module.modulemap | 2 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/merge-template-members/update.h | 2 | ||||
-rw-r--r-- | clang/test/Modules/merge-template-members.cpp | 10 |
6 files changed, 40 insertions, 9 deletions
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 9283d2dc435..58f24d9b87e 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -788,9 +788,6 @@ protected: friend class FunctionDecl; - /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; - /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & @@ -804,6 +801,9 @@ protected: void *InsertPos); public: + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// Get the underlying function declaration of the template. FunctionDecl *getTemplatedDecl() const { return static_cast<FunctionDecl*>(TemplatedDecl); @@ -1827,9 +1827,6 @@ protected: uint32_t *LazySpecializations; }; - /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; - /// \brief Retrieve the set of specializations of this class template. llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & getSpecializations() const; @@ -1851,6 +1848,9 @@ protected: } public: + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// \brief Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { return static_cast<CXXRecordDecl *>(TemplatedDecl); @@ -2662,9 +2662,6 @@ protected: uint32_t *LazySpecializations; }; - /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; - /// \brief Retrieve the set of specializations of this variable template. llvm::FoldingSetVector<VarTemplateSpecializationDecl> & getSpecializations() const; @@ -2686,6 +2683,9 @@ protected: } public: + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// \brief Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { return static_cast<VarDecl *>(TemplatedDecl); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index f7822b74769..5b9ad12a3c5 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -6081,6 +6081,12 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) { return GetDecl(ID); } +template<typename TemplateSpecializationDecl> +static void completeRedeclChainForTemplateSpecialization(Decl *D) { + if (auto *TSD = dyn_cast<TemplateSpecializationDecl>(D)) + TSD->getSpecializedTemplate()->LoadLazySpecializations(); +} + void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { // We arrange to not care about the complete redeclaration chain while we're @@ -6114,6 +6120,15 @@ void ASTReader::CompleteRedeclChain(const Decl *D) { D->getDeclContext()->decls_begin(); } } + + if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) + CTSD->getSpecializedTemplate()->LoadLazySpecializations(); + if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(D)) + VTSD->getSpecializedTemplate()->LoadLazySpecializations(); + if (auto *FD = dyn_cast<FunctionDecl>(D)) { + if (auto *Template = FD->getPrimaryTemplate()) + Template->LoadLazySpecializations(); + } } uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, diff --git a/clang/test/Modules/Inputs/merge-template-members/def.h b/clang/test/Modules/Inputs/merge-template-members/def.h new file mode 100644 index 00000000000..f9f65c34db0 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/def.h @@ -0,0 +1,2 @@ +template<typename> struct A { int n; }; +template<typename> struct B { typedef A<void> C; }; diff --git a/clang/test/Modules/Inputs/merge-template-members/module.modulemap b/clang/test/Modules/Inputs/merge-template-members/module.modulemap new file mode 100644 index 00000000000..9ce569074d8 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/module.modulemap @@ -0,0 +1,2 @@ +module def { header "def.h" export * } +module update { header "update.h" export * } diff --git a/clang/test/Modules/Inputs/merge-template-members/update.h b/clang/test/Modules/Inputs/merge-template-members/update.h new file mode 100644 index 00000000000..cceb52db403 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/update.h @@ -0,0 +1,2 @@ +#include "def.h" +B<int>::C use1; diff --git a/clang/test/Modules/merge-template-members.cpp b/clang/test/Modules/merge-template-members.cpp new file mode 100644 index 00000000000..99696d8ad1c --- /dev/null +++ b/clang/test/Modules/merge-template-members.cpp @@ -0,0 +1,10 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/merge-template-members -verify %s +// expected-no-diagnostics + +template<typename> struct A { int n; }; +template<typename> struct B { typedef A<void> C; }; +template class B<int>; + +#include "update.h" +B<int>::C use2; |