diff options
author | Reid Kleckner <rnk@google.com> | 2016-02-09 02:51:17 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-02-09 02:51:17 +0000 |
commit | f5f2f5f15953e68ba1b1c5feff0908feab833b33 (patch) | |
tree | 3cdff950fee6b5e8109312e9279105686cddc948 | |
parent | ca2edc7ad5ebeceb8eae8c20a8455d6db248ad74 (diff) | |
download | bcm5719-llvm-f5f2f5f15953e68ba1b1c5feff0908feab833b33.tar.gz bcm5719-llvm-f5f2f5f15953e68ba1b1c5feff0908feab833b33.zip |
Avoid forcing emission of delayed dllexported classes on template instantiation
Fixes PR26490
llvm-svn: 260194
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 10 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/dllexport.cpp | 11 |
2 files changed, 21 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 56858bcc7e6..db3f47fd916 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1949,6 +1949,13 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod(); LocalInstantiationScope Scope(*this, MergeWithParentScope); + // All dllexported classes created during instantiation should be fully + // emitted after instantiation completes. We may not be ready to emit any + // delayed classes already on the stack, so save them away and put them back + // later. + decltype(DelayedDllExportClasses) ExportedClasses; + std::swap(ExportedClasses, DelayedDllExportClasses); + // Pull attributes from the pattern onto the instantiation. InstantiateAttrs(TemplateArgs, Pattern, Instantiation); @@ -2034,6 +2041,9 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, // default arg exprs for default constructors if necessary now. ActOnFinishCXXNonNestedClass(Instantiation); + // Put back the delayed exported classes that we moved out of the way. + std::swap(ExportedClasses, DelayedDllExportClasses); + // Instantiate late parsed attributes, and attach them to their decls. // See Sema::InstantiateAttrs for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(), diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index 1412ad866bd..04007e8212d 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -777,6 +777,17 @@ struct __declspec(dllexport) Baz { // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %"struct.InClassInits::Baz"* @"\01??4Baz@InClassInits@@QAEAAU01@ABU01@@Z" } +// We had an issue where instantiating A would force emission of B's delayed +// exported methods. +namespace pr26490 { +template <typename T> struct A { }; +struct __declspec(dllexport) B { + B(int = 0) {} + A<int> m_fn1() {} +}; +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ" +} + //===----------------------------------------------------------------------===// // Classes with template base classes |