summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-02-09 02:51:17 +0000
committerReid Kleckner <rnk@google.com>2016-02-09 02:51:17 +0000
commitf5f2f5f15953e68ba1b1c5feff0908feab833b33 (patch)
tree3cdff950fee6b5e8109312e9279105686cddc948
parentca2edc7ad5ebeceb8eae8c20a8455d6db248ad74 (diff)
downloadbcm5719-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.cpp10
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp11
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
OpenPOWER on IntegriCloud