From: Nico Rieck Date: Sun, 25 May 2014 10:34:16 +0000 (+0000) Subject: IRGen: Add more tests for dll attributes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6fa6ef4556ad3f31efbb219e03ec77649fca77b3;p=clang IRGen: Add more tests for dll attributes git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209596 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d7b5ba427d..1501be88be 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5056,7 +5056,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // dllimport globals without explicit storage class are treated as extern. We // have to change the storage class this early to get the right DeclContext. if (SC == SC_None && !DC->isRecord() && - hasParsedAttr(S, D, AttributeList::AT_DLLImport)) + hasParsedAttr(S, D, AttributeList::AT_DLLImport) && + !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) SC = SC_Extern; DeclContext *OriginalDC = DC; diff --git a/test/CodeGen/dllexport.c b/test/CodeGen/dllexport.c index 10f8546bcc..4389994943 100644 --- a/test/CodeGen/dllexport.c +++ b/test/CodeGen/dllexport.c @@ -1,8 +1,115 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -std=c99 -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s -#define DLLEXPORT __declspec(dllexport) -inline void DLLEXPORT f() {} -extern void DLLEXPORT f(); -// CHECK: define weak_odr dllexport void @f() +//===----------------------------------------------------------------------===// +// Globals +//===----------------------------------------------------------------------===// + +// Declarations are not exported. +// CHECK-NOT: @ExternGlobalDecl +__declspec(dllexport) extern int ExternGlobalDecl; + +// dllexport implies a definition. +// CHECK-DAG: @GlobalDef = common dllexport global i32 0, align 4 +__declspec(dllexport) int GlobalDef; + +// Export definition. +// CHECK-DAG: @GlobalInit = dllexport global i32 1, align 4 +__declspec(dllexport) int GlobalInit = 1; + +// Declare, then export definition. +// CHECK-DAG: @GlobalDeclInit = dllexport global i32 1, align 4 +__declspec(dllexport) extern int GlobalDeclInit; +int GlobalDeclInit = 1; + +// Redeclarations +// CHECK-DAG: @GlobalRedecl1 = common dllexport global i32 0, align 4 +__declspec(dllexport) extern int GlobalRedecl1; +__declspec(dllexport) int GlobalRedecl1; + +// CHECK-DAG: @GlobalRedecl2 = common dllexport global i32 0, align 4 +__declspec(dllexport) extern int GlobalRedecl2; + int GlobalRedecl2; + + + +//===----------------------------------------------------------------------===// +// Functions +//===----------------------------------------------------------------------===// + +// Declarations are not exported. + +// Export function definition. +// CHECK-DAG: define dllexport void @def() +__declspec(dllexport) void def(void) {} + +// Export inline function. +// CHECK-DAG: define weak_odr dllexport void @inlineFunc() +// CHECK-DAG: define weak_odr dllexport void @externInlineFunc() +__declspec(dllexport) inline void inlineFunc(void) {} +__declspec(dllexport) inline void externInlineFunc(void) {} +extern void externInlineFunc(void); + +// Redeclarations +// CHECK-DAG: define dllexport void @redecl1() +__declspec(dllexport) void redecl1(void); +__declspec(dllexport) void redecl1(void) {} + +// CHECK-DAG: define dllexport void @redecl2() +__declspec(dllexport) void redecl2(void); + void redecl2(void) {} + + + +//===----------------------------------------------------------------------===// +// Precedence +//===----------------------------------------------------------------------===// + +// dllexport takes precedence over the dllimport if both are specified. +// CHECK-DAG: @PrecedenceGlobal1A = common dllexport global i32 0, align 4 +// CHECK-DAG: @PrecedenceGlobal1B = common dllexport global i32 0, align 4 +__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; +__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; + +// CHECK-DAG: @PrecedenceGlobal2A = common dllexport global i32 0, align 4 +// CHECK-DAG: @PrecedenceGlobal2B = common dllexport global i32 0, align 4 +__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; +__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; + +// CHECK-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4 +__declspec(dllexport) extern int PrecedenceGlobalRedecl1; +__declspec(dllimport) int PrecedenceGlobalRedecl1 = 0; + +// CHECK-DAG: @PrecedenceGlobalRedecl2 = common dllexport global i32 0, align 4 +__declspec(dllimport) extern int PrecedenceGlobalRedecl2; +__declspec(dllexport) int PrecedenceGlobalRedecl2; + +// CHECK-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 1, align 4 +__attribute__((dllexport)) extern int PrecedenceGlobalMixed1; +__declspec(dllimport) int PrecedenceGlobalMixed1 = 1; + +// CHECK-DAG: @PrecedenceGlobalMixed2 = common dllexport global i32 0, align 4 +__attribute__((dllimport)) extern int PrecedenceGlobalMixed2; +__declspec(dllexport) int PrecedenceGlobalMixed2; + +// CHECK-DAG: define dllexport void @precedence1A() +// CHECK-DAG: define dllexport void @precedence1B() +void __attribute__((dllimport, dllexport)) precedence1A(void) {} +void __declspec(dllimport) __declspec(dllexport) precedence1B(void) {} + +// CHECK-DAG: define dllexport void @precedence2A() +// CHECK-DAG: define dllexport void @precedence2B() +void __attribute__((dllexport, dllimport)) precedence2A(void) {} +void __declspec(dllexport) __declspec(dllimport) precedence2B(void) {} + +// CHECK-DAG: define dllexport void @precedenceRedecl1() +void __declspec(dllimport) precedenceRedecl1(void); +void __declspec(dllexport) precedenceRedecl1(void) {} + +// CHECK-DAG: define dllexport void @precedenceRedecl2() +void __declspec(dllexport) precedenceRedecl2(void); +void __declspec(dllimport) precedenceRedecl2(void) {} diff --git a/test/CodeGen/dllimport-dllexport.c b/test/CodeGen/dllimport-dllexport.c deleted file mode 100644 index b005e34b78..0000000000 --- a/test/CodeGen/dllimport-dllexport.c +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s - -__attribute__((dllexport)) int bar1 = 2; -// CHECK-LABEL: @bar1 = dllexport global i32 2 -__attribute__((dllimport)) extern int bar2; -// CHECK-LABEL: @bar2 = external dllimport global i32 - -void __attribute__((dllimport)) foo1(); -void __attribute__((dllexport)) foo1(){} -// CHECK-LABEL: define dllexport void @foo1 -void __attribute__((dllexport)) foo2(); - -// PR6269 -__declspec(dllimport) void foo3(); -__declspec(dllexport) void foo3(){} -// CHECK-LABEL: define dllexport void @foo3 -__declspec(dllexport) void foo4(); - -__declspec(dllimport) void foo5(); -// CHECK-LABEL: declare dllimport void @foo5 - -int use() { foo5(); return bar2; } diff --git a/test/CodeGen/dllimport.c b/test/CodeGen/dllimport.c new file mode 100644 index 0000000000..485f6e21b2 --- /dev/null +++ b/test/CodeGen/dllimport.c @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s + +#define JOIN2(x, y) x##y +#define JOIN(x, y) JOIN2(x, y) +#define USEVAR(var) int JOIN(use, __LINE__)() { return var; } +#define USE(func) void JOIN(use, __LINE__)() { func(); } + + + +//===----------------------------------------------------------------------===// +// Globals +//===----------------------------------------------------------------------===// + +// Import declaration. +// CHECK: @ExternGlobalDecl = external dllimport global i32 +__declspec(dllimport) extern int ExternGlobalDecl; +USEVAR(ExternGlobalDecl) + +// dllimport implies a declaration. +// CHECK: @GlobalDecl = external dllimport global i32 +__declspec(dllimport) int GlobalDecl; +USEVAR(GlobalDecl) + +// Redeclarations +// CHECK: @GlobalRedecl1 = external dllimport global i32 +__declspec(dllimport) extern int GlobalRedecl1; +__declspec(dllimport) extern int GlobalRedecl1; +USEVAR(GlobalRedecl1) + +// CHECK: @GlobalRedecl2 = external dllimport global i32 +__declspec(dllimport) int GlobalRedecl2; +__declspec(dllimport) int GlobalRedecl2; +USEVAR(GlobalRedecl2) + +// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC +// and drop the dllimport with a warning. +// CHECK: @GlobalRedecl3 = external global i32 +__declspec(dllimport) extern int GlobalRedecl3; + extern int GlobalRedecl3; // dllimport ignored +USEVAR(GlobalRedecl3) + + + +//===----------------------------------------------------------------------===// +// Functions +//===----------------------------------------------------------------------===// + +// Import function declaration. +// CHECK-DAG: declare dllimport void @decl() +__declspec(dllimport) void decl(void); +USE(decl) + +// Import inline function. +// CHECK-DAG: declare dllimport void @inlineFunc() +// O1-DAG: define available_externally dllimport void @inlineFunc() +__declspec(dllimport) inline void inlineFunc(void) {} +USE(inlineFunc) + +// inline attributes +// CHECK-DAG: declare dllimport void @noinline() +// O1-DAG: define available_externally dllimport void @noinline() +// CHECK-NOT: @alwaysInline() +// O1-NOT: @alwaysInline() +__declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {} +__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {} +USE(noinline) +USE(alwaysInline) + +// Redeclarations +// CHECK-DAG: declare dllimport void @redecl1() +__declspec(dllimport) void redecl1(void); +__declspec(dllimport) void redecl1(void); +USE(redecl1) + +// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC +// and drop the dllimport with a warning. +// CHECK-DAG: declare void @redecl2() +__declspec(dllimport) void redecl2(void); + void redecl2(void); +USE(redecl2) + +// CHECK-DAG: define void @redecl3() +__declspec(dllimport) void redecl3(void); + void redecl3(void) {} // dllimport ignored +USE(redecl3) diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp new file mode 100644 index 0000000000..c4a1d430c3 --- /dev/null +++ b/test/CodeGenCXX/dllexport-members.cpp @@ -0,0 +1,657 @@ +// RUN: %clang_cc1 -triple i686-win32 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s +// RUN: %clang_cc1 -triple x86_64-win32 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-mingw32 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-mingw32 -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s + +// Helper structs to make templates more expressive. +struct ImplicitInst_Exported {}; +struct ExplicitDecl_Exported {}; +struct ExplicitInst_Exported {}; +struct ExplicitSpec_Exported {}; +struct ExplicitSpec_Def_Exported {}; +struct ExplicitSpec_InlineDef_Exported {}; +struct ExplicitSpec_NotExported {}; + +extern "C" void* malloc(__SIZE_TYPE__ size); +extern "C" void free(void* p); + +// Used to force non-trivial special members. +struct ForceNonTrivial { + ForceNonTrivial(); + ~ForceNonTrivial(); + ForceNonTrivial(const ForceNonTrivial&); + ForceNonTrivial& operator=(const ForceNonTrivial&); + ForceNonTrivial(ForceNonTrivial&&); + ForceNonTrivial& operator=(ForceNonTrivial&&); +}; + + + +//===----------------------------------------------------------------------===// +// Class members +//===----------------------------------------------------------------------===// + +// Export individual members of a class. +struct ExportMembers { + struct Nested; + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?normalDef@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define dllexport void @"\01?normalDef@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define weak_odr dllexport void @"\01?normalInclass@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDef@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define weak_odr dllexport void @"\01?normalInlineDef@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDecl@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define weak_odr dllexport void @"\01?normalInlineDecl@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this) + __declspec(dllexport) void normalDef(); + __declspec(dllexport) void normalInclass() {} + __declspec(dllexport) void normalInlineDef(); + __declspec(dllexport) inline void normalInlineDecl(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?virtualDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define dllexport void @"\01?virtualDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInclass@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define weak_odr dllexport void @"\01?virtualInclass@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define weak_odr dllexport void @"\01?virtualInlineDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDecl@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define weak_odr dllexport void @"\01?virtualInlineDecl@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this) + __declspec(dllexport) virtual void virtualDef(); + __declspec(dllexport) virtual void virtualInclass() {} + __declspec(dllexport) virtual void virtualInlineDef(); + __declspec(dllexport) virtual inline void virtualInlineDecl(); + + // MSC-DAG: define dllexport void @"\01?staticDef@ExportMembers@@SAXXZ"() + // MSC-DAG: define weak_odr dllexport void @"\01?staticInclass@ExportMembers@@SAXXZ"() + // MSC-DAG: define weak_odr dllexport void @"\01?staticInlineDef@ExportMembers@@SAXXZ"() + // MSC-DAG: define weak_odr dllexport void @"\01?staticInlineDecl@ExportMembers@@SAXXZ"() + // GNU-DAG: define dllexport void @_ZN13ExportMembers9staticDefEv() + // GNU-DAG: define weak_odr dllexport void @_ZN13ExportMembers13staticInclassEv() + // GNU-DAG: define weak_odr dllexport void @_ZN13ExportMembers15staticInlineDefEv() + // GNU-DAG: define weak_odr dllexport void @_ZN13ExportMembers16staticInlineDeclEv() + __declspec(dllexport) static void staticDef(); + __declspec(dllexport) static void staticInclass() {} + __declspec(dllexport) static void staticInlineDef(); + __declspec(dllexport) static inline void staticInlineDecl(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?protectedDef@ExportMembers@@IAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define dllexport void @"\01?protectedDef@ExportMembers@@IEAAXXZ"(%struct.ExportMembers* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this) + // MSC-DAG: define dllexport void @"\01?protectedStaticDef@ExportMembers@@KAXXZ"() + // GNU-DAG: define dllexport void @_ZN13ExportMembers18protectedStaticDefEv() +protected: + __declspec(dllexport) void protectedDef(); + __declspec(dllexport) static void protectedStaticDef(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?privateDef@ExportMembers@@AAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define dllexport void @"\01?privateDef@ExportMembers@@AEAAXXZ"(%struct.ExportMembers* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this) + // MSC-DAG: define dllexport void @"\01?privateStaticDef@ExportMembers@@CAXXZ"() + // GNU-DAG: define dllexport void @_ZN13ExportMembers16privateStaticDefEv() +private: + __declspec(dllexport) void privateDef(); + __declspec(dllexport) static void privateStaticDef(); + + // M32-DAG: define x86_thiscallcc void @"\01?ignored@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this) + // M64-DAG: define void @"\01?ignored@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this) + // G32-DAG: define x86_thiscallcc void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this) + // G64-DAG: define void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this) +public: + void ignored(); + + // MSC-DAG: @"\01?StaticField@ExportMembers@@2HA" = dllexport global i32 1, align 4 + // MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB" = dllexport constant i32 1, align 4 + // FIXME: These three should be weak_odr. + // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers11StaticFieldE = dllexport global i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE = dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldBraceInitE = dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers14ConstexprFieldE = dllexport constant i32 1, align 4 + __declspec(dllexport) static int StaticField; + __declspec(dllexport) static const int StaticConstField; + __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; + __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; + __declspec(dllexport) constexpr static int ConstexprField = 1; +}; + + void ExportMembers::normalDef() {} +inline void ExportMembers::normalInlineDef() {} + void ExportMembers::normalInlineDecl() {} + void ExportMembers::virtualDef() {} +inline void ExportMembers::virtualInlineDef() {} + void ExportMembers::virtualInlineDecl() {} + void ExportMembers::staticDef() {} +inline void ExportMembers::staticInlineDef() {} + void ExportMembers::staticInlineDecl() {} + void ExportMembers::ignored() {} + void ExportMembers::protectedDef() {} + void ExportMembers::protectedStaticDef() {} + void ExportMembers::privateDef() {} + void ExportMembers::privateStaticDef() {} + + int ExportMembers::StaticField = 1; +const int ExportMembers::StaticConstField = 1; +const int ExportMembers::StaticConstFieldEqualInit; +const int ExportMembers::StaticConstFieldBraceInit; +constexpr int ExportMembers::ConstexprField; + + +// Export individual members of a nested class. +struct ExportMembers::Nested { + // M32-DAG: define dllexport x86_thiscallcc void @"\01?normalDef@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define dllexport void @"\01?normalDef@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define weak_odr dllexport void @"\01?normalInclass@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDef@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define weak_odr dllexport void @"\01?normalInlineDef@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDecl@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define weak_odr dllexport void @"\01?normalInlineDecl@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this) + __declspec(dllexport) void normalDef(); + __declspec(dllexport) void normalInclass() {} + __declspec(dllexport) void normalInlineDef(); + __declspec(dllexport) inline void normalInlineDecl(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?virtualDef@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define dllexport void @"\01?virtualDef@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInclass@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define weak_odr dllexport void @"\01?virtualInclass@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDef@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define weak_odr dllexport void @"\01?virtualInlineDef@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDecl@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define weak_odr dllexport void @"\01?virtualInlineDecl@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this) + __declspec(dllexport) virtual void virtualDef(); + __declspec(dllexport) virtual void virtualInclass() {} + __declspec(dllexport) virtual void virtualInlineDef(); + __declspec(dllexport) virtual inline void virtualInlineDecl(); + + // MSC-DAG: define dllexport void @"\01?staticDef@Nested@ExportMembers@@SAXXZ"() + // MSC-DAG: define weak_odr dllexport void @"\01?staticInclass@Nested@ExportMembers@@SAXXZ"() + // MSC-DAG: define weak_odr dllexport void @"\01?staticInlineDef@Nested@ExportMembers@@SAXXZ"() + // MSC-DAG: define weak_odr dllexport void @"\01?staticInlineDecl@Nested@ExportMembers@@SAXXZ"() + // GNU-DAG: define dllexport void @_ZN13ExportMembers6Nested9staticDefEv() + // GNU-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested13staticInclassEv() + // GNU-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested15staticInlineDefEv() + // GNU-DAG: define weak_odr dllexport void @_ZN13ExportMembers6Nested16staticInlineDeclEv() + __declspec(dllexport) static void staticDef(); + __declspec(dllexport) static void staticInclass() {} + __declspec(dllexport) static void staticInlineDef(); + __declspec(dllexport) static inline void staticInlineDecl(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?protectedDef@Nested@ExportMembers@@IAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define dllexport void @"\01?protectedDef@Nested@ExportMembers@@IEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this) + // MSC-DAG: define dllexport void @"\01?protectedStaticDef@Nested@ExportMembers@@KAXXZ"() + // GNU-DAG: define dllexport void @_ZN13ExportMembers6Nested18protectedStaticDefEv() +protected: + __declspec(dllexport) void protectedDef(); + __declspec(dllexport) static void protectedStaticDef(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01?privateDef@Nested@ExportMembers@@AAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define dllexport void @"\01?privateDef@Nested@ExportMembers@@AEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define dllexport void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this) + // MSC-DAG: define dllexport void @"\01?privateStaticDef@Nested@ExportMembers@@CAXXZ"() + // GNU-DAG: define dllexport void @_ZN13ExportMembers6Nested16privateStaticDefEv() +private: + __declspec(dllexport) void privateDef(); + __declspec(dllexport) static void privateStaticDef(); + + // M32-DAG: define x86_thiscallcc void @"\01?ignored@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this) + // M64-DAG: define void @"\01?ignored@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this) + // G32-DAG: define x86_thiscallcc void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this) + // G64-DAG: define void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this) +public: + void ignored(); + + // MSC-DAG: @"\01?StaticField@Nested@ExportMembers@@2HA" = dllexport global i32 1, align 4 + // MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB" = dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB" = linkonce_odr dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE = dllexport global i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE = dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldBraceInitE = dllexport constant i32 1, align 4 + // GNU-DAG: @_ZN13ExportMembers6Nested14ConstexprFieldE = dllexport constant i32 1, align 4 + __declspec(dllexport) static int StaticField; + __declspec(dllexport) static const int StaticConstField; + __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; + __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; + __declspec(dllexport) constexpr static int ConstexprField = 1; +}; + + void ExportMembers::Nested::normalDef() {} +inline void ExportMembers::Nested::normalInlineDef() {} + void ExportMembers::Nested::normalInlineDecl() {} + void ExportMembers::Nested::virtualDef() {} +inline void ExportMembers::Nested::virtualInlineDef() {} + void ExportMembers::Nested::virtualInlineDecl() {} + void ExportMembers::Nested::staticDef() {} +inline void ExportMembers::Nested::staticInlineDef() {} + void ExportMembers::Nested::staticInlineDecl() {} + void ExportMembers::Nested::ignored() {} + void ExportMembers::Nested::protectedDef() {} + void ExportMembers::Nested::protectedStaticDef() {} + void ExportMembers::Nested::privateDef() {} + void ExportMembers::Nested::privateStaticDef() {} + + int ExportMembers::Nested::StaticField = 1; +const int ExportMembers::Nested::StaticConstField = 1; +const int ExportMembers::Nested::StaticConstFieldEqualInit; +const int ExportMembers::Nested::StaticConstFieldBraceInit; +constexpr int ExportMembers::Nested::ConstexprField; + + +// Export special member functions. +struct ExportSpecials { + // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@XZ"(%struct.ExportSpecials* returned %this) + // M64-DAG: define dllexport %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@XZ"(%struct.ExportSpecials* returned %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this) + __declspec(dllexport) ExportSpecials(); + + // M32-DAG: define dllexport x86_thiscallcc void @"\01??1ExportSpecials@@QAE@XZ"(%struct.ExportSpecials* %this) + // M64-DAG: define dllexport void @"\01??1ExportSpecials@@QEAA@XZ"(%struct.ExportSpecials* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this) + __declspec(dllexport) ~ExportSpecials(); + + // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@ABU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*) + // M64-DAG: define dllexport %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@AEBU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + __declspec(dllexport) ExportSpecials(const ExportSpecials&); + + // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // M64-DAG: define dllexport %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G64-DAG: define dllexport %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&); + + // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@$$QAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*) + // M64-DAG: define dllexport %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials*) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G64-DAG: define dllexport void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + __declspec(dllexport) ExportSpecials(ExportSpecials&&); + + // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // M64-DAG: define dllexport %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + // G64-DAG: define dllexport %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials*) + __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&); +}; +ExportSpecials::ExportSpecials() {} +ExportSpecials::~ExportSpecials() {} +ExportSpecials::ExportSpecials(const ExportSpecials&) {} +ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; } +ExportSpecials::ExportSpecials(ExportSpecials&&) {} +ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; } + + +// Export class with inline special member functions. +struct ExportInlineSpecials { + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@XZ"(%struct.ExportInlineSpecials* returned %this) + // M64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@XZ"( + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1Ev( + // G64-DAG: define weak_odr dllexport void @_ZN20ExportInlineSpecialsC1Ev( + __declspec(dllexport) ExportInlineSpecials() {} + + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportInlineSpecials@@QAE@XZ"( + // M64-DAG: define weak_odr dllexport void @"\01??1ExportInlineSpecials@@QEAA@XZ"( + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsD1Ev( + // G64-DAG: define weak_odr dllexport void @_ZN20ExportInlineSpecialsD1Ev( + __declspec(dllexport) ~ExportInlineSpecials() {} + + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@ABU0@@Z"( + // M64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@AEBU0@@Z"( + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1ERKS_( + // G64-DAG: define weak_odr dllexport void @_ZN20ExportInlineSpecialsC1ERKS_( + __declspec(dllexport) inline ExportInlineSpecials(const ExportInlineSpecials&); + + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@ABU0@@Z"( + // M64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"( + // G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_( + // G64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_( + __declspec(dllexport) ExportInlineSpecials& operator=(const ExportInlineSpecials&); + + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@$$QAU0@@Z"( + // M64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@$$QEAU0@@Z"( + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1EOS_( + // G64-DAG: define weak_odr dllexport void @_ZN20ExportInlineSpecialsC1EOS_( + __declspec(dllexport) ExportInlineSpecials(ExportInlineSpecials&&) {} + + // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@$$QAU0@@Z"( + // M64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"( + // G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_( + // G64-DAG: define weak_odr dllexport %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_( + __declspec(dllexport) ExportInlineSpecials& operator=(ExportInlineSpecials&&) { return *this; } +}; +ExportInlineSpecials::ExportInlineSpecials(const ExportInlineSpecials&) {} +inline ExportInlineSpecials& ExportInlineSpecials::operator=(const ExportInlineSpecials&) { return *this; } + + +// Export defaulted member function definitions. +struct ExportDefaultedDefs { + __declspec(dllexport) ExportDefaultedDefs(); + __declspec(dllexport) ~ExportDefaultedDefs(); + __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&); + __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&); + __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&); + __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&); +}; + +// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@XZ"(%struct.ExportDefaultedDefs* returned %this) +// M64-DAG: define dllexport %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@XZ"(%struct.ExportDefaultedDefs* returned %this) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this) +// G64-DAG: define dllexport void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this) +// G64-DAG: define dllexport void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this) +__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default; + +// M32-DAG: define dllexport x86_thiscallcc void @"\01??1ExportDefaultedDefs@@QAE@XZ"(%struct.ExportDefaultedDefs* %this) +// M64-DAG: define dllexport void @"\01??1ExportDefaultedDefs@@QEAA@XZ"(%struct.ExportDefaultedDefs* %this) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this) +// G64-DAG: define dllexport void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this) +// G64-DAG: define dllexport void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this) +ExportDefaultedDefs::~ExportDefaultedDefs() = default; + +// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*) +// M64-DAG: define weak_odr dllexport %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G64-DAG: define weak_odr dllexport void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G64-DAG: define weak_odr dllexport void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default; + +// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// M64-DAG: define weak_odr dllexport %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G64-DAG: define weak_odr dllexport %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default; + +// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*) +// M64-DAG: define dllexport %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs*) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G64-DAG: define dllexport void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G64-DAG: define dllexport void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default; + +// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// M64-DAG: define dllexport %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +// G64-DAG: define dllexport %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs*) +ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default; + + +// Export allocation functions. +struct ExportAlloc { + __declspec(dllexport) void* operator new(__SIZE_TYPE__); + __declspec(dllexport) void* operator new[](__SIZE_TYPE__); + __declspec(dllexport) void operator delete(void*); + __declspec(dllexport) void operator delete[](void*); +}; + +// M32-DAG: define dllexport i8* @"\01??2ExportAlloc@@SAPAXI@Z"(i32 %n) +// M64-DAG: define dllexport i8* @"\01??2ExportAlloc@@SAPEAX_K@Z"(i64 %n) +// G32-DAG: define dllexport i8* @_ZN11ExportAllocnwEj(i32 %n) +// G64-DAG: define dllexport i8* @_ZN11ExportAllocnwEy(i64 %n) +void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); } + +// M32-DAG: define dllexport i8* @"\01??_UExportAlloc@@SAPAXI@Z"(i32 %n) +// M64-DAG: define dllexport i8* @"\01??_UExportAlloc@@SAPEAX_K@Z"(i64 %n) +// G32-DAG: define dllexport i8* @_ZN11ExportAllocnaEj(i32 %n) +// G64-DAG: define dllexport i8* @_ZN11ExportAllocnaEy(i64 %n) +void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); } + +// M32-DAG: define dllexport void @"\01??3ExportAlloc@@SAXPAX@Z"(i8* %p) +// M64-DAG: define dllexport void @"\01??3ExportAlloc@@SAXPEAX@Z"(i8* %p) +// G32-DAG: define dllexport void @_ZN11ExportAllocdlEPv(i8* %p) +// G64-DAG: define dllexport void @_ZN11ExportAllocdlEPv(i8* %p) +void ExportAlloc::operator delete(void* p) { free(p); } + +// M32-DAG: define dllexport void @"\01??_VExportAlloc@@SAXPAX@Z"(i8* %p) +// M64-DAG: define dllexport void @"\01??_VExportAlloc@@SAXPEAX@Z"(i8* %p) +// G32-DAG: define dllexport void @_ZN11ExportAllocdaEPv(i8* %p) +// G64-DAG: define dllexport void @_ZN11ExportAllocdaEPv(i8* %p) +void ExportAlloc::operator delete[](void* p) { free(p); } + + +//===----------------------------------------------------------------------===// +// Class member templates +//===----------------------------------------------------------------------===// + +struct MemFunTmpl { + template void normalDef() {} + template __declspec(dllexport) void exportedNormal() {} + template static void staticDef() {} + template __declspec(dllexport) static void exportedStatic() {} +}; + +// Export implicit instantiation of an exported member function template. +void useMemFunTmpl() { + // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UImplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) + // M64-DAG: define weak_odr dllexport void @"\01??$exportedNormal@UImplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) + // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this) + // G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this) + MemFunTmpl().exportedNormal(); + + // MSC-DAG: define weak_odr dllexport void @"\01??$exportedStatic@UImplicitInst_Exported@@@MemFunTmpl@@SAXXZ"() + // GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedStaticI21ImplicitInst_ExportedEEvv() + MemFunTmpl().exportedStatic(); +} + + +// Export explicit instantiation declaration of an exported member function +// template. +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define weak_odr dllexport void @"\01??$exportedNormal@UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this) +extern template void MemFunTmpl::exportedNormal(); + template void MemFunTmpl::exportedNormal(); + +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedStatic@UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedStaticI21ExplicitDecl_ExportedEEvv() +extern template void MemFunTmpl::exportedStatic(); + template void MemFunTmpl::exportedStatic(); + + +// Export explicit instantiation definition of an exported member function +// template. +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define weak_odr dllexport void @"\01??$exportedNormal@UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this) +template void MemFunTmpl::exportedNormal(); + +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedStatic@UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedStaticI21ExplicitInst_ExportedEEvv() +template void MemFunTmpl::exportedStatic(); + + +// Export specialization of an exported member function template. +// M32-DAG: define dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define dllexport void @"\01??$exportedNormal@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define dllexport void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this) +template<> __declspec(dllexport) void MemFunTmpl::exportedNormal() {} + +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define weak_odr dllexport void @"\01??$exportedNormal@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this) +template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal() {} + +// MSC-DAG: define dllexport void @"\01??$exportedStatic@UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define dllexport void @_ZN10MemFunTmpl14exportedStaticI25ExplicitSpec_Def_ExportedEEvv() +template<> __declspec(dllexport) void MemFunTmpl::exportedStatic() {} + +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedStatic@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl14exportedStaticI31ExplicitSpec_InlineDef_ExportedEEvv() +template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic() {} + + +// Not exporting specialization of an exported member function template without +// explicit dllexport. +// M32-DAG: define x86_thiscallcc void @"\01??$exportedNormal@UExplicitSpec_NotExported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define void @"\01??$exportedNormal@UExplicitSpec_NotExported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this) +template<> void MemFunTmpl::exportedNormal() {} + +// M32-DAG: define void @"\01??$exportedStatic@UExplicitSpec_NotExported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define void @_ZN10MemFunTmpl14exportedStaticI24ExplicitSpec_NotExportedEEvv() +template<> void MemFunTmpl::exportedStatic() {} + + +// Export explicit instantiation declaration of a non-exported member function +// template. +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define weak_odr dllexport void @"\01??$normalDef@UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this) +extern template __declspec(dllexport) void MemFunTmpl::normalDef(); + template __declspec(dllexport) void MemFunTmpl::normalDef(); + +// M32-DAG: define weak_odr dllexport void @"\01??$staticDef@UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ExportedEEvv() +extern template __declspec(dllexport) void MemFunTmpl::staticDef(); + template __declspec(dllexport) void MemFunTmpl::staticDef(); + + +// Export explicit instantiation definition of a non-exported member function +// template. +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define weak_odr dllexport void @"\01??$normalDef@UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this) +template __declspec(dllexport) void MemFunTmpl::normalDef(); + +// MSC-DAG: define weak_odr dllexport void @"\01??$staticDef@UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ExportedEEvv() +template __declspec(dllexport) void MemFunTmpl::staticDef(); + + +// Export specialization of a non-exported member function template. +// M32-DAG: define dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define dllexport void @"\01??$normalDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define weak_odr dllexport void @"\01??$normalDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define dllexport void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this) +// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this) +template<> __declspec(dllexport) void MemFunTmpl::normalDef() {} +template<> __declspec(dllexport) inline void MemFunTmpl::normalDef() {} + +// MSC-DAG: define dllexport void @"\01??$staticDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"() +// MSC-DAG: define weak_odr dllexport void @"\01??$staticDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define dllexport void @_ZN10MemFunTmpl9staticDefI25ExplicitSpec_Def_ExportedEEvv() +// GNU-DAG: define weak_odr dllexport void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ExportedEEvv() +template<> __declspec(dllexport) void MemFunTmpl::staticDef() {} +template<> __declspec(dllexport) inline void MemFunTmpl::staticDef() {} + + + +struct MemVarTmpl { + template static const int StaticVar = 1; + template __declspec(dllexport) static const int ExportedStaticVar = 1; +}; +template const int MemVarTmpl::StaticVar; +template const int MemVarTmpl::ExportedStaticVar; + +// Export implicit instantiation of an exported member variable template. +// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4 +int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar; } + +// Export explicit instantiation declaration of an exported member variable +// template. +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, align 4 +extern template const int MemVarTmpl::ExportedStaticVar; + template const int MemVarTmpl::ExportedStaticVar; + +// Export explicit instantiation definition of an exported member variable +// template. +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4 +template const int MemVarTmpl::ExportedStaticVar; + +// Export specialization of an exported member variable template. +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI25ExplicitSpec_Def_ExportedEE = dllexport constant i32 1, align 4 +template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar = 1; + +// Not exporting specialization of an exported member variable template without +// explicit dllexport. +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI24ExplicitSpec_NotExportedEE = constant i32 1, align 4 +template<> const int MemVarTmpl::ExportedStaticVar = 1; + + +// Export explicit instantiation declaration of a non-exported member variable +// template. +// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, align 4 +extern template __declspec(dllexport) const int MemVarTmpl::StaticVar; + template __declspec(dllexport) const int MemVarTmpl::StaticVar; + +// Export explicit instantiation definition of a non-exported member variable +// template. +// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4 +template __declspec(dllexport) const int MemVarTmpl::StaticVar; + +// Export specialization of a non-exported member variable template. +// MSC-DAG: @"\01??$StaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI25ExplicitSpec_Def_ExportedEE = dllexport constant i32 1, align 4 +template<> __declspec(dllexport) const int MemVarTmpl::StaticVar = 1; diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index 04413574dc..cd448049c6 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -1,28 +1,449 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -x c++ -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s -#define DLLEXPORT __declspec(dllexport) +// Helper structs to make templates more expressive. +struct ImplicitInst_Exported {}; +struct ExplicitDecl_Exported {}; +struct ExplicitInst_Exported {}; +struct ExplicitSpec_Exported {}; +struct ExplicitSpec_Def_Exported {}; +struct ExplicitSpec_InlineDef_Exported {}; +struct ExplicitSpec_NotExported {}; +struct External { int v; }; -void DLLEXPORT a(); -// CHECK-DAG: declare dllexport void @"\01?a@@YAXXZ"() +#define JOIN2(x, y) x##y +#define JOIN(x, y) JOIN2(x, y) +#define UNIQ(name) JOIN(name, __LINE__) +#define USEVAR(var) int UNIQ(use)() { return var; } +#define USE(func) void UNIQ(use)() { func(); } +#define INSTVAR(var) template int var; +#define INST(func) template void func(); -inline void DLLEXPORT b() {} -// CHECK-DAG: define weak_odr dllexport void @"\01?b@@YAXXZ"() -template void c() {} -template void DLLEXPORT c(); -// CHECK-DAG: define weak_odr dllexport void @"\01??$c@H@@YAXXZ"() +//===----------------------------------------------------------------------===// +// Globals +//===----------------------------------------------------------------------===// -struct S { - void DLLEXPORT a() {} - // CHECK-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ" +// Declarations are not exported. +// MSC-NOT: @"\01?ExternGlobalDecl@@3HA" +// GNU-NOT: @ExternGlobalDecl +__declspec(dllexport) extern int ExternGlobalDecl; - struct T { - void DLLEXPORT a() {} - // CHECK-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ" - }; +// dllexport implies a definition. +// MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @GlobalDef = dllexport global i32 0, align 4 +__declspec(dllexport) int GlobalDef; + +// Export definition. +// MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4 +// GNU-DAG: @GlobalInit1 = dllexport global i32 1, align 4 +__declspec(dllexport) int GlobalInit1 = 1; + +// MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4 +// GNU-DAG: @GlobalInit2 = dllexport global i32 1, align 4 +int __declspec(dllexport) GlobalInit2 = 1; + +// Declare, then export definition. +// MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4 +// GNU-DAG: @GlobalDeclInit = dllexport global i32 1, align 4 +__declspec(dllexport) extern int GlobalDeclInit; +int GlobalDeclInit = 1; + +// Redeclarations +// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @GlobalRedecl1 = dllexport global i32 0, align 4 +__declspec(dllexport) extern int GlobalRedecl1; +__declspec(dllexport) int GlobalRedecl1; + +// MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @GlobalRedecl2 = dllexport global i32 0, align 4 +__declspec(dllexport) extern int GlobalRedecl2; + int GlobalRedecl2; + +// MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @_ZN2ns14ExternalGlobalE = dllexport global i32 0, align 4 +namespace ns { __declspec(dllexport) int ExternalGlobal; } + +// MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4 +// GNU-DAG: @ExternalAutoTypeGlobal = dllexport global %struct.External zeroinitializer, align 4 +__declspec(dllexport) auto ExternalAutoTypeGlobal = External(); + + + +//===----------------------------------------------------------------------===// +// Variable templates +//===----------------------------------------------------------------------===// + +// Declarations are not exported. + +// dllexport implies a definition. +// MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA" +// GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE +template __declspec(dllexport) int VarTmplDef; +INSTVAR(VarTmplDef) + +// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global +// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external dllexport global +template __declspec(dllexport) int VarTmplImplicitDef; +USEVAR(VarTmplImplicitDef) + +// Export definition. +// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template __declspec(dllexport) int VarTmplInit1 = 1; +INSTVAR(VarTmplInit1) + +// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template int __declspec(dllexport) VarTmplInit2 = 1; +INSTVAR(VarTmplInit2) + +// Declare, then export definition. +// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template __declspec(dllexport) extern int VarTmplDeclInit; +template int VarTmplDeclInit = 1; +INSTVAR(VarTmplDeclInit) + +// Redeclarations +// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template __declspec(dllexport) extern int VarTmplRedecl1; +template __declspec(dllexport) int VarTmplRedecl1 = 1; +INSTVAR(VarTmplRedecl1) + +// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template __declspec(dllexport) extern int VarTmplRedecl2; +template int VarTmplRedecl2 = 1; +INSTVAR(VarTmplRedecl2) + +// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, align 4 +namespace ns { template __declspec(dllexport) int ExternalVarTmpl = 1; } +INSTVAR(ns::ExternalVarTmpl) + +// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4 +// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, align 4 +template __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External(); +template External ExternalAutoTypeVarTmpl; + + +template int VarTmpl = 1; +template __declspec(dllexport) int ExportedVarTmpl = 1; + +// Export implicit instantiation of an exported variable template. +// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +USEVAR(ExportedVarTmpl) + +// Export explicit instantiation declaration of an exported variable template. +// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4 +extern template int ExportedVarTmpl; + template int ExportedVarTmpl; + +// Export explicit instantiation definition of an exported variable template. +// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template __declspec(dllexport) int ExportedVarTmpl; + +// Export specialization of an exported variable template. +// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE = dllexport global i32 0, align 4 +template<> __declspec(dllexport) int ExportedVarTmpl; + +// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE = dllexport global i32 1, align 4 +template<> __declspec(dllexport) int ExportedVarTmpl = 1; + +// Not exporting specialization of an exported variable template without +// explicit dllexport. +// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE = global i32 0, align 4 +template<> int ExportedVarTmpl; + + +// Export explicit instantiation declaration of a non-exported variable template. +// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4 +extern template __declspec(dllexport) int VarTmpl; + template __declspec(dllexport) int VarTmpl; + +// Export explicit instantiation definition of a non-exported variable template. +// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 +// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +template __declspec(dllexport) int VarTmpl; + +// Export specialization of a non-exported variable template. +// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE = dllexport global i32 0, align 4 +template<> __declspec(dllexport) int VarTmpl; + +// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4 +// GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE = dllexport global i32 1, align 4 +template<> __declspec(dllexport) int VarTmpl = 1; + + + +//===----------------------------------------------------------------------===// +// Functions +//===----------------------------------------------------------------------===// + +// Declarations are not exported. + +// Export function definition. +// MSC-DAG: define dllexport void @"\01?def@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z3defv() +__declspec(dllexport) void def() {} + +// extern "C" +// MSC-DAG: define dllexport void @externC() +// GNU-DAG: define dllexport void @externC() +extern "C" __declspec(dllexport) void externC() {} + +// Export inline function. +// MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv() +__declspec(dllexport) inline void inlineFunc() {} + +// MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv() +__declspec(dllexport) inline void inlineDecl(); + void inlineDecl() {} + +// MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv() +__declspec(dllexport) void inlineDef(); + inline void inlineDef() {} + +// Redeclarations +// MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z7redecl1v() +__declspec(dllexport) void redecl1(); +__declspec(dllexport) void redecl1() {} + +// MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z7redecl2v() +__declspec(dllexport) void redecl2(); + void redecl2() {} + +// Friend functions +// MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z7friend1v() +// MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z7friend2v() +struct FuncFriend { + friend __declspec(dllexport) void friend1(); + friend __declspec(dllexport) void friend2(); +}; +__declspec(dllexport) void friend1() {} + void friend2() {} + +// Implicit declarations can be redeclared with dllexport. +// MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"( +// GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}( +void* alloc(__SIZE_TYPE__ n); +__declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); } + +// MSC-DAG: define dllexport void @"\01?externalFunc@ns@@YAXXZ"() +// GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv() +namespace ns { __declspec(dllexport) void externalFunc() {} } + + + +//===----------------------------------------------------------------------===// +// Function templates +//===----------------------------------------------------------------------===// + +// Export function template definition. +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv() +template __declspec(dllexport) void funcTmplDef() {} +INST(funcTmplDef) + +// Export inline function template. +// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv() +template __declspec(dllexport) inline void inlineFuncTmpl1() {} +INST(inlineFuncTmpl1) + +// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv() +template inline void __attribute__((dllexport)) inlineFuncTmpl2() {} +INST(inlineFuncTmpl2) + +// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv() +template __declspec(dllexport) inline void inlineFuncTmplDecl(); +template void inlineFuncTmplDecl() {} +INST(inlineFuncTmplDecl) + +// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv() +template __declspec(dllexport) void inlineFuncTmplDef(); +template inline void inlineFuncTmplDef() {} +INST(inlineFuncTmplDef) + + +// Redeclarations +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv() +template __declspec(dllexport) void funcTmplRedecl1(); +template __declspec(dllexport) void funcTmplRedecl1() {} +INST(funcTmplRedecl1) + +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv() +template __declspec(dllexport) void funcTmplRedecl2(); +template void funcTmplRedecl2() {} +INST(funcTmplRedecl2) + +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv() +template __declspec(dllexport) void funcTmplRedecl3(); +template void funcTmplRedecl3() {} +INST(funcTmplRedecl3) + + +// Function template friends +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv() +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv() +struct FuncTmplFriend { + template friend __declspec(dllexport) void funcTmplFriend1(); + template friend __declspec(dllexport) void funcTmplFriend2(); }; +template __declspec(dllexport) void funcTmplFriend1() {} +template void funcTmplFriend2() {} +INST(funcTmplFriend1) +INST(funcTmplFriend2) + +// MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv() +namespace ns { template __declspec(dllexport) void externalFuncTmpl() {} } +INST(ns::externalFuncTmpl) + + +template void funcTmpl() {} +template __declspec(dllexport) void exportedFuncTmpl() {} + +// Export implicit instantiation of an exported function template. +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv() +USE(exportedFuncTmpl) + +// Export explicit instantiation declaration of an exported function template. +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv() +extern template void exportedFuncTmpl(); + template void exportedFuncTmpl(); + +// Export explicit instantiation definition of an exported function template. +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv() +template void exportedFuncTmpl(); + +// Export specialization of an exported function template. +// MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv() +template<> __declspec(dllexport) void exportedFuncTmpl() {} + +// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv() +template<> __declspec(dllexport) inline void exportedFuncTmpl() {} + +// Not exporting specialization of an exported function template without +// explicit dllexport. +// MSC-DAG: define void @"\01??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"() +// GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv() +template<> void exportedFuncTmpl() {} + + +// Export explicit instantiation declaration of a non-exported function template. +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv() +extern template __declspec(dllexport) void funcTmpl(); + template __declspec(dllexport) void funcTmpl(); + +// Export explicit instantiation definition of a non-exported function template. +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv() +template __declspec(dllexport) void funcTmpl(); + +// Export specialization of a non-exported function template. +// MSC-DAG: define dllexport void @"\01??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"() +// GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv() +template<> __declspec(dllexport) void funcTmpl() {} + +// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"() +// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv() +template<> __declspec(dllexport) inline void funcTmpl() {} + + + +//===----------------------------------------------------------------------===// +// Precedence +//===----------------------------------------------------------------------===// + +// dllexport takes precedence over the dllimport if both are specified. +// MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4 +// MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobal1A = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobal1B = dllexport global i32 0, align 4 +__attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // dllimport ignored +__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored + +// MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4 +// MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobal2A = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobal2B = dllexport global i32 0, align 4 +__attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // dllimport ignored +__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored + +// MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4 +__declspec(dllexport) extern int PrecedenceGlobalRedecl1; +__declspec(dllimport) int PrecedenceGlobalRedecl1 = 0; + +// MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobalRedecl2 = dllexport global i32 0, align 4 +__declspec(dllimport) extern int PrecedenceGlobalRedecl2; +__declspec(dllexport) int PrecedenceGlobalRedecl2; + +// MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 0, align 4 +__attribute__((dllexport)) extern int PrecedenceGlobalMixed1; +__declspec(dllimport) int PrecedenceGlobalMixed1 = 0; + +// MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4 +// GNU-DAG: @PrecedenceGlobalMixed2 = dllexport global i32 0, align 4 +__attribute__((dllimport)) extern int PrecedenceGlobalMixed2; +__declspec(dllexport) int PrecedenceGlobalMixed2; + +// MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ" +// MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ" +// GNU-DAG: define dllexport void @_Z12precedence1Av() +// GNU-DAG: define dllexport void @_Z12precedence1Bv() +void __attribute__((dllimport, dllexport)) precedence1A() {} +void __declspec(dllimport) __declspec(dllexport) precedence1B() {} + +// MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ" +// MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ" +// GNU-DAG: define dllexport void @_Z12precedence2Av() +// GNU-DAG: define dllexport void @_Z12precedence2Bv() +void __attribute__((dllexport, dllimport)) precedence2A() {} +void __declspec(dllexport) __declspec(dllimport) precedence2B() {} +// MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ" +// GNU-DAG: define dllexport void @_Z17precedenceRedecl1v() +void __declspec(dllimport) precedenceRedecl1(); +void __declspec(dllexport) precedenceRedecl1() {} -void user() { - a(); -} +// MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ" +// GNU-DAG: define dllexport void @_Z17precedenceRedecl2v() +void __declspec(dllexport) precedenceRedecl2(); +void __declspec(dllimport) precedenceRedecl2() {} diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp new file mode 100644 index 0000000000..63ce989333 --- /dev/null +++ b/test/CodeGenCXX/dllimport-members.cpp @@ -0,0 +1,886 @@ +// RUN: %clang_cc1 -triple i686-windows-msvc -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 -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O1 -o - %s | FileCheck --check-prefix=GO1 %s + +// Helper structs to make templates more expressive. +struct ImplicitInst_Imported {}; +struct ExplicitDecl_Imported {}; +struct ExplicitInst_Imported {}; +struct ExplicitSpec_Imported {}; +struct ExplicitSpec_Def_Imported {}; +struct ExplicitSpec_InlineDef_Imported {}; +struct ExplicitSpec_NotImported {}; + +#define JOIN2(x, y) x##y +#define JOIN(x, y) JOIN2(x, y) +#define UNIQ(name) JOIN(name, __LINE__) +#define USE(func) void UNIQ(use)() { func(); } +#define USEMV(cls, var) int UNIQ(use)() { return ref(cls::var); } +#define USEMF(cls, fun) template<> void useMemFun<__LINE__, cls>() { cls().fun(); } +#define USESPECIALS(cls) void UNIQ(use)() { useSpecials(); } + +template +T ref(T const& v) { return v; } + +template +void useMemFun(); + +template +void useSpecials() { + T v; // Default constructor + + T c1(static_cast(v)); // Copy constructor + T c2 = static_cast(v); // Copy constructor + T c3; + c3 = static_cast(v); // Copy assignment + + T m1(static_cast(v)); // Move constructor + T m2 = static_cast(v); // Move constructor + T m3; + m3 = static_cast(v); // Move assignment +} + +// Used to force non-trivial special members. +struct ForceNonTrivial { + ForceNonTrivial(); + ~ForceNonTrivial(); + ForceNonTrivial(const ForceNonTrivial&); + ForceNonTrivial& operator=(const ForceNonTrivial&); + ForceNonTrivial(ForceNonTrivial&&); + ForceNonTrivial& operator=(ForceNonTrivial&&); +}; + + + +//===----------------------------------------------------------------------===// +// Class members +//===----------------------------------------------------------------------===// + +// Import individual members of a class. +struct ImportMembers { + struct Nested; + + // M32-DAG: define x86_thiscallcc void @"\01?normalDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers* %this) + // M64-DAG: define void @"\01?normalDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers* %this) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?normalDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass@ImportMembers@@QAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?normalInclass@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?normalInlineDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?normalInlineDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*) + // G32-DAG: define x86_thiscallcc void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this) + // G64-DAG: define void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInclass@ImportMembers@@QAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDef@ImportMembers@@QAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDecl@ImportMembers@@QAEXXZ"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv( + __declspec(dllimport) void normalDef(); // dllimport ignored + __declspec(dllimport) void normalDecl(); + __declspec(dllimport) void normalInclass() {} + __declspec(dllimport) void normalInlineDef(); + __declspec(dllimport) inline void normalInlineDecl(); + + // M32-DAG: define x86_thiscallcc void @"\01?virtualDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers* %this) + // M64-DAG: define void @"\01?virtualDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers* %this) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?virtualDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass@ImportMembers@@UAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?virtualInclass@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?virtualInlineDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?virtualInlineDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*) + // G32-DAG: define x86_thiscallcc void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this) + // G64-DAG: define void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInclass@ImportMembers@@UAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDef@ImportMembers@@UAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDecl@ImportMembers@@UAEXXZ"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv( + __declspec(dllimport) virtual void virtualDef(); // dllimport ignored + __declspec(dllimport) virtual void virtualDecl(); + __declspec(dllimport) virtual void virtualInclass() {} + __declspec(dllimport) virtual void virtualInlineDef(); + __declspec(dllimport) virtual inline void virtualInlineDecl(); + + // MSC-DAG: define void @"\01?staticDef@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticDecl@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticInclass@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticInlineDef@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticInlineDecl@ImportMembers@@SAXXZ"() + // GNU-DAG: define void @_ZN13ImportMembers9staticDefEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers10staticDeclEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers13staticInclassEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers15staticInlineDefEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers16staticInlineDeclEv() + // MO1-DAG: define available_externally dllimport void @"\01?staticInclass@ImportMembers@@SAXXZ"() + // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDef@ImportMembers@@SAXXZ"() + // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDecl@ImportMembers@@SAXXZ"() + // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers13staticInclassEv() + // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers15staticInlineDefEv() + // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers16staticInlineDeclEv() + __declspec(dllimport) static void staticDef(); // dllimport ignored + __declspec(dllimport) static void staticDecl(); + __declspec(dllimport) static void staticInclass() {} + __declspec(dllimport) static void staticInlineDef(); + __declspec(dllimport) static inline void staticInlineDecl(); + + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?protectedNormalDecl@ImportMembers@@IAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?protectedNormalDecl@ImportMembers@@IEAAXXZ"(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*) + // MSC-DAG: declare dllimport void @"\01?protectedStaticDecl@ImportMembers@@KAXXZ"() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers19protectedStaticDeclEv() +protected: + __declspec(dllimport) void protectedNormalDecl(); + __declspec(dllimport) static void protectedStaticDecl(); + + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?privateNormalDecl@ImportMembers@@AAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare dllimport void @"\01?privateNormalDecl@ImportMembers@@AEAAXXZ"(%struct.ImportMembers*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*) + // MSC-DAG: declare dllimport void @"\01?privateStaticDecl@ImportMembers@@CAXXZ"() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers17privateStaticDeclEv() +private: + __declspec(dllimport) void privateNormalDecl(); + __declspec(dllimport) static void privateStaticDecl(); + + // M32-DAG: declare x86_thiscallcc void @"\01?ignored@ImportMembers@@QAEXXZ"(%struct.ImportMembers*) + // M64-DAG: declare void @"\01?ignored@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*) + // G32-DAG: declare x86_thiscallcc void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*) + // G64-DAG: declare void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*) +public: + void ignored(); + + // MSC-DAG: @"\01?StaticField@ImportMembers@@2HA" = external dllimport global i32 + // MSC-DAG: @"\01?StaticConstField@ImportMembers@@2HB" = external dllimport constant i32 + // MSC-DAG-FIXME: @"\01?StaticConstFieldEqualInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4 + // MSC-DAG-FIXME: @"\01?StaticConstFieldBraceInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4 + // MSC-DAG-FIXME: @"\01?ConstexprField@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4 + // GNU-DAG: @_ZN13ImportMembers11StaticFieldE = external dllimport global i32 + // GNU-DAG: @_ZN13ImportMembers16StaticConstFieldE = external dllimport constant i32 + // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldEqualInitE = external dllimport constant i32 + // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldBraceInitE = external dllimport constant i32 + // GNU-DAG: @_ZN13ImportMembers14ConstexprFieldE = external dllimport constant i32 + __declspec(dllimport) static int StaticField; + __declspec(dllimport) static const int StaticConstField; + #ifndef MSABI // FIXME + __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; + __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; + __declspec(dllimport) constexpr static int ConstexprField = 1; + #endif + + template friend void useMemFun(); +}; + + void ImportMembers::normalDef() {} // dllimport ignored +inline void ImportMembers::normalInlineDef() {} + void ImportMembers::normalInlineDecl() {} + void ImportMembers::virtualDef() {} // dllimport ignored +inline void ImportMembers::virtualInlineDef() {} + void ImportMembers::virtualInlineDecl() {} + void ImportMembers::staticDef() {} // dllimport ignored +inline void ImportMembers::staticInlineDef() {} + void ImportMembers::staticInlineDecl() {} + +USEMF(ImportMembers, normalDef) +USEMF(ImportMembers, normalDecl) +USEMF(ImportMembers, normalInclass) +USEMF(ImportMembers, normalInlineDef) +USEMF(ImportMembers, normalInlineDecl) +USEMF(ImportMembers, virtualDef) +USEMF(ImportMembers, virtualDecl) +USEMF(ImportMembers, virtualInclass) +USEMF(ImportMembers, virtualInlineDef) +USEMF(ImportMembers, virtualInlineDecl) +USEMF(ImportMembers, staticDef) +USEMF(ImportMembers, staticDecl) +USEMF(ImportMembers, staticInclass) +USEMF(ImportMembers, staticInlineDef) +USEMF(ImportMembers, staticInlineDecl) +USEMF(ImportMembers, protectedNormalDecl) +USEMF(ImportMembers, protectedStaticDecl) +USEMF(ImportMembers, privateNormalDecl) +USEMF(ImportMembers, privateStaticDecl) +USEMF(ImportMembers, ignored) + +USEMV(ImportMembers, StaticField) +USEMV(ImportMembers, StaticConstField) +#ifndef MSABI // FIXME +USEMV(ImportMembers, StaticConstFieldEqualInit) +USEMV(ImportMembers, StaticConstFieldBraceInit) +USEMV(ImportMembers, ConstexprField) +#endif + + +// Import individual members of a nested class. +struct ImportMembers::Nested { + // M32-DAG: define x86_thiscallcc void @"\01?normalDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"* %this) + // M64-DAG: define void @"\01?normalDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"* %this) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?normalDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?normalInclass@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?normalInlineDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?normalInlineDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*) + // G32-DAG: define x86_thiscallcc void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this) + // G64-DAG: define void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInclass@Nested@ImportMembers@@QAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDef@Nested@ImportMembers@@QAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDecl@Nested@ImportMembers@@QAEXXZ"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv( + __declspec(dllimport) void normalDef(); // dllimport ignored + __declspec(dllimport) void normalDecl(); + __declspec(dllimport) void normalInclass() {} + __declspec(dllimport) void normalInlineDef(); + __declspec(dllimport) inline void normalInlineDecl(); + + // M32-DAG: define x86_thiscallcc void @"\01?virtualDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"* %this) + // M64-DAG: define void @"\01?virtualDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"* %this) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?virtualDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?virtualInclass@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?virtualInlineDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*) + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?virtualInlineDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*) + // G32-DAG: define x86_thiscallcc void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this) + // G64-DAG: define void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"*) + + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInclass@Nested@ImportMembers@@UAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDef@Nested@ImportMembers@@UAEXXZ"( + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDecl@Nested@ImportMembers@@UAEXXZ"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv( + __declspec(dllimport) virtual void virtualDef(); // dllimport ignored + __declspec(dllimport) virtual void virtualDecl(); + __declspec(dllimport) virtual void virtualInclass() {} + __declspec(dllimport) virtual void virtualInlineDef(); + __declspec(dllimport) virtual inline void virtualInlineDecl(); + + // MSC-DAG: define void @"\01?staticDef@Nested@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticDecl@Nested@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticInclass@Nested@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticInlineDef@Nested@ImportMembers@@SAXXZ"() + // MSC-DAG: declare dllimport void @"\01?staticInlineDecl@Nested@ImportMembers@@SAXXZ"() + // GNU-DAG: define void @_ZN13ImportMembers6Nested9staticDefEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested10staticDeclEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested13staticInclassEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested15staticInlineDefEv() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested16staticInlineDeclEv() + // MO1-DAG: define available_externally dllimport void @"\01?staticInclass@Nested@ImportMembers@@SAXXZ"() + // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDef@Nested@ImportMembers@@SAXXZ"() + // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDecl@Nested@ImportMembers@@SAXXZ"() + // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested13staticInclassEv() + // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested15staticInlineDefEv() + // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested16staticInlineDeclEv() + __declspec(dllimport) static void staticDef(); // dllimport ignored + __declspec(dllimport) static void staticDecl(); + __declspec(dllimport) static void staticInclass() {} + __declspec(dllimport) static void staticInlineDef(); + __declspec(dllimport) static inline void staticInlineDecl(); + + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?protectedNormalDecl@Nested@ImportMembers@@IAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?protectedNormalDecl@Nested@ImportMembers@@IEAAXXZ"(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*) + // MSC-DAG: declare dllimport void @"\01?protectedStaticDecl@Nested@ImportMembers@@KAXXZ"() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested19protectedStaticDeclEv() +protected: + __declspec(dllimport) void protectedNormalDecl(); + __declspec(dllimport) static void protectedStaticDecl(); + + // M32-DAG: declare dllimport x86_thiscallcc void @"\01?privateNormalDecl@Nested@ImportMembers@@AAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare dllimport void @"\01?privateNormalDecl@Nested@ImportMembers@@AEAAXXZ"(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare dllimport void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*) + // MSC-DAG: declare dllimport void @"\01?privateStaticDecl@Nested@ImportMembers@@CAXXZ"() + // GNU-DAG: declare dllimport void @_ZN13ImportMembers6Nested17privateStaticDeclEv() +private: + __declspec(dllimport) void privateNormalDecl(); + __declspec(dllimport) static void privateStaticDecl(); + + // M32-DAG: declare x86_thiscallcc void @"\01?ignored@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*) + // M64-DAG: declare void @"\01?ignored@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*) + // G32-DAG: declare x86_thiscallcc void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*) + // G64-DAG: declare void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*) +public: + void ignored(); + + // MSC-DAG: @"\01?StaticField@Nested@ImportMembers@@2HA" = external dllimport global i32 + // MSC-DAG: @"\01?StaticConstField@Nested@ImportMembers@@2HB" = external dllimport constant i32 + // MSC-DAG-FIXME: @"\01?StaticConstFieldEqualInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4 + // MSC-DAG-FIXME: @"\01?StaticConstFieldBraceInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4 + // MSC-DAG-FIXME: @"\01?ConstexprField@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4 + // GNU-DAG: @_ZN13ImportMembers6Nested11StaticFieldE = external dllimport global i32 + // GNU-DAG: @_ZN13ImportMembers6Nested16StaticConstFieldE = external dllimport constant i32 + // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldEqualInitE = external dllimport constant i32 + // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldBraceInitE = external dllimport constant i32 + // GNU-DAG: @_ZN13ImportMembers6Nested14ConstexprFieldE = external dllimport constant i32 + __declspec(dllimport) static int StaticField; + __declspec(dllimport) static const int StaticConstField; + #ifndef MSABI // FIXME + __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; + __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; + __declspec(dllimport) constexpr static int ConstexprField = 1; + #endif + + template friend void useMemFun(); +}; + + void ImportMembers::Nested::normalDef() {} // dllimport ignored +inline void ImportMembers::Nested::normalInlineDef() {} + void ImportMembers::Nested::normalInlineDecl() {} + void ImportMembers::Nested::virtualDef() {} // dllimport ignored +inline void ImportMembers::Nested::virtualInlineDef() {} + void ImportMembers::Nested::virtualInlineDecl() {} + void ImportMembers::Nested::staticDef() {} // dllimport ignored +inline void ImportMembers::Nested::staticInlineDef() {} + void ImportMembers::Nested::staticInlineDecl() {} + +USEMF(ImportMembers::Nested, normalDef) +USEMF(ImportMembers::Nested, normalDecl) +USEMF(ImportMembers::Nested, normalInclass) +USEMF(ImportMembers::Nested, normalInlineDef) +USEMF(ImportMembers::Nested, normalInlineDecl) +USEMF(ImportMembers::Nested, virtualDef) +USEMF(ImportMembers::Nested, virtualDecl) +USEMF(ImportMembers::Nested, virtualInclass) +USEMF(ImportMembers::Nested, virtualInlineDef) +USEMF(ImportMembers::Nested, virtualInlineDecl) +USEMF(ImportMembers::Nested, staticDef) +USEMF(ImportMembers::Nested, staticDecl) +USEMF(ImportMembers::Nested, staticInclass) +USEMF(ImportMembers::Nested, staticInlineDef) +USEMF(ImportMembers::Nested, staticInlineDecl) +USEMF(ImportMembers::Nested, protectedNormalDecl) +USEMF(ImportMembers::Nested, protectedStaticDecl) +USEMF(ImportMembers::Nested, privateNormalDecl) +USEMF(ImportMembers::Nested, privateStaticDecl) +USEMF(ImportMembers::Nested, ignored) + +USEMV(ImportMembers::Nested, StaticField) +USEMV(ImportMembers::Nested, StaticConstField) +#ifndef MSABI // FIXME +USEMV(ImportMembers::Nested, StaticConstFieldEqualInit) +USEMV(ImportMembers::Nested, StaticConstFieldBraceInit) +USEMV(ImportMembers::Nested, ConstexprField) +#endif + + +// Import special member functions. +struct ImportSpecials { + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@XZ"(%struct.ImportSpecials* returned) + // M64-DAG: declare dllimport %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials* returned) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*) + // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*) + __declspec(dllimport) ImportSpecials(); + + // FIXME: MSVC emits ??1ImportSpecials@@{{QAE|QEAA}}@XZ here. + // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportSpecials@@QAE@XZ"(%struct.ImportSpecials*) + // M64-DAG: declare dllimport void @"\01??_DImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*) + // G64-DAG: declare dllimport void @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*) + __declspec(dllimport) ~ImportSpecials() {} + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@ABU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*) + // M64-DAG: declare dllimport %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@AEBU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + __declspec(dllimport) ImportSpecials(const ImportSpecials&); + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*) + // M64-DAG: declare dllimport %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + // G64-DAG: declare dllimport %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&); + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@$$QAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*) + // M64-DAG: declare dllimport %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + // G64-DAG: declare dllimport void @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + __declspec(dllimport) ImportSpecials(ImportSpecials&&); + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*) + // M64-DAG: declare dllimport %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + // G64-DAG: declare dllimport %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials*) + __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&); +}; +USESPECIALS(ImportSpecials) + + +// Export inline special member functions. +struct ImportInlineSpecials { + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials* returned) + // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials* returned) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials*) + // G64-DAG: declare dllimport void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@XZ"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev( + __declspec(dllimport) ImportInlineSpecials() {} + + // FIXME: MSVC emits ??1ImportInlineSpecials@@{{QAE|QEAA}}@XZ here. + // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*) + // M64-DAG: declare dllimport void @"\01??_DImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*) + // G64-DAG: declare dllimport void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE@XZ"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev( + __declspec(dllimport) ~ImportInlineSpecials() {} + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*) + // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@AEBU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // G64-DAG: declare dllimport void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_( + __declspec(dllimport) inline ImportInlineSpecials(const ImportInlineSpecials&); + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // G64-DAG: declare dllimport %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_( + __declspec(dllimport) ImportInlineSpecials& operator=(const ImportInlineSpecials&); + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*) + // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // G64-DAG: declare dllimport void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_( + __declspec(dllimport) ImportInlineSpecials(ImportInlineSpecials&&) {} + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // M64-DAG: declare dllimport %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // G64-DAG: declare dllimport %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"( + // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_( + __declspec(dllimport) ImportInlineSpecials& operator=(ImportInlineSpecials&&) { return *this; } +}; +ImportInlineSpecials::ImportInlineSpecials(const ImportInlineSpecials&) {} +inline ImportInlineSpecials& ImportInlineSpecials::operator=(const ImportInlineSpecials&) { return *this; } +USESPECIALS(ImportInlineSpecials) + + +// Import defaulted member functions. +struct ImportDefaulted { + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* returned) + // M64-DAG: declare dllimport %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted* returned) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted*) + // G64-DAG: declare dllimport void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* returned %this) + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this) + __declspec(dllimport) ImportDefaulted() = default; + + // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*) + // M64-DAG: declare dllimport void @"\01??_DImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*) + // G64-DAG: declare dllimport void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this) + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this) + __declspec(dllimport) ~ImportDefaulted() = default; + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*) + // M64-DAG: declare dllimport %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@AEBU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // G64-DAG: declare dllimport void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted*) + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*) + __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default; + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // M64-DAG: declare dllimport %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // G64-DAG: declare dllimport %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*) + // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*) + __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default; + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*) + // M64-DAG: declare dllimport %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted*) + // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // G64-DAG: declare dllimport void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted*) + // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*) + __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default; + + // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // M64-DAG: declare dllimport %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // G64-DAG: declare dllimport %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted*) + // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*) + // GO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted*) + __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default; + + ForceNonTrivial v; // ensure special members are non-trivial +}; +USESPECIALS(ImportDefaulted) + + +// Import defaulted member function definitions. +struct ImportDefaultedDefs { + __declspec(dllimport) inline ImportDefaultedDefs(); + __declspec(dllimport) inline ~ImportDefaultedDefs(); + + __declspec(dllimport) ImportDefaultedDefs(const ImportDefaultedDefs&); + __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&); + + __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&); + __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&); +}; + +// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs* returned) +// M64-DAG: declare dllimport %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs* returned) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*) +// G64-DAG: declare dllimport void @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*) +__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; + +// FIXME: MSVC emits ??1ImportDefaultedDefs@@{{QAE|QEAA}}@XZ here. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*) +// M64-DAG: declare dllimport void @"\01??_DImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*) +// G64-DAG: declare dllimport void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*) +__declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default; + +// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs*) +// M64-DAG: declare dllimport %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*) +// G64-DAG: declare dllimport void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*) +inline ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default; + +// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*) +// M64-DAG: declare dllimport %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*) +// G32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*) +// G64-DAG: declare dllimport %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs*) +inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default; + +// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs*) +// M64-DAG: define %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs*) +// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +// G64-DAG: define void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +// G64-DAG: define void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // dllimport ignored + +// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +// M64-DAG: define %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +// G32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +// G64-DAG: define %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs*) +ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // dllimport ignored + +USESPECIALS(ImportDefaultedDefs) + + +// Import allocation functions. +struct ImportAlloc { + __declspec(dllimport) void* operator new(__SIZE_TYPE__); + __declspec(dllimport) void* operator new[](__SIZE_TYPE__); + __declspec(dllimport) void operator delete(void*); + __declspec(dllimport) void operator delete[](void*); +}; + +// M32-DAG: declare dllimport i8* @"\01??2ImportAlloc@@SAPAXI@Z"(i32) +// M64-DAG: declare dllimport i8* @"\01??2ImportAlloc@@SAPEAX_K@Z"(i64) +// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnwEj(i32) +// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnwEy(i64) +void UNIQ(use)() { new ImportAlloc(); } + +// M32-DAG: declare dllimport i8* @"\01??_UImportAlloc@@SAPAXI@Z"(i32) +// M64-DAG: declare dllimport i8* @"\01??_UImportAlloc@@SAPEAX_K@Z"(i64) +// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnaEj(i32) +// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnaEy(i64) +void UNIQ(use)() { new ImportAlloc[1]; } + +// M32-DAG: declare dllimport void @"\01??3ImportAlloc@@SAXPAX@Z"(i8*) +// M64-DAG: declare dllimport void @"\01??3ImportAlloc@@SAXPEAX@Z"(i8*) +// G32-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*) +// G64-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*) +void UNIQ(use)(ImportAlloc* ptr) { delete ptr; } + +// M32-DAG: declare dllimport void @"\01??_VImportAlloc@@SAXPAX@Z"(i8*) +// M64-DAG: declare dllimport void @"\01??_VImportAlloc@@SAXPEAX@Z"(i8*) +// G32-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*) +// G64-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*) +void UNIQ(use)(ImportAlloc* ptr) { delete[] ptr; } + + +//===----------------------------------------------------------------------===// +// Class member templates +//===----------------------------------------------------------------------===// + +struct MemFunTmpl { + template void normalDef() {} + template __declspec(dllimport) void importedNormal() {} + template static void staticDef() {} + template __declspec(dllimport) static void importedStatic() {} +}; + +// Import implicit instantiation of an imported member function template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UImplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$importedNormal@UImplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl*) +USEMF(MemFunTmpl, importedNormal) + +// MSC-DAG: declare dllimport void @"\01??$importedStatic@UImplicitInst_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl14importedStaticI21ImplicitInst_ImportedEEvv() +USE(MemFunTmpl::importedStatic) + + +// Import explicit instantiation declaration of an imported member function +// template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$importedNormal@UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*) +extern template void MemFunTmpl::importedNormal(); +USEMF(MemFunTmpl, importedNormal) + +// MSC-DAG: declare dllimport void @"\01??$importedStatic@UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl14importedStaticI21ExplicitDecl_ImportedEEvv() +extern template void MemFunTmpl::importedStatic(); +USE(MemFunTmpl::importedStatic) + + +// Import explicit instantiation definition of an imported member function +// template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$importedNormal@UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*) +template void MemFunTmpl::importedNormal(); +USEMF(MemFunTmpl, importedNormal) + +// MSC-DAG: declare dllimport void @"\01??$importedStatic@UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl14importedStaticI21ExplicitInst_ImportedEEvv() +template void MemFunTmpl::importedStatic(); +USE(MemFunTmpl::importedStatic) + + +// Import specialization of an imported member function template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$importedNormal@UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*) +template<> __declspec(dllimport) void MemFunTmpl::importedNormal(); +USEMF(MemFunTmpl, importedNormal) + +// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG-FIXME: declare dllimport void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +#ifdef MSABI +//template<> __declspec(dllimport) void MemFunTmpl::importedNormal() {} +//USEMF(MemFunTmpl, importedNormal) +#endif + +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*) +template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal() {} +USEMF(MemFunTmpl, importedNormal) + + +// MSC-DAG: declare dllimport void @"\01??$importedStatic@UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl14importedStaticI21ExplicitSpec_ImportedEEvv() +template<> __declspec(dllimport) void MemFunTmpl::importedStatic(); +USE(MemFunTmpl::importedStatic) + +// MSC-DAG-FIXME: declare dllimport void @"\01??$importedStatic@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"() +#ifdef MSABI +//template<> __declspec(dllimport) void MemFunTmpl::importedStatic() {} +//USE(MemFunTmpl::importedStatic) +#endif + +// MSC-DAG: declare dllimport void @"\01??$importedStatic@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl14importedStaticI31ExplicitSpec_InlineDef_ImportedEEvv() +template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic() {} +USE(MemFunTmpl::importedStatic) + + +// Not importing specialization of an imported member function template without +// explicit dllimport. +// M32-DAG: define x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_NotImported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this) +// M64-DAG: define void @"\01??$importedNormal@UExplicitSpec_NotImported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this) +// G32-DAG: define x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this) +// G64-DAG: define void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this) +template<> void MemFunTmpl::importedNormal() {} +USEMF(MemFunTmpl, importedNormal) + +// MSC-DAG: define void @"\01??$importedStatic@UExplicitSpec_NotImported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: define void @_ZN10MemFunTmpl14importedStaticI24ExplicitSpec_NotImportedEEvv() +template<> void MemFunTmpl::importedStatic() {} +USE(MemFunTmpl::importedStatic) + + +// Import explicit instantiation declaration of a non-imported member function +// template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$normalDef@UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*) +extern template __declspec(dllimport) void MemFunTmpl::normalDef(); +USEMF(MemFunTmpl, normalDef) + +// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ImportedEEvv() +extern template __declspec(dllimport) void MemFunTmpl::staticDef(); +USE(MemFunTmpl::staticDef) + + +// Import explicit instantiation definition of a non-imported member function +// template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$normalDef@UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*) +template __declspec(dllimport) void MemFunTmpl::normalDef(); +USEMF(MemFunTmpl, normalDef) + +// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ImportedEEvv() +template __declspec(dllimport) void MemFunTmpl::staticDef(); +USE(MemFunTmpl::staticDef) + + +// Import specialization of a non-imported member function template. +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$normalDef@UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*) +template<> __declspec(dllimport) void MemFunTmpl::normalDef(); +USEMF(MemFunTmpl, normalDef) + +// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG-FIXME: declare dllimport void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +#ifdef MSABI +//template<> __declspec(dllimport) void MemFunTmpl::normalDef() {} +//USEMF(MemFunTmpl, normalDef) +#endif + +// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*) +// M64-DAG: declare dllimport void @"\01??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*) +// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*) +// G64-DAG: declare dllimport void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*) +template<> __declspec(dllimport) inline void MemFunTmpl::normalDef() {} +USEMF(MemFunTmpl, normalDef) + + +// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI21ExplicitSpec_ImportedEEvv() +template<> __declspec(dllimport) void MemFunTmpl::staticDef(); +USE(MemFunTmpl::staticDef) + +// MSC-DAG-FIXME: declare dllimport void @"\01??$staticDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"() +#ifdef MSABI +//template<> __declspec(dllimport) void MemFunTmpl::staticDef() {} +//USE(MemFunTmpl::staticDef) +#endif + +// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"() +// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ImportedEEvv() +template<> __declspec(dllimport) inline void MemFunTmpl::staticDef() {} +USE(MemFunTmpl::staticDef) + + + +struct MemVarTmpl { + template static const int StaticVar = 1; + template __declspec(dllimport) static const int ImportedStaticVar = 1; +}; + +// Import implicit instantiation of an imported member variable template. +// MSC-DAG: @"\01??$ImportedStaticVar@UImplicitInst_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ImplicitInst_ImportedEE = external dllimport constant i32 +USEMV(MemVarTmpl, ImportedStaticVar) + +// Import explicit instantiation declaration of an imported member variable +// template. +// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32 +// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32 +extern template const int MemVarTmpl::ImportedStaticVar; +USEMV(MemVarTmpl, ImportedStaticVar) + +// An explicit instantiation definition of an imported member variable template +// cannot be imported because the template must be defined which is illegal. The +// in-class initializer does not count. + +// Import specialization of an imported member variable template. +// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32 +// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitSpec_ImportedEE = external dllimport constant i32 +template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar; +USEMV(MemVarTmpl, ImportedStaticVar) + +// Not importing specialization of a member variable template without explicit +// dllimport. +// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitSpec_NotImported@@@MemVarTmpl@@2HB" = external constant i32 +// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE = external constant i32 +template<> const int MemVarTmpl::ImportedStaticVar; +USEMV(MemVarTmpl, ImportedStaticVar) + + +// Import explicit instantiation declaration of a non-imported member variable +// template. +// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ImportedEE = external dllimport constant i32 +extern template __declspec(dllimport) const int MemVarTmpl::StaticVar; +USEMV(MemVarTmpl, StaticVar) + +// An explicit instantiation definition of a non-imported member variable template +// cannot be imported because the template must be defined which is illegal. The +// in-class initializer does not count. + +// Import specialization of a non-imported member variable template. +// MSC-DAG: @"\01??$StaticVar@UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitSpec_ImportedEE = external dllimport constant i32 +template<> __declspec(dllimport) const int MemVarTmpl::StaticVar; +USEMV(MemVarTmpl, StaticVar) diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index c4640c1af5..87f3c884ea 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -1,25 +1,503 @@ -// RUN: %clang_cc1 -triple i686-pc-win32 -x c++ -O2 -disable-llvm-optzns -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-msvc -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 -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O1 -o - %s | FileCheck --check-prefix=GO1 %s -#define DLLIMPORT __declspec(dllimport) +// Helper structs to make templates more expressive. +struct ImplicitInst_Imported {}; +struct ImplicitInst_NotImported {}; +struct ExplicitDecl_Imported {}; +struct ExplicitInst_Imported {}; +struct ExplicitSpec_Imported {}; +struct ExplicitSpec_Def_Imported {}; +struct ExplicitSpec_InlineDef_Imported {}; +struct ExplicitSpec_NotImported {}; -void DLLIMPORT a(); -// CHECK-DAG: declare dllimport void @"\01?a@@YAXXZ"() +#define JOIN2(x, y) x##y +#define JOIN(x, y) JOIN2(x, y) +#define UNIQ(name) JOIN(name, __LINE__) +#define USEVARTYPE(type, var) type UNIQ(use)() { return var; } +#define USEVAR(var) USEVARTYPE(int, var) +#define USE(func) void UNIQ(use)() { func(); } -inline void DLLIMPORT b() {} -// CHECK-DAG: define available_externally dllimport void @"\01?b@@YAXXZ"() -template void c() {} -template void DLLIMPORT c(); -// CHECK-DAG: define available_externally dllimport void @"\01??$c@H@@YAXXZ"() -struct S { - void DLLIMPORT a() {} - // CHECK-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@S@@QAEXXZ" +//===----------------------------------------------------------------------===// +// Globals +//===----------------------------------------------------------------------===// + +// Import declaration. +// MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32 +// GNU-DAG: @ExternGlobalDecl = external dllimport global i32 +__declspec(dllimport) extern int ExternGlobalDecl; +USEVAR(ExternGlobalDecl) + +// dllimport implies a declaration. +// MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32 +// GNU-DAG: @GlobalDecl = external dllimport global i32 +__declspec(dllimport) int GlobalDecl; +USEVAR(GlobalDecl) + +// Redeclarations +// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32 +// GNU-DAG: @GlobalRedecl1 = external dllimport global i32 +__declspec(dllimport) extern int GlobalRedecl1; +__declspec(dllimport) extern int GlobalRedecl1; +USEVAR(GlobalRedecl1) + +// MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32 +// GNU-DAG: @GlobalRedecl2a = external dllimport global i32 +__declspec(dllimport) int GlobalRedecl2a; +__declspec(dllimport) int GlobalRedecl2a; +USEVAR(GlobalRedecl2a) + +// M32-DAG: @"\01?GlobalRedecl2b@@3PAHA" = external dllimport global i32* +// M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32* +// GNU-DAG: @GlobalRedecl2b = external dllimport global i32* +int *__attribute__((dllimport)) GlobalRedecl2b; +int *__attribute__((dllimport)) GlobalRedecl2b; +USEVARTYPE(int*, GlobalRedecl2b) + +// MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32 +// GNU-DAG: @GlobalRedecl2c = external dllimport global i32 +int GlobalRedecl2c __attribute__((dllimport)); +int GlobalRedecl2c __attribute__((dllimport)); +USEVAR(GlobalRedecl2c) + +// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC +// and drop the dllimport with a warning. +// MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32 +// GNU-DAG: @GlobalRedecl3 = external global i32 +__declspec(dllimport) extern int GlobalRedecl3; + extern int GlobalRedecl3; // dllimport ignored +USEVAR(GlobalRedecl3) + +// MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = external dllimport global i32 +// GNU-DAG: @_ZN2ns14ExternalGlobalE = external dllimport global i32 +namespace ns { __declspec(dllimport) int ExternalGlobal; } +USEVAR(ns::ExternalGlobal) + + + +//===----------------------------------------------------------------------===// +// Variable templates +//===----------------------------------------------------------------------===// + +// Import declaration. +// MSC-DAG: @"\01??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32 +template __declspec(dllimport) extern int ExternVarTmplDecl; +USEVAR(ExternVarTmplDecl) + +// dllimport implies a declaration. +// MSC-DAG: @"\01??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32 +template __declspec(dllimport) int VarTmplDecl; +USEVAR(VarTmplDecl) + +// Redeclarations +// MSC-DAG: @"\01??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE = external dllimport global i32 +template __declspec(dllimport) extern int VarTmplRedecl1; +template __declspec(dllimport) extern int VarTmplRedecl1; +USEVAR(VarTmplRedecl1) + +// MSC-DAG: @"\01??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE = external dllimport global i32 +template __declspec(dllimport) int VarTmplRedecl2; +template __declspec(dllimport) int VarTmplRedecl2; +USEVAR(VarTmplRedecl2) + +// MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32 +// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32 +template __declspec(dllimport) extern int VarTmplRedecl3; +template extern int VarTmplRedecl3; // dllimport ignored +USEVAR(VarTmplRedecl3) + + +// MSC-DAG: @"\01??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32 +// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE = external dllimport global i32 +namespace ns { template __declspec(dllimport) int ExternalVarTmpl; } +USEVAR(ns::ExternalVarTmpl) + + +template int VarTmpl; +template __declspec(dllimport) int ImportedVarTmpl; + +// Import implicit instantiation of an imported variable template. +// MSC-DAG: @"\01??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE = external dllimport global i32 +USEVAR(ImportedVarTmpl) + +// Import explicit instantiation declaration of an imported variable template. +// MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE = external dllimport global i32 +extern template int ImportedVarTmpl; +USEVAR(ImportedVarTmpl) + +// An explicit instantiation definition of an imported variable template cannot +// be imported because the template must be defined which is illegal. + +// Import specialization of an imported variable template. +// MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE = external dllimport global i32 +template<> __declspec(dllimport) int ImportedVarTmpl; +USEVAR(ImportedVarTmpl) + +// Not importing specialization of an imported variable template without +// explicit dllimport. +// MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4 +// GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE = global i32 0, align 4 +template<> int ImportedVarTmpl; +USEVAR(ImportedVarTmpl) + +// Import explicit instantiation declaration of a non-imported variable template. +// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE = external dllimport global i32 +extern template __declspec(dllimport) int VarTmpl; +USEVAR(VarTmpl) + +// Import explicit instantiation definition of a non-imported variable template. +// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE = external dllimport global i32 +template __declspec(dllimport) int VarTmpl; +USEVAR(VarTmpl) + +// Import specialization of a non-imported variable template. +// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32 +// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE = external dllimport global i32 +template<> __declspec(dllimport) int VarTmpl; +USEVAR(VarTmpl) + + + +//===----------------------------------------------------------------------===// +// Functions +//===----------------------------------------------------------------------===// + +// Import function declaration. +// MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z4declv() +__declspec(dllimport) void decl(); +USE(decl) + +// extern "C" +// MSC-DAG: declare dllimport void @externC() +// GNU-DAG: declare dllimport void @externC() +extern "C" __declspec(dllimport) void externC(); +USE(externC) + +// Import inline function. +// MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z10inlineFuncv() +// MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z10inlineFuncv() +__declspec(dllimport) inline void inlineFunc() {} +USE(inlineFunc) + +// MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z10inlineDeclv() +// MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"() +// GO1-DAG: define available_externally dllimport 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() +// MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"() +// GO1-DAG: define available_externally dllimport 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() +__declspec(dllimport) __attribute__((noinline)) inline void noinline() {} +USE(noinline) + +// MSC-NOT: @"\01?alwaysInline@@YAXXZ"() +// GNU-NOT: @_Z12alwaysInlinev() +__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {} +USE(alwaysInline) + +// Redeclarations +// MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z7redecl1v() +__declspec(dllimport) void redecl1(); +__declspec(dllimport) void redecl1(); +USE(redecl1) + +// NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC +// and drop the dllimport with a warning. +// MSC-DAG: declare void @"\01?redecl2@@YAXXZ"() +// GNU-DAG: declare void @_Z7redecl2v() +__declspec(dllimport) void redecl2(); + void redecl2(); +USE(redecl2) + +// MSC-DAG: define void @"\01?redecl3@@YAXXZ"() +// GNU-DAG: define void @_Z7redecl3v() +__declspec(dllimport) void redecl3(); + void redecl3() {} // dllimport ignored +USE(redecl3) + + +// Friend functions +// MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z7friend1v() +// MSC-DAG: declare void @"\01?friend2@@YAXXZ"() +// GNU-DAG: declare void @_Z7friend2v() +// MSC-DAG: define void @"\01?friend3@@YAXXZ"() +// GNU-DAG: define void @_Z7friend3v() +struct FuncFriend { + friend __declspec(dllimport) void friend1(); + friend __declspec(dllimport) void friend2(); + friend __declspec(dllimport) void friend3(); }; +__declspec(dllimport) void friend1(); + void friend2(); // dllimport ignored + void friend3() {} // dllimport ignored +USE(friend1) +USE(friend2) +USE(friend3) + +// Implicit declarations can be redeclared with dllimport. +// MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"( +// GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}( +__declspec(dllimport) void* operator new(__SIZE_TYPE__ n); +void UNIQ(use)() { ::operator new(42); } + +// MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"() +// GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv() +namespace ns { __declspec(dllimport) void externalFunc(); } +USE(ns::externalFunc) + + + +//===----------------------------------------------------------------------===// +// Function templates +//===----------------------------------------------------------------------===// + +// Import function template declaration. +// MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv() +template __declspec(dllimport) void funcTmplDecl(); +USE(funcTmplDecl) + +// Function template definitions cannot be imported. + +// Import inline function template. +// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() +// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() +template __declspec(dllimport) inline void inlineFuncTmpl1() {} +USE(inlineFuncTmpl1) + +// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() +// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() +template inline void __attribute__((dllimport)) inlineFuncTmpl2() {} +USE(inlineFuncTmpl2) + +// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() +// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() +template __declspec(dllimport) inline void inlineFuncTmplDecl(); +template void inlineFuncTmplDecl() {} +USE(inlineFuncTmplDecl) + +// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() +// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() +template __declspec(dllimport) void inlineFuncTmplDef(); +template inline void inlineFuncTmplDef() {} +USE(inlineFuncTmplDef) + + +// Redeclarations +// MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv() +template __declspec(dllimport) void funcTmplRedecl1(); +template __declspec(dllimport) void funcTmplRedecl1(); +USE(funcTmplRedecl1) + +// MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"() +// GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv() +template __declspec(dllimport) void funcTmplRedecl2(); +template void funcTmplRedecl2(); // dllimport ignored +USE(funcTmplRedecl2) + +// MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"() +// GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv() +template __declspec(dllimport) void funcTmplRedecl3(); +template void funcTmplRedecl3() {} // dllimport ignored +USE(funcTmplRedecl3) + + +// Function template friends +// MSC-DAG: declare dllimport void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv() +// MSC-DAG: declare void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"() +// GNU-DAG: declare void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv() +// 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() +struct FuncTmplFriend { + template friend __declspec(dllimport) void funcTmplFriend1(); + template friend __declspec(dllimport) void funcTmplFriend2(); + template friend __declspec(dllimport) void funcTmplFriend3(); + template friend __declspec(dllimport) inline void funcTmplFriend4(); +}; +template __declspec(dllimport) void funcTmplFriend1(); +template void funcTmplFriend2(); // dllimport ignored +template void funcTmplFriend3() {} // dllimport ignored +template inline void funcTmplFriend4() {} +USE(funcTmplFriend1) +USE(funcTmplFriend2) +USE(funcTmplFriend3) +USE(funcTmplFriend4) + +// MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"() +// GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv() +namespace ns { template __declspec(dllimport) void externalFuncTmpl(); } +USE(ns::externalFuncTmpl) + + +template void funcTmpl() {} +template inline void inlineFuncTmpl() {} +template __declspec(dllimport) void importedFuncTmplDecl(); +template __declspec(dllimport) inline void importedFuncTmpl() {} + +// Import implicit instantiation of an imported function template. +// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv() +USE(importedFuncTmplDecl) + +// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() +// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() +USE(importedFuncTmpl) + +// 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() +// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() +extern template void importedFuncTmpl(); +USE(importedFuncTmpl) + +// 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() +// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() +template void importedFuncTmpl(); +USE(importedFuncTmpl) + + +// Import specialization of an imported function template. +// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv() +template<> __declspec(dllimport) void importedFuncTmplDecl(); +USE(importedFuncTmplDecl) + +// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"() +// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"() +#ifdef MSABI +//template<> __declspec(dllimport) void importedFuncTmplDecl() {} +//USE(importedFuncTmplDecl) +#endif + +// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport 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() +template<> __declspec(dllimport) inline void importedFuncTmplDecl() {} +USE(importedFuncTmplDecl) + + +// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv() +template<> __declspec(dllimport) void importedFuncTmpl(); +USE(importedFuncTmpl) + +// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() +// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() +#ifdef MSABI +//template<> __declspec(dllimport) void importedFuncTmpl() {} +//USE(importedFuncTmpl) +#endif + +// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport 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() +template<> __declspec(dllimport) inline void importedFuncTmpl() {} +USE(importedFuncTmpl) + + +// Not importing specialization of an imported function template without +// explicit dllimport. +// MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"() +// GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv() +template<> void importedFuncTmpl() {} +USE(importedFuncTmpl) + + +// Import explicit instantiation declaration of a non-imported function template. +// 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() +// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() +// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() +extern template __declspec(dllimport) void funcTmpl(); +extern template __declspec(dllimport) void inlineFuncTmpl(); +USE(funcTmpl) +USE(inlineFuncTmpl) + + +// Import explicit instantiation definition of a non-imported function template. +// 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() +// 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() +template __declspec(dllimport) void funcTmpl(); +template __declspec(dllimport) void inlineFuncTmpl(); +USE(funcTmpl) +USE(inlineFuncTmpl) + + +// Import specialization of a non-imported function template. +// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv() +template<> __declspec(dllimport) void funcTmpl(); +USE(funcTmpl) + +// MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() +// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() +#ifdef MSABI +//template<> __declspec(dllimport) void funcTmpl() {} +//USE(funcTmpl) +#endif -void user(S* s) { - a(); - b(); - c(); - s->a(); -} +// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() +// GNU-DAG: declare dllimport 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() +template<> __declspec(dllimport) inline void funcTmpl() {} +USE(funcTmpl)