1067 lines · cpp
1// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s2// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s3// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s4// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s5// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-pc-cygwin -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=C32 %s6// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-pc-cygwin -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s7// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s8// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s9// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -w | FileCheck --check-prefix=GO1 %s10// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-scei-ps4 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s11// RUN: %clang_cc1 -no-enable-noundef-analysis -triple x86_64-sie-ps5 -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=PS %s12 13// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.14// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s15// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s16// RUN: %clang_cc1 -no-enable-noundef-analysis -triple i686-pc-cygwin -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s17 18// Helper structs to make templates more expressive.19struct ImplicitInst_Imported {};20struct ImplicitInst_NotImported {};21struct ExplicitDecl_Imported {};22struct ExplicitInst_Imported {};23struct ExplicitSpec_Imported {};24struct ExplicitSpec_Def_Imported {};25struct ExplicitSpec_InlineDef_Imported {};26struct ExplicitSpec_NotImported {};27 28#define JOIN2(x, y) x##y29#define JOIN(x, y) JOIN2(x, y)30#define UNIQ(name) JOIN(name, __LINE__)31#define USEVARTYPE(type, var) type UNIQ(use)() { return var; }32#define USEVAR(var) USEVARTYPE(int, var)33#define USE(func) void UNIQ(use)() { func(); }34#define USE1(func) void UNIQ(use)() { func(nullptr); }35#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }36#define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; }37#define USECLASS(class) void UNIQ(USE)() { class x; }38#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }39#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }40 41//===----------------------------------------------------------------------===//42// Globals43//===----------------------------------------------------------------------===//44 45// Import declaration.46// MSC-DAG: @"?ExternGlobalDecl@@3HA" = external dllimport global i3247// GNU-DAG: @ExternGlobalDecl = external dllimport global i3248__declspec(dllimport) extern int ExternGlobalDecl;49USEVAR(ExternGlobalDecl)50 51// dllimport implies a declaration.52// MSC-DAG: @"?GlobalDecl@@3HA" = external dllimport global i3253// GNU-DAG: @GlobalDecl = external dllimport global i3254__declspec(dllimport) int GlobalDecl;55USEVAR(GlobalDecl)56 57// Redeclarations58// MSC-DAG: @"?GlobalRedecl1@@3HA" = external dllimport global i3259// GNU-DAG: @GlobalRedecl1 = external dllimport global i3260__declspec(dllimport) extern int GlobalRedecl1;61__declspec(dllimport) extern int GlobalRedecl1;62USEVAR(GlobalRedecl1)63 64// MSC-DAG: @"?GlobalRedecl2a@@3HA" = external dllimport global i3265// GNU-DAG: @GlobalRedecl2a = external dllimport global i3266__declspec(dllimport) int GlobalRedecl2a;67__declspec(dllimport) int GlobalRedecl2a;68USEVAR(GlobalRedecl2a)69 70// M32-DAG: @"?GlobalRedecl2b@@3PAHA" = external dllimport global ptr71// M64-DAG: @"?GlobalRedecl2b@@3PEAHEA" = external dllimport global ptr72// GNU-DAG: @GlobalRedecl2b = external dllimport global ptr73int *__attribute__((dllimport)) GlobalRedecl2b;74int *__attribute__((dllimport)) GlobalRedecl2b;75USEVARTYPE(int*, GlobalRedecl2b)76 77// MSC-DAG: @"?GlobalRedecl2c@@3HA" = external dllimport global i3278// GNU-DAG: @GlobalRedecl2c = external dllimport global i3279int GlobalRedecl2c __attribute__((dllimport));80int GlobalRedecl2c __attribute__((dllimport));81USEVAR(GlobalRedecl2c)82 83// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC84// and drop the dllimport with a warning.85// MSC-DAG: @"?GlobalRedecl3@@3HA" = external dso_local global i3286// GNU-DAG: @GlobalRedecl3 = external global i3287__declspec(dllimport) extern int GlobalRedecl3;88 extern int GlobalRedecl3; // dllimport ignored89USEVAR(GlobalRedecl3)90 91// MSC-DAG: @"?ExternalGlobal@ns@@3HA" = external dllimport global i3292// GNU-DAG: @_ZN2ns14ExternalGlobalE = external dllimport global i3293namespace ns { __declspec(dllimport) int ExternalGlobal; }94USEVAR(ns::ExternalGlobal)95 96int __declspec(dllimport) f();97// MO1-DAG: @"?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 098// MO1-DAG: @"??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 099inline int __declspec(dllimport) inlineStaticLocalsFunc() {100 static int x = f();101 return x++;102};103USE(inlineStaticLocalsFunc);104 105// The address of a dllimport global cannot be used in constant initialization.106// M32-DAG: @"?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x ptr] zeroinitializer107// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x ptr] zeroinitializer108int *initializationFunc() {109 static int *const arr[] = {&ExternGlobalDecl};110 return arr[0];111}112USE(initializationFunc);113 114 115//===----------------------------------------------------------------------===//116// Variable templates117//===----------------------------------------------------------------------===//118 119// Import declaration.120// MSC-DAG: @"??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32121// GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32122template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;123USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)124 125// dllimport implies a declaration.126// MSC-DAG: @"??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32127// GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32128template<typename T> __declspec(dllimport) int VarTmplDecl;129USEVAR(VarTmplDecl<ImplicitInst_Imported>)130 131// Redeclarations132// MSC-DAG: @"??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32133// GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE = external dllimport global i32134template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;135template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;136USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)137 138// MSC-DAG: @"??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32139// GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE = external dllimport global i32140template<typename T> __declspec(dllimport) int VarTmplRedecl2;141template<typename T> __declspec(dllimport) int VarTmplRedecl2;142USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)143 144// MSC-DAG: @"??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external dso_local global i32145// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32146template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;147template<typename T> extern int VarTmplRedecl3; // dllimport ignored148USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)149 150 151// MSC-DAG: @"??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32152// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE = external dllimport global i32153namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }154USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)155 156 157template<typename T> int VarTmpl;158template<typename T> __declspec(dllimport) int ImportedVarTmpl;159 160// Import implicit instantiation of an imported variable template.161// MSC-DAG: @"??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32162// GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE = external dllimport global i32163USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)164 165// Import explicit instantiation declaration of an imported variable template.166// MSC-DAG: @"??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32167// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE = external dllimport global i32168extern template int ImportedVarTmpl<ExplicitDecl_Imported>;169USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)170 171// An explicit instantiation definition of an imported variable template cannot172// be imported because the template must be defined which is illegal.173 174// Import specialization of an imported variable template.175// MSC-DAG: @"??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32176// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE = external dllimport global i32177template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;178USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)179 180// Not importing specialization of an imported variable template without181// explicit dllimport.182// MSC-DAG: @"??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = dso_local global i32 0, align 4183// GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE = dso_local global i32 0, align 4184template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;185USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)186 187// Import explicit instantiation declaration of a non-imported variable template.188// MSC-DAG: @"??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32189// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE = external dllimport global i32190extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;191USEVAR(VarTmpl<ExplicitDecl_Imported>)192 193// Import explicit instantiation definition of a non-imported variable template.194// MSC-DAG: @"??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32195// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE = external dllimport global i32196template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;197USEVAR(VarTmpl<ExplicitInst_Imported>)198 199// Import specialization of a non-imported variable template.200// MSC-DAG: @"??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32201// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE = external dllimport global i32202template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;203USEVAR(VarTmpl<ExplicitSpec_Imported>)204 205 206 207//===----------------------------------------------------------------------===//208// Functions209//===----------------------------------------------------------------------===//210 211// GNU-DAG: declare dso_local void @_ZdlPv{{[jym]}}(ptr, i{{32|64}})212 213// Import function declaration.214// MSC-DAG: declare dllimport void @"?decl@@YAXXZ"()215// GNU-DAG: declare dllimport void @_Z4declv()216__declspec(dllimport) void decl();217USE(decl)218 219// extern "C"220// MSC-DAG: declare dllimport void @externC()221// GNU-DAG: declare dllimport void @externC()222extern "C" __declspec(dllimport) void externC();223USE(externC)224 225// Import inline function.226// MSC-DAG: declare dllimport void @"?inlineFunc@@YAXXZ"()227// GNU-DAG: define linkonce_odr dso_local void @_Z10inlineFuncv()228// MO1-DAG: define available_externally dllimport void @"?inlineFunc@@YAXXZ"()229// GO1-DAG: define linkonce_odr dso_local void @_Z10inlineFuncv()230__declspec(dllimport) inline void inlineFunc() {}231USE(inlineFunc)232 233// MSC-DAG: declare dllimport void @"?inlineDecl@@YAXXZ"()234// GNU-DAG: define linkonce_odr dso_local void @_Z10inlineDeclv()235// MO1-DAG: define available_externally dllimport void @"?inlineDecl@@YAXXZ"()236// GO1-DAG: define linkonce_odr dso_local void @_Z10inlineDeclv()237__declspec(dllimport) inline void inlineDecl();238 void inlineDecl() {}239USE(inlineDecl)240 241// MSC-DAG: declare dllimport void @"?inlineDef@@YAXXZ"()242// GNU-DAG: define linkonce_odr dso_local void @_Z9inlineDefv()243// MO1-DAG: define available_externally dllimport void @"?inlineDef@@YAXXZ"()244// GO1-DAG: define linkonce_odr dso_local void @_Z9inlineDefv()245__declspec(dllimport) void inlineDef();246 inline void inlineDef() {}247USE(inlineDef)248 249// inline attributes250// MSC-DAG: declare dllimport void @"?noinline@@YAXXZ"()251// GNU-DAG: define linkonce_odr dso_local void @_Z8noinlinev()252__declspec(dllimport) __attribute__((noinline)) inline void noinline() {}253USE(noinline)254 255// MSC2-NOT: @"?alwaysInline@@YAXXZ"()256// GNU2-NOT: @_Z12alwaysInlinev()257__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}258USE(alwaysInline)259 260// Redeclarations261// MSC-DAG: declare dllimport void @"?redecl1@@YAXXZ"()262// GNU-DAG: declare dllimport void @_Z7redecl1v()263__declspec(dllimport) void redecl1();264__declspec(dllimport) void redecl1();265USE(redecl1)266 267// NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC268// and drop the dllimport with a warning.269// MSC-DAG: declare dso_local void @"?redecl2@@YAXXZ"()270// GNU-DAG: declare dso_local void @_Z7redecl2v()271__declspec(dllimport) void redecl2();272 void redecl2();273USE(redecl2)274 275// MSC-DAG: define dso_local dllexport void @"?redecl3@@YAXXZ"()276// GNU-DAG: define dso_local void @_Z7redecl3v()277__declspec(dllimport) void redecl3();278 void redecl3() {} // dllimport ignored279USE(redecl3)280 281 282// Friend functions283// MSC-DAG: declare dllimport void @"?friend1@@YAXXZ"()284// GNU-DAG: declare dllimport void @_Z7friend1v()285// MSC-DAG: declare dso_local void @"?friend2@@YAXXZ"()286// GNU-DAG: declare dso_local void @_Z7friend2v()287// MSC-DAG: define dso_local dllexport void @"?friend3@@YAXXZ"()288// GNU-DAG: define dso_local void @_Z7friend3v()289// MSC-DAG: declare dso_local void @"?friend4@@YAXXZ"()290// GNU-DAG: declare dso_local void @_Z7friend4v()291// MSC-DAG: declare dllimport void @"?friend5@@YAXXZ"()292// GNU-DAG: declare dllimport void @_Z7friend5v()293 294struct FuncFriend {295 friend __declspec(dllimport) void friend1();296 friend __declspec(dllimport) void friend2();297 friend __declspec(dllimport) void friend3();298};299__declspec(dllimport) void friend1();300 void friend2(); // dllimport ignored301 void friend3() {} // dllimport ignored302 303__declspec(dllimport) void friend4();304__declspec(dllimport) void friend5();305struct FuncFriendRedecl {306 friend void friend4(); // dllimport ignored307 friend void ::friend5();308};309USE(friend1)310USE(friend2)311USE(friend3)312USE(friend4)313USE(friend5)314 315// Implicit declarations can be redeclared with dllimport.316// MSC-DAG: declare dllimport nonnull ptr @"??2@{{YAPAXI|YAPEAX_K}}@Z"(317// GNU-DAG: declare dllimport nonnull ptr @_Znw{{[yjm]}}(318__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);319void UNIQ(use)() { ::operator new(42); }320 321// MSC-DAG: declare dllimport void @"?externalFunc@ns@@YAXXZ"()322// GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()323namespace ns { __declspec(dllimport) void externalFunc(); }324USE(ns::externalFunc)325 326// A dllimport function referencing non-imported vars or functions must not be available_externally.327 328__declspec(dllimport) int ImportedVar;329int NonImportedVar;330__declspec(dllimport) int ImportedFunc();331int NonImportedFunc();332struct ClassWithNonImportedMethod { int f(); };333 334__declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; }335// MO1-DAG: define available_externally dllimport i32 @"?ReferencingImportedVar@@YAHXZ"336__declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; }337// MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedVar@@YAHXZ"()338__declspec(dllimport) inline int ReferencingImportedFunc() { return ImportedFunc(); }339// MO1-DAG: define available_externally dllimport i32 @"?ReferencingImportedFunc@@YAHXZ"340__declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); }341// MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedFunc@@YAHXZ"()342__declspec(dllimport) inline int ReferencingNonImportedMethod(ClassWithNonImportedMethod *x) { return x->f(); }343// MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedMethod344__declspec(dllimport) inline int ReferencingClassMemberPtr(int (ClassWithNonImportedMethod::*p)(), ClassWithNonImportedMethod *x) { return (x->*p)(); }345// MO1-DAG: define available_externally dllimport i32 @"?ReferencingClassMemberPtr@@YAHP8ClassWithNonImportedMethod@@AEHXZPAU1@@Z"346USE(ReferencingImportedVar)347USE(ReferencingNonImportedVar)348USE(ReferencingImportedFunc)349USE(ReferencingNonImportedFunc)350USE1(ReferencingNonImportedMethod)351void UNIQ(use)() { ReferencingClassMemberPtr(&ClassWithNonImportedMethod::f, nullptr); }352// References to operator new and delete count too, despite not being DeclRefExprs.353__declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; }354// MO1-DAG: declare dllimport ptr @"?ReferencingNonImportedNew@@YAPAHXZ"355__declspec(dllimport) inline int *ReferencingNonImportedDelete() { delete (int*)nullptr; }356// MO1-DAG: declare dllimport ptr @"?ReferencingNonImportedDelete@@YAPAHXZ"357USE(ReferencingNonImportedNew)358USE(ReferencingNonImportedDelete)359__declspec(dllimport) void* operator new[](__SIZE_TYPE__);360__declspec(dllimport) void operator delete(void*);361__declspec(dllimport) inline int *ReferencingImportedNew() { return new int[2]; }362// MO1-DAG: define available_externally dllimport ptr @"?ReferencingImportedNew@@YAPAHXZ"363__declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nullptr; }364// MO1-DAG: declare dllimport ptr @"?ReferencingImportedDelete@@YAPAHXZ"365USE(ReferencingImportedNew)366USE(ReferencingImportedDelete)367struct ClassWithDtor { ~ClassWithDtor() {} };368struct __declspec(dllimport) ClassWithNonDllImportField { using X = ClassWithDtor; X t[2]; };369struct __declspec(dllimport) ClassWithNonDllImportBase : public ClassWithDtor { };370USECLASS(ClassWithNonDllImportField);371USECLASS(ClassWithNonDllImportBase);372// MO1-DAG: declare dllimport x86_thiscallcc void @"??1ClassWithNonDllImportBase@@QAE@XZ"(ptr {{[^,]*}})373// MO1-DAG: declare dllimport x86_thiscallcc void @"??1ClassWithNonDllImportField@@QAE@XZ"(ptr {{[^,]*}})374struct ClassWithCtor { ClassWithCtor() {} };375struct __declspec(dllimport) ClassWithNonDllImportFieldWithCtor { ClassWithCtor t; };376USECLASS(ClassWithNonDllImportFieldWithCtor);377// MO1-DAG: declare dllimport x86_thiscallcc ptr @"??0ClassWithNonDllImportFieldWithCtor@@QAE@XZ"(ptr {{[^,]*}} returned {{[^,]*}})378struct ClassWithImplicitDtor { __declspec(dllimport) ClassWithImplicitDtor(); ClassWithDtor member; };379__declspec(dllimport) inline void ReferencingDtorThroughDefinition() { ClassWithImplicitDtor x; };380USE(ReferencingDtorThroughDefinition)381// MO1-DAG: declare dllimport void @"?ReferencingDtorThroughDefinition@@YAXXZ"()382__declspec(dllimport) inline void ReferencingDtorThroughTemporary() { ClassWithImplicitDtor(); };383USE(ReferencingDtorThroughTemporary)384// MO1-DAG: declare dllimport void @"?ReferencingDtorThroughTemporary@@YAXXZ"()385 386// A dllimport function with a TLS variable must not be available_externally.387__declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; }388// MO1-DAG: declare dllimport void @"?FunctionWithTLSVar@@YAXXZ"389__declspec(dllimport) inline void FunctionWithNormalVar() { static int x = 42; }390// MO1-DAG: define available_externally dllimport void @"?FunctionWithNormalVar@@YAXXZ"391USE(FunctionWithTLSVar)392USE(FunctionWithNormalVar)393 394// always_inline and __force_inline take precedence.395__declspec(dllimport) inline int ReferencingNonImportedFuncAlwaysInline() __attribute__((always_inline)) { return NonImportedFunc(); }396USE(ReferencingNonImportedFuncAlwaysInline)397// MO1-DAG: define available_externally dllimport i32 @"?ReferencingNonImportedFuncAlwaysInline@@YAHXZ"398__declspec(dllimport) __forceinline int ReferencingNonImportedFuncForceInline() { return NonImportedFunc(); }399USE(ReferencingNonImportedFuncForceInline)400// MO1-DAG: define available_externally dllimport i32 @"?ReferencingNonImportedFuncForceInline@@YAHXZ"401 402//===----------------------------------------------------------------------===//403// Function templates404//===----------------------------------------------------------------------===//405 406// Import function template declaration.407// MSC-DAG: declare dllimport void @"??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()408// GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()409template<typename T> __declspec(dllimport) void funcTmplDecl();410USE(funcTmplDecl<ImplicitInst_Imported>)411 412// Function template definitions cannot be imported.413 414// Import inline function template.415// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()416// GNU-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()417// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()418// GO1-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()419template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}420USE(inlineFuncTmpl1<ImplicitInst_Imported>)421 422// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()423// GNU-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()424// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()425// GO1-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()426template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}427USE(inlineFuncTmpl2<ImplicitInst_Imported>)428 429// MSC-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()430// GNU-DAG: define linkonce_odr dso_local void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()431// MO1-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()432// GO1-DAG: define linkonce_odr dso_local void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()433template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();434template<typename T> void inlineFuncTmplDecl() {}435USE(inlineFuncTmplDecl<ImplicitInst_Imported>)436 437// MSC-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()438// GNU-DAG: define linkonce_odr dso_local void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()439// MO1-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()440// GO1-DAG: define linkonce_odr dso_local void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()441template<typename T> __declspec(dllimport) void inlineFuncTmplDef();442template<typename T> inline void inlineFuncTmplDef() {}443USE(inlineFuncTmplDef<ImplicitInst_Imported>)444 445 446// Redeclarations447// MSC-DAG: declare dllimport void @"??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()448// GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()449template<typename T> __declspec(dllimport) void funcTmplRedecl1();450template<typename T> __declspec(dllimport) void funcTmplRedecl1();451USE(funcTmplRedecl1<ImplicitInst_Imported>)452 453// MSC-DAG: declare dso_local void @"??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()454// GNU-DAG: declare dso_local void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()455template<typename T> __declspec(dllimport) void funcTmplRedecl2();456template<typename T> void funcTmplRedecl2(); // dllimport ignored457USE(funcTmplRedecl2<ImplicitInst_NotImported>)458 459// MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()460// GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()461template<typename T> __declspec(dllimport) void funcTmplRedecl3();462template<typename T> void funcTmplRedecl3() {} // dllimport ignored463USE(funcTmplRedecl3<ImplicitInst_NotImported>)464 465 466// Function template friends467// MSC-DAG: declare dllimport void @"??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()468// GNU-DAG: declare dllimport void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()469// MSC-DAG: declare dso_local void @"??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()470// GNU-DAG: declare dso_local void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()471// MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()472// GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()473// MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()474// GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()475struct FuncTmplFriend {476 template<typename T> friend __declspec(dllimport) void funcTmplFriend1();477 template<typename T> friend __declspec(dllimport) void funcTmplFriend2();478 template<typename T> friend __declspec(dllimport) void funcTmplFriend3();479 template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();480};481template<typename T> __declspec(dllimport) void funcTmplFriend1();482template<typename T> void funcTmplFriend2(); // dllimport ignored483template<typename T> void funcTmplFriend3() {} // dllimport ignored484template<typename T> inline void funcTmplFriend4() {}485USE(funcTmplFriend1<ImplicitInst_Imported>)486USE(funcTmplFriend2<ImplicitInst_NotImported>)487USE(funcTmplFriend3<ImplicitInst_NotImported>)488USE(funcTmplFriend4<ImplicitInst_Imported>)489 490// MSC-DAG: declare dllimport void @"??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()491// GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()492namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }493USE(ns::externalFuncTmpl<ImplicitInst_Imported>)494 495 496template<typename T> void funcTmpl() {}497template<typename T> inline void inlineFuncTmpl() {}498template<typename T> __declspec(dllimport) void importedFuncTmplDecl();499template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}500 501// Import implicit instantiation of an imported function template.502// MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()503// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()504USE(importedFuncTmplDecl<ImplicitInst_Imported>)505 506// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()507// GNU-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()508// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()509// GO1-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()510USE(importedFuncTmpl<ImplicitInst_Imported>)511 512// Import explicit instantiation declaration of an imported function template.513// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()514// GNU-DAG: declare dso_local void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()515// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()516// GO1-DAG: define available_externally dso_local void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()517extern template void importedFuncTmpl<ExplicitDecl_Imported>();518USE(importedFuncTmpl<ExplicitDecl_Imported>)519 520// Import explicit instantiation definition of an imported function template.521// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()522// GNU-DAG: define weak_odr dso_local void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()523// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()524// GO1-DAG: define weak_odr dso_local void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()525template void importedFuncTmpl<ExplicitInst_Imported>();526USE(importedFuncTmpl<ExplicitInst_Imported>)527 528 529// Import specialization of an imported function template.530// MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()531// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()532template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();533USE(importedFuncTmplDecl<ExplicitSpec_Imported>)534 535// MSC-DAG-FIXME: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()536// MO1-DAG-FIXME: define available_externally dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()537#ifdef MSABI538//template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}539//USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)540#endif541 542// MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()543// GNU-DAG: define linkonce_odr dso_local void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()544// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()545// GO1-DAG: define linkonce_odr dso_local void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()546template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}547USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)548 549 550// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()551// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()552template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();553USE(importedFuncTmpl<ExplicitSpec_Imported>)554 555// MSC-DAG-FIXME: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()556// MO1-DAG-FIXME: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()557#ifdef MSABI558//template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}559//USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)560#endif561 562// MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()563// GNU-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()564// MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()565// GO1-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()566template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}567USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)568 569 570// Not importing specialization of an imported function template without571// explicit dllimport.572// MSC-DAG: define dso_local void @"??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()573// GNU-DAG: define dso_local void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()574template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}575USE(importedFuncTmpl<ExplicitSpec_NotImported>)576 577 578// Import explicit instantiation declaration of a non-imported function template.579// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()580// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()581// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()582// GNU-DAG: declare dso_local void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()583// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()584// GO1-DAG: define available_externally dso_local void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()585extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();586extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();587USE(funcTmpl<ExplicitDecl_Imported>)588USE(inlineFuncTmpl<ExplicitDecl_Imported>)589 590 591// Import explicit instantiation definition of a non-imported function template.592// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()593// MSC-DAG: declare dllimport void @"??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()594// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()595// GNU-DAG: define weak_odr dso_local void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()596// MO1-DAG: declare dllimport void @"??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()597// MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()598// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()599// GO1-DAG: define weak_odr dso_local void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()600template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();601template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();602USE(funcTmpl<ExplicitInst_Imported>)603USE(inlineFuncTmpl<ExplicitInst_Imported>)604 605 606// Import specialization of a non-imported function template.607// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()608// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()609template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();610USE(funcTmpl<ExplicitSpec_Imported>)611 612// MSC-DAG-FIXME: declare dllimport void @"??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()613// MO1-DAG-FIXME: define available_externally dllimport void @"??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()614#ifdef MSABI615//template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}616//USE(funcTmpl<ExplicitSpec_Def_Imported>)617#endif618 619// MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()620// GNU-DAG: define linkonce_odr dso_local void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()621// MO1-DAG: define available_externally dllimport void @"??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()622// GO1-DAG: define linkonce_odr dso_local void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()623template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}624USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)625 626#ifdef MSABI627namespace pr35435 {628struct X;629template <typename T> struct __declspec(dllimport) S {630 void foo(T *t) { t->problem(); }631};632template void S<X>::foo(X*); // Cannot be instantiated because X is incomplete; dllimport means it's treated as an instantiation decl.633}634#endif635 636 637//===----------------------------------------------------------------------===//638// Classes639//===----------------------------------------------------------------------===//640 641struct __declspec(dllimport) T {642 void a() {}643 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?a@T@@QAEXXZ"644 645 static void StaticMethod();646 // MSC-DAG: declare dllimport void @"?StaticMethod@T@@SAXXZ"()647 // GNU-DAG: declare dllimport void @_ZN1T12StaticMethodEv()648 649 static int b;650 // MO1-DAG: @"?b@T@@2HA" = external dllimport global i32651 652 T& operator=(T&) = default;653 // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@AAU0@@Z"654 655 T& operator=(T&&) = default;656 // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.657 // M18-DAG: define linkonce_odr dso_local x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@$$QAU0@@Z"658 // M19-DAG: define available_externally dllimport x86_thiscallcc nonnull align {{[0-9]+}} dereferenceable({{[0-9]+}}) ptr @"??4T@@QAEAAU0@$$QAU0@@Z"659};660USEMEMFUNC(T, a)661USESTATICMEMFUNC(T, StaticMethod)662USEVAR(T::b)663USECOPYASSIGN(T)664USEMOVEASSIGN(T)665 666template <typename T> struct __declspec(dllimport) U { void foo() {} };667// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?foo@?$U@H@@QAEXXZ"668struct __declspec(dllimport) V : public U<int> { };669USEMEMFUNC(V, foo)670 671struct __declspec(dllimport) W { virtual void foo() {} };672USECLASS(W)673// vftable:674// MO1-DAG: @"??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] } { [1 x ptr] [ptr @"?foo@W@@UAEXXZ"] }675// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr null, ptr @_ZN1W3fooEv] }676 677struct __declspec(dllimport) KeyFuncClass {678 constexpr KeyFuncClass() {}679 virtual void foo();680};681extern constexpr KeyFuncClass keyFuncClassVar = {};682// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x ptr] }683// C32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x ptr] }684 685struct __declspec(dllimport) X : public virtual W {};686USECLASS(X)687// vbtable:688// MO1-DAG: @"??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]689 690struct __declspec(dllimport) Y {691 int x;692};693 694struct __declspec(dllimport) Z { virtual ~Z() {} };695USECLASS(Z)696// User-defined dtor:697// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"??1Z@@UAE@XZ"698 699namespace DontUseDtorAlias {700 struct __declspec(dllimport) A { ~A(); };701 struct __declspec(dllimport) B : A { ~B(); };702 inline A::~A() { }703 inline B::~B() { }704 // Emit a real definition of B's constructor; don't alias it to A's.705 // MO1-DAG: available_externally dllimport x86_thiscallcc void @"??1B@DontUseDtorAlias@@QAE@XZ"706 USECLASS(B)707}708 709namespace Vtordisp {710 // Don't dllimport the vtordisp.711 // MO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ"712 713 class __declspec(dllimport) Base {714 virtual void f() {}715 };716 template <typename T>717 class __declspec(dllimport) C : virtual public Base {718 public:719 C() {}720 virtual void f() {}721 };722 USECLASS(C<int>);723}724 725namespace ClassTemplateStaticDef {726 // Regular template static field:727 template <typename T> struct __declspec(dllimport) S {728 static int x;729 };730 template <typename T> int S<T>::x;731 // MSC-DAG: @"?x@?$S@H@ClassTemplateStaticDef@@2HA" = external dllimport global i32732 int f() { return S<int>::x; }733 734 // Partial class template specialization static field:735 template <typename A> struct T;736 template <typename A> struct __declspec(dllimport) T<A*> {737 static int x;738 };739 template <typename A> int T<A*>::x;740 // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = external dllimport global i32741 int g() { return T<void*>::x; }742}743 744namespace PR19933 {745// Don't dynamically initialize dllimport vars.746// MSC2-NOT: @llvm.global_ctors747// GNU2-NOT: @llvm.global_ctors748 749 struct NonPOD { NonPOD(); };750 template <typename T> struct A { static NonPOD x; };751 template <typename T> NonPOD A<T>::x;752 template struct __declspec(dllimport) A<int>;753 USEVARTYPE(NonPOD, A<int>::x);754 // MSC-DAG: @"?x@?$A@H@PR19933@@2UNonPOD@2@A" = external dllimport global %"struct.PR19933::NonPOD"755 756 int f();757 template <typename T> struct B { static int x; };758 template <typename T> int B<T>::x = f();759 template struct __declspec(dllimport) B<int>;760 USEVAR(B<int>::x);761 // MSC-DAG: @"?x@?$B@H@PR19933@@2HA" = external dllimport global i32762 763 constexpr int g() { return 42; }764 template <typename T> struct C { static int x; };765 template <typename T> int C<T>::x = g();766 template struct __declspec(dllimport) C<int>;767 USEVAR(C<int>::x);768 // MSC-DAG: @"?x@?$C@H@PR19933@@2HA" = external dllimport global i32769 770 template <int I> struct D { static int x, y; };771 template <int I> int D<I>::x = I + 1;772 template <int I> int D<I>::y = I + f();773 template struct __declspec(dllimport) D<42>;774 USEVAR(D<42>::x);775 USEVAR(D<42>::y);776 // MSC-DAG: @"?x@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32777 // MSC-DAG: @"?y@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32778}779 780namespace PR21355 {781 struct __declspec(dllimport) S {782 virtual ~S();783 };784 S::~S() {}785 786 // S::~S is a key function, so we would ordinarily emit a strong definition for787 // the vtable. However, S is imported, so the vtable should be too.788 789 // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant { [4 x ptr] }790}791 792namespace PR21366 {793 struct __declspec(dllimport) S {794 void outOfLineMethod();795 void inlineMethod() {}796 inline void anotherInlineMethod();797 void outOfClassInlineMethod();798 };799 void S::anotherInlineMethod() {}800 inline void S::outOfClassInlineMethod() {}801}802 803namespace PR27319 {804 // Make sure we don't assert due to not having checked for operator delete on805 // the destructor.806 template <typename> struct A {807 virtual ~A() = default;808 };809 extern template struct __declspec(dllimport) A<int>;810 void f() { new A<int>(); }811 // MO1-DAG: @"??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant { [1 x ptr] }812}813 814// MS ignores DLL attributes on partial specializations.815template <typename T> struct PartiallySpecializedClassTemplate {};816template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };817USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);818// M32-DAG: declare dso_local x86_thiscallcc void @"?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"819// G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv820// C32-DAG: declare dllimport void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv821 822// Attributes on explicit specializations are honored.823template <typename T> struct ExplicitlySpecializedClassTemplate {};824template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); };825USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);826// M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"827// G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv828// C32-DAG: declare dllimport void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv829 830// MS inherits DLL attributes to partial specializations.831template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {};832template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} };833USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f);834// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ"835// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv836// C32-DAG: define linkonce_odr dso_local void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv837 838// Attributes on the instantiation take precedence over attributes on the template.839template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };840template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>;841USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);842// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"843 844template <typename T> struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} ExplicitInstantiationDeclImportedDefTemplate() {}};845extern template struct ExplicitInstantiationDeclImportedDefTemplate<int>;846template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate<int>;847USECLASS(ExplicitInstantiationDeclImportedDefTemplate<int>);848USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f);849// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ"850// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc ptr @"??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ"851// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv852// C32-DAG: define weak_odr dso_local void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv853 854template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} };855extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>;856template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>;857USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate<int>);858USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f);859// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ"860// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc ptr @"??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ"861 862template <typename T> struct PR23770BaseTemplate { void f() {} };863template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};864extern template struct PR23770DerivedTemplate<int>;865template struct __declspec(dllimport) PR23770DerivedTemplate<int>;866USEMEMFUNC(PR23770BaseTemplate<int>, f);867// M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$PR23770BaseTemplate@H@@QAEXXZ"868 869namespace PR27810 {870 template <class T>871 struct basic_ostream {872 struct sentry {873 sentry() { }874 void foo() { }875 };876 };877 template class __declspec(dllimport) basic_ostream<char>;878 // The explicit instantiation definition acts as an explicit instantiation879 // *declaration*, dllimport is not inherited by the inner class, and no880 // functions are emitted unless they are used.881 882 USEMEMFUNC(basic_ostream<char>::sentry, foo);883 // M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?foo@sentry@?$basic_ostream@D@PR27810@@QAEXXZ"884 // M32-NOT: ??0sentry@?$basic_ostream@D@PR27810@@QAE@XZ885}886 887namespace PR27811 {888 template <class T> struct codecvt {889 virtual ~codecvt() { }890 };891 template class __declspec(dllimport) codecvt<char>;892 893 // dllimport means this explicit instantiation definition gets treated as a894 // declaration. Thus, the vtable should not be marked used, and in fact895 // nothing for this class should be emitted at all since it's not used.896 // M32-NOT: codecvt897}898 899//===----------------------------------------------------------------------===//900// Classes with template base classes901//===----------------------------------------------------------------------===//902 903template <typename T> struct ClassTemplate { void func() {} };904template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };905template <typename T> void ExportedClassTemplate<T>::func() {}906template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };907 908template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };909template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };910template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };911template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };912void ExplicitlyExportSpecializedTemplate<int>::func() {}913template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };914template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };915 916template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };917template struct ExplicitlyInstantiatedTemplate<int>;918template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };919template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}920template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;921template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };922template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;923 924 925// MS: ClassTemplate<int> gets imported.926struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};927USEMEMFUNC(ClassTemplate<int>, func)928// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ"929// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv930// C32-DAG: define linkonce_odr dso_local void @_ZN13ClassTemplateIiE4funcEv931// PS-DAG: declare dllimport void @_ZN13ClassTemplateIiE4funcEv932 933// ImportedTemplate is explicitly imported.934struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};935USEMEMFUNC(ImportedClassTemplate<int>, func)936// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ"937// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv938// C32-DAG: declare dllimport void @_ZN21ImportedClassTemplateIiE4funcEv939// PS-DAG: declare dllimport void @_ZN21ImportedClassTemplateIiE4funcEv940 941// ExportedTemplate is explicitly exported.942struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};943USEMEMFUNC(ExportedClassTemplate<int>, func)944// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ"945// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv946// C32-DAG: define weak_odr dso_local dllexport void @_ZN21ExportedClassTemplateIiE4funcEv947// PS-DAG: define weak_odr dllexport void @_ZN21ExportedClassTemplateIiE4funcEv948 949// Base class already implicitly instantiated without attribute.950struct DerivedFromTemplateD : public ClassTemplate<double> {};951struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};952USEMEMFUNC(ClassTemplate<double>, func)953// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ"954// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv955// C32-DAG: define linkonce_odr dso_local void @_ZN13ClassTemplateIdE4funcEv956// PS-DAG: declare dllimport void @_ZN13ClassTemplateIdE4funcEv957 958// MS: Base class already instantiated with dfferent attribute.959struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};960struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};961USEMEMFUNC(ClassTemplate<bool>, func)962// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ"963// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv964// C32-DAG: define linkonce_odr dso_local void @_ZN13ClassTemplateIbE4funcEv965// PS-DAG: define weak_odr dllexport void @_ZN13ClassTemplateIbE4funcEv966 967// Base class already specialized without dll attribute.968struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};969USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)970// M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"971// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv972// C32-DAG: define linkonce_odr dso_local void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv973// PS-DAG: define linkonce_odr void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv974 975// Base class alredy specialized with export attribute.976struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};977USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)978// M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"979// G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv980// C32-DAG: define dso_local dllexport void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv981// PS-DAG: define dso_local dllexport void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv982 983// Base class already specialized with import attribute.984struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};985USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)986// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"987// G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv988// C32-DAG: declare dllimport void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv989// PS-DAG: declare dllimport void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv990 991// Base class already instantiated without dll attribute.992struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};993USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)994// M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"995// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv996// C32-DAG: define weak_odr dso_local void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv997// PS-DAG: define weak_odr void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv998 999// Base class already instantiated with export attribute.1000struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};1001USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)1002// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"1003// G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv1004// C32-DAG: define weak_odr dso_local dllexport void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv1005// PS-DAG: define weak_odr dllexport void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv1006 1007// Base class already instantiated with import attribute.1008struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};1009USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)1010// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"1011// G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv1012// C32-DAG: declare dllimport void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv1013// PS-DAG: declare dllimport void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv1014 1015// MS: A dll attribute propagates through multiple levels of instantiation.1016template <typename T> struct TopClass { void func() {} };1017template <typename T> struct MiddleClass : public TopClass<T> { };1018struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };1019USEMEMFUNC(TopClass<int>, func)1020// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ"1021// G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv1022// C32-DAG: define linkonce_odr dso_local void @_ZN8TopClassIiE4funcEv1023// PS-DAG: declare dllimport void @_ZN8TopClassIiE4funcEv1024 1025template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };1026extern template struct ExplicitInstantiationDeclTemplateBase<int>;1027struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};1028template struct ExplicitInstantiationDeclTemplateBase<int>;1029USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func)1030// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"1031// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv1032// C32-DAG: define weak_odr dso_local void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv1033// PS-DAG: declare dllimport void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv1034 1035template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} };1036extern template struct ExplicitInstantiationDeclTemplateBase2<int>;1037struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {};1038template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int>;1039USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func)1040// M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"1041// G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv1042// C32-DAG: define weak_odr dso_local void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv1043// PS-DAG: declare dllimport void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv1044 1045namespace pr39496 {1046// Make sure dll attribute are inherited by static locals also in template1047// specializations.1048template <typename> struct __declspec(dllimport) S { int foo() { static int x; return x++; } };1049int foo() { S<int> s; return s.foo(); }1050// MO1-DAG: @"?x@?{{1|2}}??foo@?$S@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 41051 1052template <typename> struct T { int foo() { static int x; return x++; } };1053extern template struct __declspec(dllimport) T<int>;1054int bar() { T<int> t; return t.foo(); }1055// MO1-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 41056 1057template <typename T> struct __declspec(dllimport) U {1058 void foo() {1059 // Don't inherit dllimport to src before attaching the initializer.1060 static constexpr char src[] = {"hello"};1061 T arr[sizeof(src)];1062 }1063};1064void baz() { U<int> u; u.foo(); } // No diagnostic.1065 1066}1067