From 508954279356432f9f0a91eef6ca432892ae4b62 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Sat, 31 Jan 2015 03:04:55 +0000 Subject: [PATCH] [modules] When we try to complete the redeclaration chain for a class template specialization, pull in any lazy specializations of the class template. llvm-svn: 227668 --- clang/include/clang/AST/DeclTemplate.h | 18 +++++++++--------- clang/lib/Serialization/ASTReader.cpp | 15 +++++++++++++++ clang/test/Modules/Inputs/merge-template-members/def.h | 2 ++ .../Inputs/merge-template-members/module.modulemap | 2 ++ .../Modules/Inputs/merge-template-members/update.h | 2 ++ clang/test/Modules/merge-template-members.cpp | 10 ++++++++++ 6 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 clang/test/Modules/Inputs/merge-template-members/def.h create mode 100644 clang/test/Modules/Inputs/merge-template-members/module.modulemap create mode 100644 clang/test/Modules/Inputs/merge-template-members/update.h create mode 100644 clang/test/Modules/merge-template-members.cpp diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 9283d2d..58f24d9 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 & @@ -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(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 & 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(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 & 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(TemplatedDecl); diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index f7822b74..5b9ad12 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 +static void completeRedeclChainForTemplateSpecialization(Decl *D) { + if (auto *TSD = dyn_cast(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(D)) + CTSD->getSpecializedTemplate()->LoadLazySpecializations(); + if (auto *VTSD = dyn_cast(D)) + VTSD->getSpecializedTemplate()->LoadLazySpecializations(); + if (auto *FD = dyn_cast(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 0000000..f9f65c3 --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/def.h @@ -0,0 +1,2 @@ +template struct A { int n; }; +template struct B { typedef A 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 0000000..9ce5690 --- /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 0000000..cceb52d --- /dev/null +++ b/clang/test/Modules/Inputs/merge-template-members/update.h @@ -0,0 +1,2 @@ +#include "def.h" +B::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 0000000..99696d8 --- /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 struct A { int n; }; +template struct B { typedef A C; }; +template class B; + +#include "update.h" +B::C use2; -- 2.7.4