diag::warn_dllimport_dropped_from_inline_function)
<< NewDecl << OldImportAttr;
}
+
+ // A specialization of a class template member function is processed here
+ // since it's a redeclaration. If the parent class is dllexport, the
+ // specialization inherits that attribute. This doesn't happen automatically
+ // since the parent class isn't instantiated until later.
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewDecl)) {
+ if (MD->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization &&
+ !NewImportAttr && !NewExportAttr) {
+ if (const DLLExportAttr *ParentExportAttr =
+ MD->getParent()->getAttr<DLLExportAttr>()) {
+ DLLExportAttr *NewAttr = ParentExportAttr->clone(S.Context);
+ NewAttr->setInherited(true);
+ NewDecl->addAttr(NewAttr);
+ }
+ }
+ }
}
/// Given that we are within the definition of the given function,
template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
+namespace pr34849 {
+// Specializations of exported class template member functions get exported.
+template <typename> struct __declspec(dllexport) ExportedClassTemplate { void foo(); };
+template<> void ExportedClassTemplate<int>::foo() {}
+template struct ExportedClassTemplate<int>;
+// M32-DAG: define dllexport x86_thiscallcc void @"\01?foo@?$ExportedClassTemplate@H@pr34849@@QAEXXZ"
+
+// Specializations of exported class member template functions do not get exported.
+struct __declspec(dllexport) ExportedClass { template <typename> void bar() ; };
+template<> void ExportedClass::bar<int>() {}
+// M32-DAG: define x86_thiscallcc void @"\01??$bar@H@ExportedClass@pr34849@@QAEXXZ"
+template <typename> struct __declspec(dllexport) ExportedClassTemplate2 { template <typename> void baz(); };
+template<> template<> void ExportedClassTemplate2<int>::baz<int>() {}
+// M32-DAG: define x86_thiscallcc void @"\01??$baz@H@?$ExportedClassTemplate2@H@pr34849@@QAEXXZ"
+}
//===----------------------------------------------------------------------===//
// Classes with template base classes