From 99fa97a8b987febf298007b27e42f8a1d1549822 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 19 Feb 2015 22:39:24 +0000 Subject: [PATCH] Don't dllexport inline methods when targeting MinGW. MinGW neither imports nor exports such methods. The import bit was committed earlier, in r221154, and this takes care of the export part. This also partially fixes PR22591. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@229922 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 4 +-- test/CodeGenCXX/dllexport.cpp | 41 ++++++++++++++++++------------ test/CodeGenCXX/dllimport.cpp | 13 ++++++---- test/SemaCXX/dllexport-pr22591.cpp | 16 ++++++++++++ 4 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 test/SemaCXX/dllexport-pr22591.cpp diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f274323575..33f8c91691 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4786,9 +4786,9 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { continue; } - if (MD->isInlined() && ClassImported && + if (MD->isInlined() && !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { - // MinGW does not import inline functions. + // MinGW does not import or export inline methods. continue; } } diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index 0845c6dd7f..5532a7d5f3 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -511,7 +511,8 @@ struct __declspec(dllexport) V : public U { }; // U's assignment operator is emitted. // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z" -struct __declspec(dllexport) W { virtual void foo() {} }; +struct __declspec(dllexport) W { virtual void foo(); }; +void W::foo() {} // Default ctor: // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ" // Copy ctor: @@ -519,7 +520,7 @@ struct __declspec(dllexport) W { virtual void foo() {} }; // vftable: // M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)], comdat($"\01??_7W@@6B@") // M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[W_VTABLE]], i32 0, i32 1) -// G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] +// G32-DAG: @_ZTV1W = dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] struct __declspec(dllexport) X : public virtual W {}; // vbtable: @@ -573,17 +574,19 @@ namespace ReferencedInlineMethodInNestedClass { // MS ignores DLL attributes on partial specializations. template struct PartiallySpecializedClassTemplate {}; -template struct __declspec(dllexport) PartiallySpecializedClassTemplate { void f() {} }; +template struct __declspec(dllexport) PartiallySpecializedClassTemplate { void f(); }; +template void PartiallySpecializedClassTemplate::f() {} 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() {} }; +template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate { void f(); }; +void ExplicitlySpecializedClassTemplate::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 +// M32-DAG: define dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" +// G32-DAG: define dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv // MS inherits DLL attributes to partial specializations. template struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate {}; @@ -646,21 +649,27 @@ USEMEMFUNC(ExplicitInstantiationDeclExportedTemplate, f); // Classes with template base classes //===----------------------------------------------------------------------===// -template struct ClassTemplate { void func() {} }; -template struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; +template struct ClassTemplate { void func(); }; +template void ClassTemplate::func() {} +template struct __declspec(dllexport) ExportedClassTemplate { void func(); }; +template void ExportedClassTemplate::func() {} template struct __declspec(dllimport) ImportedClassTemplate { void func(); }; template void ImportedClassTemplate::func() {} template struct ExplicitlySpecializedTemplate { void func() {} }; -template <> struct ExplicitlySpecializedTemplate { void func() {} }; +template <> struct ExplicitlySpecializedTemplate { void func(); }; +void ExplicitlySpecializedTemplate::func() {} template struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate { void func() {} }; +template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate { void func(); }; +void ExplicitlyExportSpecializedTemplate::func() {} template struct ExplicitlyImportSpecializedTemplate { void func(); }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate { void func(); }; -template struct ExplicitlyInstantiatedTemplate { void func() {} }; +template struct ExplicitlyInstantiatedTemplate { void func(); }; +template void ExplicitlyInstantiatedTemplate::func() {} template struct ExplicitlyInstantiatedTemplate; -template struct ExplicitlyExportInstantiatedTemplate { void func() {} }; +template struct ExplicitlyExportInstantiatedTemplate { void func(); }; +template void ExplicitlyExportInstantiatedTemplate::func() {} template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate; template struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate; @@ -701,14 +710,14 @@ USEMEMFUNC(DerivedFromTemplateB2, func) // Base class already specialized without dll attribute. struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate {}; USEMEMFUNC(DerivedFromExplicitlySpecializedTemplate, func) -// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ" -// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv +// M32-DAG: define x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ" +// G32-DAG: define x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv // Base class alredy specialized with export attribute. struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate {}; USEMEMFUNC(DerivedFromExplicitlyExportSpecializedTemplate, func) -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" -// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv +// M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" +// G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv // Base class already specialized with import attribute. struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate {}; diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index e5b9f64dcc..73f6023443 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -728,19 +728,22 @@ USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr, f); //===----------------------------------------------------------------------===// template struct ClassTemplate { void func() {} }; -template struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; +template struct __declspec(dllexport) ExportedClassTemplate { void func(); }; +template void ExportedClassTemplate::func() {} template struct __declspec(dllimport) ImportedClassTemplate { void func(); }; template struct ExplicitlySpecializedTemplate { void func() {} }; template <> struct ExplicitlySpecializedTemplate { void func() {} }; template struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate { void func() {} }; +template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate { void func(); }; +void ExplicitlyExportSpecializedTemplate::func() {} template struct ExplicitlyImportSpecializedTemplate { void func() {} }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate { void func(); }; template struct ExplicitlyInstantiatedTemplate { void func() {} }; template struct ExplicitlyInstantiatedTemplate; -template struct ExplicitlyExportInstantiatedTemplate { void func() {} }; +template struct ExplicitlyExportInstantiatedTemplate { void func(); }; +template void ExplicitlyExportInstantiatedTemplate::func() {} template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate; template struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate; @@ -787,8 +790,8 @@ USEMEMFUNC(ExplicitlySpecializedTemplate, func) // Base class alredy specialized with export attribute. struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate {}; USEMEMFUNC(ExplicitlyExportSpecializedTemplate, func) -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" -// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv +// M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" +// G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv // Base class already specialized with import attribute. struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate {}; diff --git a/test/SemaCXX/dllexport-pr22591.cpp b/test/SemaCXX/dllexport-pr22591.cpp new file mode 100644 index 0000000000..af75e4fe64 --- /dev/null +++ b/test/SemaCXX/dllexport-pr22591.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple i686-windows-gnu -verify -std=c++03 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -verify -std=c++11 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -verify -std=c++11 %s + +// FIXME: For C++03 MS ABI we erroneously try to synthesize default ctor, etc. for S. + +// expected-no-diagnostics + +struct NonCopyable { +private: + NonCopyable(); +}; + +struct __declspec(dllexport) S { + NonCopyable member; +}; -- 2.40.0