diff options
| author | Hans Wennborg <hans@hanshq.net> | 2015-02-19 22:39:24 +0000 |
|---|---|---|
| committer | Hans Wennborg <hans@hanshq.net> | 2015-02-19 22:39:24 +0000 |
| commit | 97cbed422c3dde90347df519abe5f8ba663158a8 (patch) | |
| tree | c41868892bdb20e826128dec0f212f0eb5d82382 | |
| parent | 6b5ed34a406451f33b60cdd52c3d5df6e0afab0c (diff) | |
| download | bcm5719-llvm-97cbed422c3dde90347df519abe5f8ba663158a8.tar.gz bcm5719-llvm-97cbed422c3dde90347df519abe5f8ba663158a8.zip | |
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.
llvm-svn: 229922
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/dllexport.cpp | 41 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/dllimport.cpp | 13 | ||||
| -rw-r--r-- | clang/test/SemaCXX/dllexport-pr22591.cpp | 16 |
4 files changed, 51 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f274323575e..33f8c91691f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index 0845c6dd7fc..5532a7d5f3a 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -511,7 +511,8 @@ struct __declspec(dllexport) V : public U<int> { }; // U<int>'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 <typename T> struct PartiallySpecializedClassTemplate {}; -template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} }; +template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f(); }; +template <typename T> void PartiallySpecializedClassTemplate<T*>::f() {} USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, 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 <typename T> struct ExplicitlySpecializedClassTemplate {}; -template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f() {} }; +template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f(); }; +void ExplicitlySpecializedClassTemplate<void*>::f() {} USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, 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 <typename T> struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate {}; @@ -646,21 +649,27 @@ USEMEMFUNC(ExplicitInstantiationDeclExportedTemplate<int>, f); // Classes with template base classes //===----------------------------------------------------------------------===// -template <typename T> struct ClassTemplate { void func() {} }; -template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; +template <typename T> struct ClassTemplate { void func(); }; +template <typename T> void ClassTemplate<T>::func() {} +template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); }; +template <typename T> void ExportedClassTemplate<T>::func() {} template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); }; template <typename T> void ImportedClassTemplate<T>::func() {} template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; -template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; +template <> struct ExplicitlySpecializedTemplate<int> { void func(); }; +void ExplicitlySpecializedTemplate<int>::func() {} template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; +template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); }; +void ExplicitlyExportSpecializedTemplate<int>::func() {} template <typename T> struct ExplicitlyImportSpecializedTemplate { void func(); }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); }; -template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyInstantiatedTemplate { void func(); }; +template <typename T> void ExplicitlyInstantiatedTemplate<T>::func() {} template struct ExplicitlyInstantiatedTemplate<int>; -template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); }; +template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {} template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; @@ -701,14 +710,14 @@ USEMEMFUNC(DerivedFromTemplateB2, func) // Base class already specialized without dll attribute. struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; 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<int> {}; 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<int> {}; diff --git a/clang/test/CodeGenCXX/dllimport.cpp b/clang/test/CodeGenCXX/dllimport.cpp index e5b9f64dcca..73f60234430 100644 --- a/clang/test/CodeGenCXX/dllimport.cpp +++ b/clang/test/CodeGenCXX/dllimport.cpp @@ -728,19 +728,22 @@ USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f); //===----------------------------------------------------------------------===// template <typename T> struct ClassTemplate { void func() {} }; -template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; +template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); }; +template <typename T> void ExportedClassTemplate<T>::func() {} template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); }; template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; +template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); }; +void ExplicitlyExportSpecializedTemplate<int>::func() {} template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); }; template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; template struct ExplicitlyInstantiatedTemplate<int>; -template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); }; +template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {} template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; @@ -787,8 +790,8 @@ USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func) // Base class alredy specialized with export attribute. struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, 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<int> {}; diff --git a/clang/test/SemaCXX/dllexport-pr22591.cpp b/clang/test/SemaCXX/dllexport-pr22591.cpp new file mode 100644 index 00000000000..af75e4fe646 --- /dev/null +++ b/clang/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; +}; |

