Author: hans Date: Tue Oct 10 09:53:25 2017 New Revision: 315330 URL: http://llvm.org/viewvc/llvm-project?rev=315330&view=rev Log: 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. Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/CodeGenCXX/dllexport.cpp Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=315330&r1=315329&r2=315330&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Oct 10 09:53:25 2017 @@ -6041,6 +6041,22 @@ static void checkDLLAttributeRedeclarati 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, Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=315330&r1=315329&r2=315330&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original) +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Tue Oct 10 09:53:25 2017 @@ -831,6 +831,21 @@ template <typename T> struct ExplicitIns 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits