forked from OSchip/llvm-project
For dllexport class templates, export specializations of member functions (PR34849) (take 2)
This is a re-commit of r315025, but making sure to only apply this to specializations of class template member functions; i.e. not when the function itself is a template. llvm-svn: 315330
This commit is contained in:
parent
57304923ca
commit
90ccab6855
|
@ -6041,6 +6041,22 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
|
||||||
diag::warn_dllimport_dropped_from_inline_function)
|
diag::warn_dllimport_dropped_from_inline_function)
|
||||||
<< NewDecl << OldImportAttr;
|
<< 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,
|
/// Given that we are within the definition of the given function,
|
||||||
|
|
|
@ -831,6 +831,21 @@ template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
|
||||||
template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
|
template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
|
||||||
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
|
// 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
|
// Classes with template base classes
|
||||||
|
|
Loading…
Reference in New Issue