Avoid forcing emission of delayed dllexported classes on template instantiation
authorReid Kleckner <rnk@google.com>
Tue, 9 Feb 2016 02:51:17 +0000 (02:51 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 9 Feb 2016 02:51:17 +0000 (02:51 +0000)
Fixes PR26490

llvm-svn: 260194

clang/lib/Sema/SemaTemplateInstantiate.cpp
clang/test/CodeGenCXX/dllexport.cpp

index 56858bc..db3f47f 100644 (file)
@@ -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(),
index 1412ad8..04007e8 100644 (file)
@@ -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