diff options
Diffstat (limited to 'test/CodeGenCXX/dllimport.cpp')
-rw-r--r-- | test/CodeGenCXX/dllimport.cpp | 164 |
1 files changed, 108 insertions, 56 deletions
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index 59f8f63..e5b9f64 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -1,13 +1,13 @@ -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s -// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s -// RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s | FileCheck --check-prefix=GO1 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines. -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC2 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU2 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s // Helper structs to make templates more expressive. struct ImplicitInst_Imported {}; @@ -95,7 +95,7 @@ inline int __declspec(dllimport) inlineStaticLocalsFunc() { USE(inlineStaticLocalsFunc); // The address of a dllimport global cannot be used in constant initialization. -// M32-DAG: @"\01?arr@?0??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer +// M32-DAG: @"\01?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer // GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer int *initializationFunc() { static int *const arr[] = {&ExternGlobalDecl}; @@ -214,36 +214,36 @@ USE(externC) // Import inline function. // MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z10inlineFuncv() +// GNU-DAG: define linkonce_odr void @_Z10inlineFuncv() // MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z10inlineFuncv() +// GO1-DAG: define linkonce_odr void @_Z10inlineFuncv() __declspec(dllimport) inline void inlineFunc() {} USE(inlineFunc) // MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z10inlineDeclv() +// GNU-DAG: define linkonce_odr void @_Z10inlineDeclv() // MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z10inlineDeclv() +// GO1-DAG: define linkonce_odr void @_Z10inlineDeclv() __declspec(dllimport) inline void inlineDecl(); void inlineDecl() {} USE(inlineDecl) // MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z9inlineDefv() +// GNU-DAG: define linkonce_odr void @_Z9inlineDefv() // MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z9inlineDefv() +// GO1-DAG: define linkonce_odr void @_Z9inlineDefv() __declspec(dllimport) void inlineDef(); inline void inlineDef() {} USE(inlineDef) // inline attributes // MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z8noinlinev() +// GNU-DAG: define linkonce_odr void @_Z8noinlinev() __declspec(dllimport) __attribute__((noinline)) inline void noinline() {} USE(noinline) // MSC2-NOT: @"\01?alwaysInline@@YAXXZ"() -// GNU2-NOT: @_Z12alwaysInlinev() +// GNU-DAG: define linkonce_odr void @_Z12alwaysInlinev() {{.*}} comdat { __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {} USE(alwaysInline) @@ -276,6 +276,11 @@ USE(redecl3) // GNU-DAG: declare void @_Z7friend2v() // MSC-DAG: define void @"\01?friend3@@YAXXZ"() // GNU-DAG: define void @_Z7friend3v() +// MSC-DAG: declare void @"\01?friend4@@YAXXZ"() +// GNU-DAG: declare void @_Z7friend4v() +// MSC-DAG: declare dllimport void @"\01?friend5@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z7friend5v() + struct FuncFriend { friend __declspec(dllimport) void friend1(); friend __declspec(dllimport) void friend2(); @@ -284,9 +289,18 @@ struct FuncFriend { __declspec(dllimport) void friend1(); void friend2(); // dllimport ignored void friend3() {} // dllimport ignored + +__declspec(dllimport) void friend4(); +__declspec(dllimport) void friend5(); +struct FuncFriendRedecl { + friend void friend4(); // dllimport ignored + friend void ::friend5(); +}; USE(friend1) USE(friend2) USE(friend3) +USE(friend4) +USE(friend5) // Implicit declarations can be redeclared with dllimport. // MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"( @@ -315,31 +329,31 @@ USE(funcTmplDecl<ImplicitInst_Imported>) // Import inline function template. // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} USE(inlineFuncTmpl1<ImplicitInst_Imported>) // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} USE(inlineFuncTmpl2<ImplicitInst_Imported>) // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); template<typename T> void inlineFuncTmplDecl() {} USE(inlineFuncTmplDecl<ImplicitInst_Imported>) // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); template<typename T> inline void inlineFuncTmplDef() {} USE(inlineFuncTmplDef<ImplicitInst_Imported>) @@ -373,7 +387,7 @@ USE(funcTmplRedecl3<ImplicitInst_NotImported>) // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"() // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv() // MSC-DAG: declare dllimport void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv() struct FuncTmplFriend { template<typename T> friend __declspec(dllimport) void funcTmplFriend1(); template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); @@ -406,24 +420,24 @@ template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {} USE(importedFuncTmplDecl<ImplicitInst_Imported>) // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() USE(importedFuncTmpl<ImplicitInst_Imported>) // Import explicit instantiation declaration of an imported function template. // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() +// GNU-DAG: declare void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() +// GO1-DAG: define available_externally void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() extern template void importedFuncTmpl<ExplicitDecl_Imported>(); USE(importedFuncTmpl<ExplicitDecl_Imported>) // Import explicit instantiation definition of an imported function template. // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() +// GNU-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() +// GO1-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() template void importedFuncTmpl<ExplicitInst_Imported>(); USE(importedFuncTmpl<ExplicitInst_Imported>) @@ -442,9 +456,9 @@ USE(importedFuncTmplDecl<ExplicitSpec_Imported>) #endif // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv() template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {} USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>) @@ -462,9 +476,9 @@ USE(importedFuncTmpl<ExplicitSpec_Imported>) #endif // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv() template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>) @@ -481,9 +495,9 @@ USE(importedFuncTmpl<ExplicitSpec_NotImported>) // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"() // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv() -// GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() +// GNU-DAG: declare void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() +// GO1-DAG: define available_externally void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>(); extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>(); USE(funcTmpl<ExplicitDecl_Imported>) @@ -494,11 +508,11 @@ USE(inlineFuncTmpl<ExplicitDecl_Imported>) // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"() // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv() -// GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv() +// GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"() // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv() -// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv() +// GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv() template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>(); template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>(); USE(funcTmpl<ExplicitInst_Imported>) @@ -519,9 +533,9 @@ USE(funcTmpl<ExplicitSpec_Imported>) #endif // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() -// GNU-DAG: declare dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv() +// GNU-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv() // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() -// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv() +// GO1-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv() template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} USE(funcTmpl<ExplicitSpec_InlineDef_Imported>) @@ -658,18 +672,56 @@ namespace PR19933 { // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0 } +namespace PR21355 { + struct __declspec(dllimport) S { + virtual ~S(); + }; + S::~S() {} + + // S::~S is a key function, so we would ordinarily emit a strong definition for + // the vtable. However, S is imported, so the vtable should be too. + + // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*] +} + +namespace PR21366 { + struct __declspec(dllimport) S { + void outOfLineMethod(); + void inlineMethod() {} + inline void anotherInlineMethod(); + void outOfClassInlineMethod(); + }; + void S::anotherInlineMethod() {} + inline void S::outOfClassInlineMethod() {} +} + // MS ignores DLL attributes on partial specializations. template <typename T> struct PartiallySpecializedClassTemplate {}; -template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} }; +template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); }; USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, 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 +// M32-DAG: declare x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ" +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv +// Attributes on explicit specializations are honored. template <typename T> struct ExplicitlySpecializedClassTemplate {}; -template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f() {} }; +template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); }; USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, 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 +// M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv + +// MS inherits DLL attributes to partial specializations. +template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {}; +template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} }; +USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, 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 + +// Attributes on the instantiation take precedence over attributes on the template. +template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} }; +template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>; +USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f); +// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ" + //===----------------------------------------------------------------------===// // Classes with template base classes @@ -677,20 +729,20 @@ USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f); template <typename T> struct ClassTemplate { void func() {} }; template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; -template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void 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 <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { 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 struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; -template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; @@ -703,7 +755,7 @@ USEMEMFUNC(ClassTemplate<int>, func) // ImportedTemplate is explicitly imported. struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {}; USEMEMFUNC(ImportedClassTemplate<int>, func) -// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ" +// M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ" // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv // ExportedTemplate is explicitly exported. @@ -741,8 +793,8 @@ USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func) // Base class already specialized with import attribute. struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func) -// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ" -// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv +// M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ" +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv // Base class already instantiated without dll attribute. struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {}; @@ -759,8 +811,8 @@ USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func) // Base class already instantiated with import attribute. struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {}; USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func) -// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ" -// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv +// M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ" +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv // MS: A dll attribute propagates through multiple levels of instantiation. template <typename T> struct TopClass { void func() {} }; |