From 5148a692554b5680815a40fa8c03a2a62689b3de Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Sat, 23 Aug 2014 22:34:43 +0000 Subject: [PATCH] MS ABI: Inherit DLL attributes to partial class template specializations git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216333 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 13 +++++++++++++ test/CodeGenCXX/dllexport.cpp | 8 ++++++++ test/CodeGenCXX/dllimport.cpp | 9 +++++++++ 3 files changed, 30 insertions(+) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 844011880e..5e789fe20e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4421,6 +4421,19 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info, /// \brief Check class-level dllimport/dllexport attribute. static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { Attr *ClassAttr = getDLLAttr(Class); + + // MSVC inherits DLL attributes to partial class template specializations. + if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) { + if (auto *Spec = dyn_cast(Class)) { + if (Attr *TemplateAttr = + getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) { + auto *A = cast(TemplateAttr->clone(S.getASTContext())); + A->setInherited(true); + ClassAttr = A; + } + } + } + if (!ClassAttr) return; diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index 4cf6005134..44af5d0215 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -579,12 +579,20 @@ USEMEMFUNC(PartiallySpecializedClassTemplate, f); // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ" // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv +// Attributes on explicit specializations are honored. template struct ExplicitlySpecializedClassTemplate {}; template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate { void f() {} }; USEMEMFUNC(ExplicitlySpecializedClassTemplate, f); // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv +// MS inherits DLL attributes to partial specializations. +template struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate {}; +template struct PartiallySpecializedExportedClassTemplate { void f() {} }; +USEMEMFUNC(PartiallySpecializedExportedClassTemplate, f); +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$PartiallySpecializedExportedClassTemplate@PAX@@QAEXXZ" +// G32-DAG: define linkonce_odr x86_thiscallcc @_ZN41PartiallySpecializedExportedClassTemplateIPvE1fEv + //===----------------------------------------------------------------------===// // Classes with template base classes //===----------------------------------------------------------------------===// diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index c0949942dc..3292a9fa38 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -679,12 +679,21 @@ USEMEMFUNC(PartiallySpecializedClassTemplate, f); // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ" // G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv +// Attributes on explicit specializations are honored. template struct ExplicitlySpecializedClassTemplate {}; template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate { void f() {} }; USEMEMFUNC(ExplicitlySpecializedClassTemplate, f); // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" // G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv +// MS inherits DLL attributes to partial specializations. +template struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {}; +template struct PartiallySpecializedImportedClassTemplate { void f() {} }; +USEMEMFUNC(PartiallySpecializedImportedClassTemplate, f); +// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ" +// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv + + //===----------------------------------------------------------------------===// // Classes with template base classes //===----------------------------------------------------------------------===// -- 2.40.0