1*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 -check-prefix=M32MSVC2015 %s
2*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 -check-prefix=M32MSVC2013 %s
3*67e74705SXin Li
4*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2015 -check-prefix=M64MSVC2015 %s
5*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w -fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC --check-prefix=M64 -check-prefix=MSVC2013 -check-prefix=M64MSVC2013 %s
6*67e74705SXin Li
7*67e74705SXin Li // RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
8*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
9*67e74705SXin Li
10*67e74705SXin Li // Helper structs to make templates more expressive.
11*67e74705SXin Li struct ImplicitInst_Exported {};
12*67e74705SXin Li struct ExplicitDecl_Exported {};
13*67e74705SXin Li struct ExplicitInst_Exported {};
14*67e74705SXin Li struct ExplicitSpec_Exported {};
15*67e74705SXin Li struct ExplicitSpec_Def_Exported {};
16*67e74705SXin Li struct ExplicitSpec_InlineDef_Exported {};
17*67e74705SXin Li struct ExplicitSpec_NotExported {};
18*67e74705SXin Li struct External { int v; };
19*67e74705SXin Li
20*67e74705SXin Li #define JOIN2(x, y) x##y
21*67e74705SXin Li #define JOIN(x, y) JOIN2(x, y)
22*67e74705SXin Li #define UNIQ(name) JOIN(name, __LINE__)
23*67e74705SXin Li #define USEVAR(var) int UNIQ(use)() { return var; }
24*67e74705SXin Li #define USE(func) void UNIQ(use)() { func(); }
25*67e74705SXin Li #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
26*67e74705SXin Li #define INSTVAR(var) template int var;
27*67e74705SXin Li #define INST(func) template void func();
28*67e74705SXin Li
29*67e74705SXin Li // The vftable for struct W is comdat largest because we have RTTI.
30*67e74705SXin Li // M32-DAG: $"\01??_7W@@6B@" = comdat largest
31*67e74705SXin Li
32*67e74705SXin Li
33*67e74705SXin Li //===----------------------------------------------------------------------===//
34*67e74705SXin Li // Globals
35*67e74705SXin Li //===----------------------------------------------------------------------===//
36*67e74705SXin Li
37*67e74705SXin Li // Declarations are not exported.
38*67e74705SXin Li // MSC-NOT: @"\01?ExternGlobalDecl@@3HA"
39*67e74705SXin Li // GNU-NOT: @ExternGlobalDecl
40*67e74705SXin Li __declspec(dllexport) extern int ExternGlobalDecl;
41*67e74705SXin Li
42*67e74705SXin Li // dllexport implies a definition.
43*67e74705SXin Li // MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4
44*67e74705SXin Li // GNU-DAG: @GlobalDef = dllexport global i32 0, align 4
45*67e74705SXin Li __declspec(dllexport) int GlobalDef;
46*67e74705SXin Li
47*67e74705SXin Li // Export definition.
48*67e74705SXin Li // MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4
49*67e74705SXin Li // GNU-DAG: @GlobalInit1 = dllexport global i32 1, align 4
50*67e74705SXin Li __declspec(dllexport) int GlobalInit1 = 1;
51*67e74705SXin Li
52*67e74705SXin Li // MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4
53*67e74705SXin Li // GNU-DAG: @GlobalInit2 = dllexport global i32 1, align 4
54*67e74705SXin Li int __declspec(dllexport) GlobalInit2 = 1;
55*67e74705SXin Li
56*67e74705SXin Li // Declare, then export definition.
57*67e74705SXin Li // MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4
58*67e74705SXin Li // GNU-DAG: @GlobalDeclInit = dllexport global i32 1, align 4
59*67e74705SXin Li __declspec(dllexport) extern int GlobalDeclInit;
60*67e74705SXin Li int GlobalDeclInit = 1;
61*67e74705SXin Li
62*67e74705SXin Li // Redeclarations
63*67e74705SXin Li // MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4
64*67e74705SXin Li // GNU-DAG: @GlobalRedecl1 = dllexport global i32 0, align 4
65*67e74705SXin Li __declspec(dllexport) extern int GlobalRedecl1;
66*67e74705SXin Li __declspec(dllexport) int GlobalRedecl1;
67*67e74705SXin Li
68*67e74705SXin Li // MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4
69*67e74705SXin Li // GNU-DAG: @GlobalRedecl2 = dllexport global i32 0, align 4
70*67e74705SXin Li __declspec(dllexport) extern int GlobalRedecl2;
71*67e74705SXin Li int GlobalRedecl2;
72*67e74705SXin Li
73*67e74705SXin Li // MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = dllexport global i32 0, align 4
74*67e74705SXin Li // GNU-DAG: @_ZN2ns14ExternalGlobalE = dllexport global i32 0, align 4
75*67e74705SXin Li namespace ns { __declspec(dllexport) int ExternalGlobal; }
76*67e74705SXin Li
77*67e74705SXin Li // MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4
78*67e74705SXin Li // GNU-DAG: @ExternalAutoTypeGlobal = dllexport global %struct.External zeroinitializer, align 4
79*67e74705SXin Li __declspec(dllexport) auto ExternalAutoTypeGlobal = External();
80*67e74705SXin Li
81*67e74705SXin Li int f();
82*67e74705SXin Li // MSC-DAG: @"\01?x@?1??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0
83*67e74705SXin Li // MSC-DAG: @"\01?$S1@?1??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0
nonInlineStaticLocalsFunc()84*67e74705SXin Li int __declspec(dllexport) nonInlineStaticLocalsFunc() {
85*67e74705SXin Li static int x = f();
86*67e74705SXin Li return x++;
87*67e74705SXin Li };
88*67e74705SXin Li
89*67e74705SXin Li // MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0, comdat
90*67e74705SXin Li // MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0, comdat
91*67e74705SXin Li // Note: MinGW doesn't seem to export the static local here.
inlineStaticLocalsFunc()92*67e74705SXin Li inline int __declspec(dllexport) inlineStaticLocalsFunc() {
93*67e74705SXin Li static int x = f();
94*67e74705SXin Li return x++;
95*67e74705SXin Li }
96*67e74705SXin Li
97*67e74705SXin Li
98*67e74705SXin Li
99*67e74705SXin Li //===----------------------------------------------------------------------===//
100*67e74705SXin Li // Variable templates
101*67e74705SXin Li //===----------------------------------------------------------------------===//
102*67e74705SXin Li
103*67e74705SXin Li // Declarations are not exported.
104*67e74705SXin Li
105*67e74705SXin Li // dllexport implies a definition.
106*67e74705SXin Li // MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA"
107*67e74705SXin Li // GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
108*67e74705SXin Li template<typename T> __declspec(dllexport) int VarTmplDef;
109*67e74705SXin Li INSTVAR(VarTmplDef<ExplicitInst_Exported>)
110*67e74705SXin Li
111*67e74705SXin Li // MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global
112*67e74705SXin Li // GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE = external dllexport global
113*67e74705SXin Li template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
114*67e74705SXin Li USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
115*67e74705SXin Li
116*67e74705SXin Li // Export definition.
117*67e74705SXin Li // MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
118*67e74705SXin Li // GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
119*67e74705SXin Li template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
120*67e74705SXin Li INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
121*67e74705SXin Li
122*67e74705SXin Li // MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
123*67e74705SXin Li // GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
124*67e74705SXin Li template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
125*67e74705SXin Li INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
126*67e74705SXin Li
127*67e74705SXin Li // Declare, then export definition.
128*67e74705SXin Li // MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
129*67e74705SXin Li // GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
130*67e74705SXin Li template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
131*67e74705SXin Li template<typename T> int VarTmplDeclInit = 1;
132*67e74705SXin Li INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
133*67e74705SXin Li
134*67e74705SXin Li // Redeclarations
135*67e74705SXin Li // MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
136*67e74705SXin Li // GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
137*67e74705SXin Li template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
138*67e74705SXin Li template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1;
139*67e74705SXin Li INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
140*67e74705SXin Li
141*67e74705SXin Li // MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
142*67e74705SXin Li // GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
143*67e74705SXin Li template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
144*67e74705SXin Li template<typename T> int VarTmplRedecl2 = 1;
145*67e74705SXin Li INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
146*67e74705SXin Li
147*67e74705SXin Li // MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
148*67e74705SXin Li // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, comdat, align 4
149*67e74705SXin Li namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
150*67e74705SXin Li INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
151*67e74705SXin Li
152*67e74705SXin Li // MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, comdat, align 4
153*67e74705SXin Li // GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, comdat, align 4
154*67e74705SXin Li template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
155*67e74705SXin Li template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
156*67e74705SXin Li
157*67e74705SXin Li
158*67e74705SXin Li template<typename T> int VarTmpl = 1;
159*67e74705SXin Li template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
160*67e74705SXin Li
161*67e74705SXin Li // Export implicit instantiation of an exported variable template.
162*67e74705SXin Li // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
163*67e74705SXin Li // GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
164*67e74705SXin Li USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
165*67e74705SXin Li
166*67e74705SXin Li // Export explicit instantiation declaration of an exported variable template.
167*67e74705SXin Li // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
168*67e74705SXin Li // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
169*67e74705SXin Li extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
170*67e74705SXin Li template int ExportedVarTmpl<ExplicitDecl_Exported>;
171*67e74705SXin Li
172*67e74705SXin Li // Export explicit instantiation definition of an exported variable template.
173*67e74705SXin Li // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
174*67e74705SXin Li // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
175*67e74705SXin Li template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
176*67e74705SXin Li
177*67e74705SXin Li // Export specialization of an exported variable template.
178*67e74705SXin Li // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
179*67e74705SXin Li // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE = dllexport global i32 0, align 4
180*67e74705SXin Li template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
181*67e74705SXin Li
182*67e74705SXin Li // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
183*67e74705SXin Li // GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE = dllexport global i32 1, align 4
184*67e74705SXin Li template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
185*67e74705SXin Li
186*67e74705SXin Li // Not exporting specialization of an exported variable template without
187*67e74705SXin Li // explicit dllexport.
188*67e74705SXin Li // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4
189*67e74705SXin Li // GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE = global i32 0, align 4
190*67e74705SXin Li template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
191*67e74705SXin Li
192*67e74705SXin Li
193*67e74705SXin Li // Export explicit instantiation declaration of a non-exported variable template.
194*67e74705SXin Li // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
195*67e74705SXin Li // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
196*67e74705SXin Li extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
197*67e74705SXin Li template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
198*67e74705SXin Li
199*67e74705SXin Li // Export explicit instantiation definition of a non-exported variable template.
200*67e74705SXin Li // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4
201*67e74705SXin Li // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4
202*67e74705SXin Li template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
203*67e74705SXin Li
204*67e74705SXin Li // Export specialization of a non-exported variable template.
205*67e74705SXin Li // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
206*67e74705SXin Li // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE = dllexport global i32 0, align 4
207*67e74705SXin Li template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
208*67e74705SXin Li
209*67e74705SXin Li // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
210*67e74705SXin Li // GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE = dllexport global i32 1, align 4
211*67e74705SXin Li template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
212*67e74705SXin Li
213*67e74705SXin Li
214*67e74705SXin Li
215*67e74705SXin Li //===----------------------------------------------------------------------===//
216*67e74705SXin Li // Functions
217*67e74705SXin Li //===----------------------------------------------------------------------===//
218*67e74705SXin Li
219*67e74705SXin Li // Declarations are not exported.
220*67e74705SXin Li
221*67e74705SXin Li // Export function definition.
222*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?def@@YAXXZ"()
223*67e74705SXin Li // GNU-DAG: define dllexport void @_Z3defv()
def()224*67e74705SXin Li __declspec(dllexport) void def() {}
225*67e74705SXin Li
226*67e74705SXin Li // extern "C"
227*67e74705SXin Li // MSC-DAG: define dllexport void @externC()
228*67e74705SXin Li // GNU-DAG: define dllexport void @externC()
externC()229*67e74705SXin Li extern "C" __declspec(dllexport) void externC() {}
230*67e74705SXin Li
231*67e74705SXin Li // Export inline function.
232*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"()
233*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv()
inlineFunc()234*67e74705SXin Li __declspec(dllexport) inline void inlineFunc() {}
235*67e74705SXin Li
236*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"()
237*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv()
238*67e74705SXin Li __declspec(dllexport) inline void inlineDecl();
inlineDecl()239*67e74705SXin Li void inlineDecl() {}
240*67e74705SXin Li
241*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"()
242*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv()
243*67e74705SXin Li __declspec(dllexport) void inlineDef();
inlineDef()244*67e74705SXin Li inline void inlineDef() {}
245*67e74705SXin Li
246*67e74705SXin Li // Redeclarations
247*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"()
248*67e74705SXin Li // GNU-DAG: define dllexport void @_Z7redecl1v()
249*67e74705SXin Li __declspec(dllexport) void redecl1();
redecl1()250*67e74705SXin Li __declspec(dllexport) void redecl1() {}
251*67e74705SXin Li
252*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"()
253*67e74705SXin Li // GNU-DAG: define dllexport void @_Z7redecl2v()
254*67e74705SXin Li __declspec(dllexport) void redecl2();
redecl2()255*67e74705SXin Li void redecl2() {}
256*67e74705SXin Li
257*67e74705SXin Li // Friend functions
258*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"()
259*67e74705SXin Li // GNU-DAG: define dllexport void @_Z7friend1v()
260*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"()
261*67e74705SXin Li // GNU-DAG: define dllexport void @_Z7friend2v()
262*67e74705SXin Li struct FuncFriend {
263*67e74705SXin Li friend __declspec(dllexport) void friend1();
264*67e74705SXin Li friend __declspec(dllexport) void friend2();
265*67e74705SXin Li };
friend1()266*67e74705SXin Li __declspec(dllexport) void friend1() {}
friend2()267*67e74705SXin Li void friend2() {}
268*67e74705SXin Li
269*67e74705SXin Li // Implicit declarations can be redeclared with dllexport.
270*67e74705SXin Li // MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
271*67e74705SXin Li // GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}(
272*67e74705SXin Li void* alloc(__SIZE_TYPE__ n);
operator new(__SIZE_TYPE__ n)273*67e74705SXin Li __declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); }
274*67e74705SXin Li
275*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?externalFunc@ns@@YAXXZ"()
276*67e74705SXin Li // GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv()
externalFunc()277*67e74705SXin Li namespace ns { __declspec(dllexport) void externalFunc() {} }
278*67e74705SXin Li
279*67e74705SXin Li
280*67e74705SXin Li
281*67e74705SXin Li //===----------------------------------------------------------------------===//
282*67e74705SXin Li // Function templates
283*67e74705SXin Li //===----------------------------------------------------------------------===//
284*67e74705SXin Li
285*67e74705SXin Li // Export function template definition.
286*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
287*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv()
funcTmplDef()288*67e74705SXin Li template<typename T> __declspec(dllexport) void funcTmplDef() {}
INST(funcTmplDef<ExplicitInst_Exported>)289*67e74705SXin Li INST(funcTmplDef<ExplicitInst_Exported>)
290*67e74705SXin Li
291*67e74705SXin Li // Export inline function template.
292*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"()
293*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv()
294*67e74705SXin Li template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
INST(inlineFuncTmpl1<ExplicitInst_Exported>)295*67e74705SXin Li INST(inlineFuncTmpl1<ExplicitInst_Exported>)
296*67e74705SXin Li
297*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"()
298*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv()
299*67e74705SXin Li template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
300*67e74705SXin Li INST(inlineFuncTmpl2<ExplicitInst_Exported>)
301*67e74705SXin Li
302*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"()
303*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv()
304*67e74705SXin Li template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
inlineFuncTmplDecl()305*67e74705SXin Li template<typename T> void inlineFuncTmplDecl() {}
306*67e74705SXin Li INST(inlineFuncTmplDecl<ExplicitInst_Exported>)
307*67e74705SXin Li
308*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
309*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv()
310*67e74705SXin Li template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
inlineFuncTmplDef()311*67e74705SXin Li template<typename T> inline void inlineFuncTmplDef() {}
312*67e74705SXin Li INST(inlineFuncTmplDef<ExplicitInst_Exported>)
313*67e74705SXin Li
314*67e74705SXin Li
315*67e74705SXin Li // Redeclarations
316*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"()
317*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv()
318*67e74705SXin Li template<typename T> __declspec(dllexport) void funcTmplRedecl1();
funcTmplRedecl1()319*67e74705SXin Li template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
320*67e74705SXin Li INST(funcTmplRedecl1<ExplicitInst_Exported>)
321*67e74705SXin Li
322*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"()
323*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv()
324*67e74705SXin Li template<typename T> __declspec(dllexport) void funcTmplRedecl2();
funcTmplRedecl2()325*67e74705SXin Li template<typename T> void funcTmplRedecl2() {}
326*67e74705SXin Li INST(funcTmplRedecl2<ExplicitInst_Exported>)
327*67e74705SXin Li
328*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"()
329*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv()
330*67e74705SXin Li template<typename T> __declspec(dllexport) void funcTmplRedecl3();
funcTmplRedecl3()331*67e74705SXin Li template<typename T> void funcTmplRedecl3() {}
332*67e74705SXin Li INST(funcTmplRedecl3<ExplicitInst_Exported>)
333*67e74705SXin Li
334*67e74705SXin Li
335*67e74705SXin Li // Function template friends
336*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"()
337*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv()
338*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"()
339*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv()
340*67e74705SXin Li struct FuncTmplFriend {
341*67e74705SXin Li template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
342*67e74705SXin Li template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
343*67e74705SXin Li };
funcTmplFriend1()344*67e74705SXin Li template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
funcTmplFriend2()345*67e74705SXin Li template<typename T> void funcTmplFriend2() {}
346*67e74705SXin Li INST(funcTmplFriend1<ExplicitInst_Exported>)
347*67e74705SXin Li INST(funcTmplFriend2<ExplicitInst_Exported>)
348*67e74705SXin Li
349*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"()
350*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv()
externalFuncTmpl()351*67e74705SXin Li namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} }
INST(ns::externalFuncTmpl<ExplicitInst_Exported>)352*67e74705SXin Li INST(ns::externalFuncTmpl<ExplicitInst_Exported>)
353*67e74705SXin Li
354*67e74705SXin Li
355*67e74705SXin Li template<typename T> void funcTmpl() {}
exportedFuncTmpl()356*67e74705SXin Li template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
357*67e74705SXin Li
358*67e74705SXin Li // Export implicit instantiation of an exported function template.
359*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"()
360*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv()
361*67e74705SXin Li USE(exportedFuncTmpl<ImplicitInst_Exported>)
362*67e74705SXin Li
363*67e74705SXin Li // Export explicit instantiation declaration of an exported function template.
364*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
365*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv()
366*67e74705SXin Li extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
367*67e74705SXin Li template void exportedFuncTmpl<ExplicitDecl_Exported>();
368*67e74705SXin Li
369*67e74705SXin Li // Export explicit instantiation definition of an exported function template.
370*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"()
371*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv()
372*67e74705SXin Li template void exportedFuncTmpl<ExplicitInst_Exported>();
373*67e74705SXin Li
374*67e74705SXin Li // Export specialization of an exported function template.
375*67e74705SXin Li // MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
376*67e74705SXin Li // GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv()
exportedFuncTmpl()377*67e74705SXin Li template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
378*67e74705SXin Li
379*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
380*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv()
exportedFuncTmpl()381*67e74705SXin Li template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
382*67e74705SXin Li
383*67e74705SXin Li // Not exporting specialization of an exported function template without
384*67e74705SXin Li // explicit dllexport.
385*67e74705SXin Li // MSC-DAG: define void @"\01??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"()
386*67e74705SXin Li // GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv()
exportedFuncTmpl()387*67e74705SXin Li template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
388*67e74705SXin Li
389*67e74705SXin Li
390*67e74705SXin Li // Export explicit instantiation declaration of a non-exported function template.
391*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
392*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv()
393*67e74705SXin Li extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
394*67e74705SXin Li template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
395*67e74705SXin Li
396*67e74705SXin Li // Export explicit instantiation definition of a non-exported function template.
397*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"()
398*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv()
399*67e74705SXin Li template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
400*67e74705SXin Li
401*67e74705SXin Li // Export specialization of a non-exported function template.
402*67e74705SXin Li // MSC-DAG: define dllexport void @"\01??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
403*67e74705SXin Li // GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv()
funcTmpl()404*67e74705SXin Li template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
405*67e74705SXin Li
406*67e74705SXin Li // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
407*67e74705SXin Li // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv()
funcTmpl()408*67e74705SXin Li template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
409*67e74705SXin Li
410*67e74705SXin Li
411*67e74705SXin Li
412*67e74705SXin Li //===----------------------------------------------------------------------===//
413*67e74705SXin Li // Precedence
414*67e74705SXin Li //===----------------------------------------------------------------------===//
415*67e74705SXin Li
416*67e74705SXin Li // dllexport takes precedence over the dllimport if both are specified.
417*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4
418*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4
419*67e74705SXin Li // GNU-DAG: @PrecedenceGlobal1A = dllexport global i32 0, align 4
420*67e74705SXin Li // GNU-DAG: @PrecedenceGlobal1B = dllexport global i32 0, align 4
421*67e74705SXin Li __attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // dllimport ignored
422*67e74705SXin Li __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored
423*67e74705SXin Li
424*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4
425*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4
426*67e74705SXin Li // GNU-DAG: @PrecedenceGlobal2A = dllexport global i32 0, align 4
427*67e74705SXin Li // GNU-DAG: @PrecedenceGlobal2B = dllexport global i32 0, align 4
428*67e74705SXin Li __attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // dllimport ignored
429*67e74705SXin Li __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored
430*67e74705SXin Li
431*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4
432*67e74705SXin Li // GNU-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4
433*67e74705SXin Li __declspec(dllexport) extern int PrecedenceGlobalRedecl1;
434*67e74705SXin Li __declspec(dllimport) int PrecedenceGlobalRedecl1 = 0;
435*67e74705SXin Li
436*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4
437*67e74705SXin Li // GNU-DAG: @PrecedenceGlobalRedecl2 = dllexport global i32 0, align 4
438*67e74705SXin Li __declspec(dllimport) extern int PrecedenceGlobalRedecl2;
439*67e74705SXin Li __declspec(dllexport) int PrecedenceGlobalRedecl2;
440*67e74705SXin Li
441*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4
442*67e74705SXin Li // GNU-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 0, align 4
443*67e74705SXin Li __attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
444*67e74705SXin Li __declspec(dllimport) int PrecedenceGlobalMixed1 = 0;
445*67e74705SXin Li
446*67e74705SXin Li // MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4
447*67e74705SXin Li // GNU-DAG: @PrecedenceGlobalMixed2 = dllexport global i32 0, align 4
448*67e74705SXin Li __attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
449*67e74705SXin Li __declspec(dllexport) int PrecedenceGlobalMixed2;
450*67e74705SXin Li
451*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ"
452*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ"
453*67e74705SXin Li // GNU-DAG: define dllexport void @_Z12precedence1Av()
454*67e74705SXin Li // GNU-DAG: define dllexport void @_Z12precedence1Bv()
precedence1A()455*67e74705SXin Li void __attribute__((dllimport, dllexport)) precedence1A() {}
precedence1B()456*67e74705SXin Li void __declspec(dllimport) __declspec(dllexport) precedence1B() {}
457*67e74705SXin Li
458*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ"
459*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ"
460*67e74705SXin Li // GNU-DAG: define dllexport void @_Z12precedence2Av()
461*67e74705SXin Li // GNU-DAG: define dllexport void @_Z12precedence2Bv()
precedence2A()462*67e74705SXin Li void __attribute__((dllexport, dllimport)) precedence2A() {}
precedence2B()463*67e74705SXin Li void __declspec(dllexport) __declspec(dllimport) precedence2B() {}
464*67e74705SXin Li
465*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ"
466*67e74705SXin Li // GNU-DAG: define dllexport void @_Z17precedenceRedecl1v()
467*67e74705SXin Li void __declspec(dllimport) precedenceRedecl1();
precedenceRedecl1()468*67e74705SXin Li void __declspec(dllexport) precedenceRedecl1() {}
469*67e74705SXin Li
470*67e74705SXin Li // MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ"
471*67e74705SXin Li // GNU-DAG: define dllexport void @_Z17precedenceRedecl2v()
472*67e74705SXin Li void __declspec(dllexport) precedenceRedecl2();
precedenceRedecl2()473*67e74705SXin Li void __declspec(dllimport) precedenceRedecl2() {}
474*67e74705SXin Li
475*67e74705SXin Li
476*67e74705SXin Li
477*67e74705SXin Li //===----------------------------------------------------------------------===//
478*67e74705SXin Li // Classes
479*67e74705SXin Li //===----------------------------------------------------------------------===//
480*67e74705SXin Li
481*67e74705SXin Li struct S {
aS482*67e74705SXin Li void __declspec(dllexport) a() {}
483*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ"
484*67e74705SXin Li
485*67e74705SXin Li struct T {
aS::T486*67e74705SXin Li void __declspec(dllexport) a() {}
487*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ"
488*67e74705SXin Li };
489*67e74705SXin Li };
490*67e74705SXin Li
491*67e74705SXin Li struct CtorWithClosure {
CtorWithClosureCtorWithClosure492*67e74705SXin Li __declspec(dllexport) CtorWithClosure(...) {}
493*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
494*67e74705SXin Li // M32-DAG: %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4
495*67e74705SXin Li // M32-DAG: store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4
496*67e74705SXin Li // M32-DAG: %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]]
497*67e74705SXin Li // M32-DAG: call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"\01??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]])
498*67e74705SXin Li // M32-DAG: ret void
499*67e74705SXin Li };
500*67e74705SXin Li
501*67e74705SXin Li #define DELETE_IMPLICIT_MEMBERS(ClassName) \
502*67e74705SXin Li ClassName(ClassName &&) = delete; \
503*67e74705SXin Li ClassName(ClassName &) = delete; \
504*67e74705SXin Li ~ClassName() = delete; \
505*67e74705SXin Li ClassName &operator=(ClassName &) = delete
506*67e74705SXin Li
507*67e74705SXin Li struct __declspec(dllexport) ClassWithClosure {
508*67e74705SXin Li DELETE_IMPLICIT_MEMBERS(ClassWithClosure);
ClassWithClosureClassWithClosure509*67e74705SXin Li ClassWithClosure(...) {}
510*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
511*67e74705SXin Li // M32-DAG: %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4
512*67e74705SXin Li // M32-DAG: store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4
513*67e74705SXin Li // M32-DAG: %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]]
514*67e74705SXin Li // M32-DAG: call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"\01??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]])
515*67e74705SXin Li // M32-DAG: ret void
516*67e74705SXin Li };
517*67e74705SXin Li
518*67e74705SXin Li struct __declspec(dllexport) NestedOuter {
519*67e74705SXin Li DELETE_IMPLICIT_MEMBERS(NestedOuter);
NestedOuterNestedOuter520*67e74705SXin Li NestedOuter(void *p = 0) {}
521*67e74705SXin Li struct __declspec(dllexport) NestedInner {
522*67e74705SXin Li DELETE_IMPLICIT_MEMBERS(NestedInner);
NestedInnerNestedOuter::NestedInner523*67e74705SXin Li NestedInner(void *p = 0) {}
524*67e74705SXin Li };
525*67e74705SXin Li };
526*67e74705SXin Li
527*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
528*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
529*67e74705SXin Li
530*67e74705SXin Li template <typename T>
531*67e74705SXin Li struct SomeTemplate {
SomeTemplateSomeTemplate532*67e74705SXin Li SomeTemplate(T o = T()) : o(o) {}
533*67e74705SXin Li T o;
534*67e74705SXin Li };
535*67e74705SXin Li // MSVC2015-DAG: define weak_odr dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}@$$Q{{.+}}@@Z"
536*67e74705SXin Li // MSVC2013-DAG: define weak_odr dllexport {{.+}} @"\01??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z"
537*67e74705SXin Li struct __declspec(dllexport) InheritFromTemplate : SomeTemplate<int> {};
538*67e74705SXin Li
539*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
540*67e74705SXin Li
541*67e74705SXin Li namespace PR23801 {
542*67e74705SXin Li template <typename>
543*67e74705SXin Li struct S {
~SPR23801::S544*67e74705SXin Li ~S() {}
545*67e74705SXin Li };
546*67e74705SXin Li struct A {
547*67e74705SXin Li A(int);
548*67e74705SXin Li S<int> s;
549*67e74705SXin Li };
550*67e74705SXin Li struct __declspec(dllexport) B {
BPR23801::B551*67e74705SXin Li B(A = 0) {}
552*67e74705SXin Li };
553*67e74705SXin Li
554*67e74705SXin Li }
555*67e74705SXin Li //
556*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@PR23801@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
557*67e74705SXin Li
558*67e74705SXin Li struct __declspec(dllexport) T {
559*67e74705SXin Li // Copy assignment operator:
560*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z"
561*67e74705SXin Li
562*67e74705SXin Li // Explicitly defaulted copy constructur:
563*67e74705SXin Li T(const T&) = default;
564*67e74705SXin Li // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
565*67e74705SXin Li
aT566*67e74705SXin Li void a() {}
567*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
568*67e74705SXin Li
569*67e74705SXin Li static int b;
570*67e74705SXin Li // M32-DAG: @"\01?b@T@@2HA" = external dllexport global i32
571*67e74705SXin Li
572*67e74705SXin Li static int c;
573*67e74705SXin Li // M32-DAG: @"\01?c@T@@2HA" = dllexport global i32 0, align 4
574*67e74705SXin Li };
575*67e74705SXin Li
576*67e74705SXin Li USEVAR(T::b)
577*67e74705SXin Li int T::c;
578*67e74705SXin Li
579*67e74705SXin Li // Export template class with static member variable
580*67e74705SXin Li // MSC-DAG: @"\01?StaticClassVarExpTmplClass@?$TmplClass@H@@2HA" = weak_odr dllexport global i32 0, comdat, align 4
581*67e74705SXin Li // GNU-DAG: @_ZN9TmplClassIiE26StaticClassVarExpTmplClassE = weak_odr dllexport global i32 0, comdat, align 4
582*67e74705SXin Li template<typename T>
583*67e74705SXin Li struct __declspec(dllexport) TmplClass
584*67e74705SXin Li {
585*67e74705SXin Li static T StaticClassVarExpTmplClass;
586*67e74705SXin Li };
587*67e74705SXin Li
588*67e74705SXin Li template<typename T>
589*67e74705SXin Li T TmplClass<T>::StaticClassVarExpTmplClass;
590*67e74705SXin Li
591*67e74705SXin Li // Export a definition of a template function.
592*67e74705SXin Li // MSC-DAG: define weak_odr dllexport i32 @"\01??$TypeFunTmpl@H@@YAHH@Z"
593*67e74705SXin Li // GNU-DAG: define weak_odr dllexport i32 @_Z11TypeFunTmplIiET_S0_
594*67e74705SXin Li template<typename T>
TypeFunTmpl(T t)595*67e74705SXin Li T __declspec(dllexport) TypeFunTmpl(T t) { return t + t; }
596*67e74705SXin Li
597*67e74705SXin Li // Instantiate the exported template class and the exported template function.
useExportedTmplStaticAndFun()598*67e74705SXin Li int useExportedTmplStaticAndFun()
599*67e74705SXin Li {
600*67e74705SXin Li return TmplClass<int>::StaticClassVarExpTmplClass + TypeFunTmpl<int>(10);
601*67e74705SXin Li }
602*67e74705SXin Li
fooU603*67e74705SXin Li template <typename T> struct __declspec(dllexport) U { void foo() {} };
604*67e74705SXin Li struct __declspec(dllexport) V : public U<int> { };
605*67e74705SXin Li // U<int>'s assignment operator is emitted.
606*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
607*67e74705SXin Li
608*67e74705SXin Li struct __declspec(dllexport) W { virtual void foo(); };
foo()609*67e74705SXin Li void W::foo() {}
610*67e74705SXin Li // Default ctor:
611*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ"
612*67e74705SXin Li // Copy ctor:
613*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z"
614*67e74705SXin Li // vftable:
615*67e74705SXin Li // M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)], comdat($"\01??_7W@@6B@")
616*67e74705SXin Li // M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias i8*, getelementptr inbounds ([2 x i8*], [2 x i8*]* [[W_VTABLE]], i32 0, i32 1)
617*67e74705SXin Li // G32-DAG: @_ZTV1W = dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
618*67e74705SXin Li
619*67e74705SXin Li struct __declspec(dllexport) X : public virtual W {};
620*67e74705SXin Li // vbtable:
621*67e74705SXin Li // M32-DAG: @"\01??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4]
622*67e74705SXin Li
623*67e74705SXin Li struct __declspec(dllexport) Y {
624*67e74705SXin Li // Move assignment operator:
625*67e74705SXin Li // MSVC2015-DAG: define weak_odr dllexport {{.+}} @"\01??4Y@@Q{{.+}}@$$Q{{.+}}@@Z"
626*67e74705SXin Li // MSVC2013-DAG: define weak_odr dllexport {{.+}} @"\01??4Y@@Q{{.+}}0@A{{.+}}0@@Z"
627*67e74705SXin Li
628*67e74705SXin Li int x;
629*67e74705SXin Li };
630*67e74705SXin Li
~ZZ631*67e74705SXin Li struct __declspec(dllexport) Z { virtual ~Z() {} };
632*67e74705SXin Li // The scalar deleting dtor does not get exported:
633*67e74705SXin Li // M32-DAG: define linkonce_odr x86_thiscallcc i8* @"\01??_GZ@@UAEPAXI@Z"
634*67e74705SXin Li
635*67e74705SXin Li
636*67e74705SXin Li // The user-defined dtor does get exported:
637*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
638*67e74705SXin Li
639*67e74705SXin Li namespace UseDtorAlias {
640*67e74705SXin Li struct __declspec(dllexport) A { ~A(); };
641*67e74705SXin Li struct __declspec(dllexport) B : A { ~B(); };
~A()642*67e74705SXin Li A::~A() { }
~B()643*67e74705SXin Li B::~B() { }
644*67e74705SXin Li // Emit a alias definition of B's constructor.
645*67e74705SXin Li // M32-DAG: @"\01??1B@UseDtorAlias@@QAE@XZ" = dllexport alias {{.*}} @"\01??1A@UseDtorAlias@@QAE@XZ"
646*67e74705SXin Li }
647*67e74705SXin Li
648*67e74705SXin Li struct __declspec(dllexport) DefaultedCtorsDtors {
649*67e74705SXin Li DefaultedCtorsDtors() = default;
650*67e74705SXin Li // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
651*67e74705SXin Li ~DefaultedCtorsDtors() = default;
652*67e74705SXin Li // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
653*67e74705SXin Li };
654*67e74705SXin Li
655*67e74705SXin Li // Export defaulted member function definitions declared inside class.
656*67e74705SXin Li struct __declspec(dllexport) ExportDefaultedInclassDefs {
657*67e74705SXin Li ExportDefaultedInclassDefs() = default;
658*67e74705SXin Li // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
659*67e74705SXin Li // M64VS2013-DAG: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
660*67e74705SXin Li // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
661*67e74705SXin Li // M64VS2015-NOT: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* returned %this)
662*67e74705SXin Li
663*67e74705SXin Li ~ExportDefaultedInclassDefs() = default;
664*67e74705SXin Li // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
665*67e74705SXin Li // M64VS2013-DAG: define weak_odr dllexport void @"\01??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
666*67e74705SXin Li // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportDefaultedInclassDefs@@QAE@XZ"(%struct.ExportDefaultedInclassDefs* %this)
667*67e74705SXin Li // M64VS2015-NOT: define weak_odr dllexport void @"\01??1ExportDefaultedInclassDefs@@QEAA@XZ"(%struct.ExportDefaultedInclassDefs* %this)
668*67e74705SXin Li
669*67e74705SXin Li ExportDefaultedInclassDefs(const ExportDefaultedInclassDefs&) = default;
670*67e74705SXin Li // M32VS2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
671*67e74705SXin Li // M64VS2013-DAG: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
672*67e74705SXin Li // M32VS2015-NOT: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
673*67e74705SXin Li // M64VS2015-NOT: define weak_odr dllexport %struct.ExportDefaultedInclassDefs* @"\01??0ExportDefaultedInclassDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* returned %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
674*67e74705SXin Li
675*67e74705SXin Li ExportDefaultedInclassDefs& operator=(const ExportDefaultedInclassDefs&) = default;
676*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"\01??4ExportDefaultedInclassDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
677*67e74705SXin Li // M64-DAG: define weak_odr dllexport dereferenceable({{[0-9]+}}) %struct.ExportDefaultedInclassDefs* @"\01??4ExportDefaultedInclassDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedInclassDefs* %this, %struct.ExportDefaultedInclassDefs* dereferenceable({{[0-9]+}}))
678*67e74705SXin Li };
679*67e74705SXin Li
680*67e74705SXin Li namespace ReferencedInlineMethodInNestedClass {
681*67e74705SXin Li struct __declspec(dllexport) S {
fooReferencedInlineMethodInNestedClass::S682*67e74705SXin Li void foo() {
683*67e74705SXin Li t->bar();
684*67e74705SXin Li }
685*67e74705SXin Li struct T {
barReferencedInlineMethodInNestedClass::S::T686*67e74705SXin Li void bar() {}
687*67e74705SXin Li };
688*67e74705SXin Li T *t;
689*67e74705SXin Li };
690*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
691*67e74705SXin Li // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
692*67e74705SXin Li }
693*67e74705SXin Li
694*67e74705SXin Li // MS ignores DLL attributes on partial specializations.
695*67e74705SXin Li template <typename T> struct PartiallySpecializedClassTemplate {};
696*67e74705SXin Li template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f(); };
f()697*67e74705SXin Li template <typename T> void PartiallySpecializedClassTemplate<T*>::f() {}
698*67e74705SXin Li USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
699*67e74705SXin Li // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
700*67e74705SXin Li // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
701*67e74705SXin Li
702*67e74705SXin Li // Attributes on explicit specializations are honored.
703*67e74705SXin Li template <typename T> struct ExplicitlySpecializedClassTemplate {};
704*67e74705SXin Li template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
f()705*67e74705SXin Li void ExplicitlySpecializedClassTemplate<void*>::f() {}
706*67e74705SXin Li USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
707*67e74705SXin Li // M32-DAG: define dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
708*67e74705SXin Li // G32-DAG: define dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
709*67e74705SXin Li
710*67e74705SXin Li // MS inherits DLL attributes to partial specializations.
711*67e74705SXin Li template <typename T> struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate {};
fPartiallySpecializedExportedClassTemplate712*67e74705SXin Li template <typename T> struct PartiallySpecializedExportedClassTemplate<T*> { void f() {} };
713*67e74705SXin Li USEMEMFUNC(PartiallySpecializedExportedClassTemplate<void*>, f);
714*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$PartiallySpecializedExportedClassTemplate@PAX@@QAEXXZ"
715*67e74705SXin Li // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN41PartiallySpecializedExportedClassTemplateIPvE1fEv
716*67e74705SXin Li
717*67e74705SXin Li // MS ignores DLL attributes on partial specializations; inheritance still works though.
718*67e74705SXin Li template <typename T> struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate2 {};
719*67e74705SXin Li template <typename T> struct __declspec(dllimport) PartiallySpecializedExportedClassTemplate2<T*> { void f(); };
f()720*67e74705SXin Li template <typename T> void PartiallySpecializedExportedClassTemplate2<T*>::f() {}
721*67e74705SXin Li USEMEMFUNC(PartiallySpecializedExportedClassTemplate2<void*>, f);
722*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$PartiallySpecializedExportedClassTemplate2@PAX@@QAEXXZ"
723*67e74705SXin Li // G32-DAG: declare dllimport x86_thiscallcc void @_ZN42PartiallySpecializedExportedClassTemplate2IPvE1fEv
724*67e74705SXin Li
725*67e74705SXin Li // Attributes on the instantiation take precedence over attributes on the template.
fExplicitlyInstantiatedWithDifferentAttr726*67e74705SXin Li template <typename T> struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
727*67e74705SXin Li template struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr<int>;
728*67e74705SXin Li USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);
729*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"
730*67e74705SXin Li
731*67e74705SXin Li // Don't create weak dllexport aliases. (PR21373)
732*67e74705SXin Li struct NonExportedBaseClass {
733*67e74705SXin Li virtual ~NonExportedBaseClass();
734*67e74705SXin Li };
~NonExportedBaseClass()735*67e74705SXin Li NonExportedBaseClass::~NonExportedBaseClass() {}
736*67e74705SXin Li
737*67e74705SXin Li struct __declspec(dllexport) ExportedDerivedClass : NonExportedBaseClass {};
738*67e74705SXin Li // M32-DAG: weak_odr dllexport x86_thiscallcc void @"\01??1ExportedDerivedClass@@UAE@XZ"
739*67e74705SXin Li
740*67e74705SXin Li // Do not assert about generating code for constexpr functions twice during explicit instantiation (PR21718).
741*67e74705SXin Li template <typename T> struct ExplicitInstConstexprMembers {
742*67e74705SXin Li // Copy assignment operator
743*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %struct.ExplicitInstConstexprMembers* @"\01??4?$ExplicitInstConstexprMembers@X@@QAEAAU0@ABU0@@Z"
744*67e74705SXin Li
ExplicitInstConstexprMembersExplicitInstConstexprMembers745*67e74705SXin Li constexpr ExplicitInstConstexprMembers() {}
746*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@XZ"
747*67e74705SXin Li
748*67e74705SXin Li ExplicitInstConstexprMembers(const ExplicitInstConstexprMembers&) = default;
749*67e74705SXin Li // M32MSVC2013-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstConstexprMembers* @"\01??0?$ExplicitInstConstexprMembers@X@@QAE@ABU0@@Z"
750*67e74705SXin Li
fExplicitInstConstexprMembers751*67e74705SXin Li constexpr int f() const { return 42; }
752*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc i32 @"\01?f@?$ExplicitInstConstexprMembers@X@@QBEHXZ"
753*67e74705SXin Li };
754*67e74705SXin Li template struct __declspec(dllexport) ExplicitInstConstexprMembers<void>;
755*67e74705SXin Li
fExplicitInstantiationDeclTemplate756*67e74705SXin Li template <typename T> struct ExplicitInstantiationDeclTemplate { void f() {} };
757*67e74705SXin Li extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>;
758*67e74705SXin Li USEMEMFUNC(ExplicitInstantiationDeclTemplate<int>, f);
759*67e74705SXin Li // M32-DAG: {{declare|define available_externally}} x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclTemplate@H@@QAEXXZ"
760*67e74705SXin Li
fExplicitInstantiationDeclExportedTemplate761*67e74705SXin Li template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate { void f() {} };
762*67e74705SXin Li extern template struct ExplicitInstantiationDeclExportedTemplate<int>;
763*67e74705SXin Li USEMEMFUNC(ExplicitInstantiationDeclExportedTemplate<int>, f);
764*67e74705SXin Li // M32-DAG: {{declare|define available_externally}} x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedTemplate@H@@QAEXXZ"
765*67e74705SXin Li
ExplicitInstantiationDeclExportedDefTemplateExplicitInstantiationDeclExportedDefTemplate766*67e74705SXin Li template <typename T> struct ExplicitInstantiationDeclExportedDefTemplate { void f() {} ExplicitInstantiationDeclExportedDefTemplate() {} };
767*67e74705SXin Li extern template struct ExplicitInstantiationDeclExportedDefTemplate<int>;
768*67e74705SXin Li template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefTemplate<int>;
769*67e74705SXin Li USEMEMFUNC(ExplicitInstantiationDeclExportedDefTemplate<int>, f);
770*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAEXXZ"
771*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAE@XZ"
772*67e74705SXin Li // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv
773*67e74705SXin Li
774*67e74705SXin Li namespace { struct InternalLinkageType {}; }
775*67e74705SXin Li struct __declspec(dllexport) PR23308 {
776*67e74705SXin Li void f(InternalLinkageType*);
777*67e74705SXin Li };
f(InternalLinkageType *)778*67e74705SXin Li void PR23308::f(InternalLinkageType*) {}
use(PR23308 * p)779*67e74705SXin Li long use(PR23308* p) { p->f(nullptr); }
780*67e74705SXin Li // M32-DAG: define internal x86_thiscallcc void @"\01?f@PR23308@@QAEXPAUInternalLinkageType@?A@@@Z"
781*67e74705SXin Li
fPR23770BaseTemplate782*67e74705SXin Li template <typename T> struct PR23770BaseTemplate { void f() {} };
783*67e74705SXin Li template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
784*67e74705SXin Li extern template struct PR23770DerivedTemplate<int>;
785*67e74705SXin Li template struct __declspec(dllexport) PR23770DerivedTemplate<int>;
786*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$PR23770BaseTemplate@H@@QAEXXZ"
787*67e74705SXin Li
788*67e74705SXin Li namespace InClassInits {
789*67e74705SXin Li
790*67e74705SXin Li struct __declspec(dllexport) S {
791*67e74705SXin Li int x = 42;
792*67e74705SXin Li };
793*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::S"* @"\01??0S@InClassInits@@QAE@XZ"
794*67e74705SXin Li
795*67e74705SXin Li // dllexport an already instantiated class template.
796*67e74705SXin Li template <typename T> struct Base {
797*67e74705SXin Li int x = 42;
798*67e74705SXin Li };
799*67e74705SXin Li Base<int> base;
800*67e74705SXin Li struct __declspec(dllexport) T : Base<int> { };
801*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Base"* @"\01??0?$Base@H@InClassInits@@QAE@XZ"
802*67e74705SXin Li
803*67e74705SXin Li struct A { A(int); };
804*67e74705SXin Li struct __declspec(dllexport) U {
805*67e74705SXin Li // Class with both default constructor closure and in-class initializer.
UInClassInits::U806*67e74705SXin Li U(A = 0) {}
807*67e74705SXin Li int x = 0;
808*67e74705SXin Li };
809*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::U"* @"\01??0U@InClassInits@@QAE@UA@1@@Z"
810*67e74705SXin Li
811*67e74705SXin Li struct Evil {
812*67e74705SXin Li template <typename T> struct Base {
813*67e74705SXin Li int x = 0;
814*67e74705SXin Li };
815*67e74705SXin Li struct S : Base<int> {};
816*67e74705SXin Li // The already instantiated Base<int> becomes dllexported below, but the
817*67e74705SXin Li // in-class initializer for Base<>::x still hasn't been parsed, so emitting
818*67e74705SXin Li // the default ctor must still be delayed.
819*67e74705SXin Li struct __declspec(dllexport) T : Base<int> {};
820*67e74705SXin Li };
821*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.InClassInits::Evil::Base"* @"\01??0?$Base@H@Evil@InClassInits@@QAE@XZ"
822*67e74705SXin Li
823*67e74705SXin Li template <typename T> struct Foo {};
824*67e74705SXin Li template <typename T> struct Bar {
operator =InClassInits::Bar825*67e74705SXin Li Bar<T> &operator=(Foo<T>) {}
826*67e74705SXin Li };
827*67e74705SXin Li struct __declspec(dllexport) Baz {
828*67e74705SXin Li Bar<int> n;
829*67e74705SXin Li };
830*67e74705SXin Li // After parsing Baz, in ActOnFinishCXXNonNestedClass we would synthesize
831*67e74705SXin Li // Baz's operator=, causing instantiation of Foo<int> after which
832*67e74705SXin Li // ActOnFinishCXXNonNestedClass is called, and we would bite our own tail.
833*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable(1) %"struct.InClassInits::Baz"* @"\01??4Baz@InClassInits@@QAEAAU01@ABU01@@Z"
834*67e74705SXin Li }
835*67e74705SXin Li
836*67e74705SXin Li // We had an issue where instantiating A would force emission of B's delayed
837*67e74705SXin Li // exported methods.
838*67e74705SXin Li namespace pr26490 {
839*67e74705SXin Li template <typename T> struct A { };
840*67e74705SXin Li struct __declspec(dllexport) B {
Bpr26490::B841*67e74705SXin Li B(int = 0) {}
m_fn1pr26490::B842*67e74705SXin Li A<int> m_fn1() {}
843*67e74705SXin Li };
844*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FB@pr26490@@QAEXXZ"
845*67e74705SXin Li }
846*67e74705SXin Li
847*67e74705SXin Li // dllexport trumps dllexport on an explicit instantiation.
fExplicitInstantiationTwoAttributes848*67e74705SXin Li template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
849*67e74705SXin Li template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
850*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
851*67e74705SXin Li
852*67e74705SXin Li
853*67e74705SXin Li //===----------------------------------------------------------------------===//
854*67e74705SXin Li // Classes with template base classes
855*67e74705SXin Li //===----------------------------------------------------------------------===//
856*67e74705SXin Li
857*67e74705SXin Li template <typename T> struct ClassTemplate { void func(); };
func()858*67e74705SXin Li template <typename T> void ClassTemplate<T>::func() {}
859*67e74705SXin Li template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };
func()860*67e74705SXin Li template <typename T> void ExportedClassTemplate<T>::func() {}
861*67e74705SXin Li template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };
func()862*67e74705SXin Li template <typename T> void ImportedClassTemplate<T>::func() {}
863*67e74705SXin Li
funcExplicitlySpecializedTemplate864*67e74705SXin Li template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
865*67e74705SXin Li template <> struct ExplicitlySpecializedTemplate<int> { void func(); };
func()866*67e74705SXin Li void ExplicitlySpecializedTemplate<int>::func() {}
funcExplicitlyExportSpecializedTemplate867*67e74705SXin Li template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
868*67e74705SXin Li template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };
func()869*67e74705SXin Li void ExplicitlyExportSpecializedTemplate<int>::func() {}
870*67e74705SXin Li template <typename T> struct ExplicitlyImportSpecializedTemplate { void func(); };
871*67e74705SXin Li template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };
872*67e74705SXin Li
873*67e74705SXin Li template <typename T> struct ExplicitlyInstantiatedTemplate { void func(); };
func()874*67e74705SXin Li template <typename T> void ExplicitlyInstantiatedTemplate<T>::func() {}
875*67e74705SXin Li template struct ExplicitlyInstantiatedTemplate<int>;
876*67e74705SXin Li template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };
func()877*67e74705SXin Li template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}
878*67e74705SXin Li template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
879*67e74705SXin Li template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };
880*67e74705SXin Li template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
881*67e74705SXin Li
882*67e74705SXin Li
883*67e74705SXin Li // MS: ClassTemplate<int> gets exported.
884*67e74705SXin Li struct __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
885*67e74705SXin Li USEMEMFUNC(DerivedFromTemplate, func)
886*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
887*67e74705SXin Li // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
888*67e74705SXin Li
889*67e74705SXin Li // ExportedTemplate is explicitly exported.
890*67e74705SXin Li struct __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
891*67e74705SXin Li USEMEMFUNC(DerivedFromExportedTemplate, func)
892*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
893*67e74705SXin Li // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
894*67e74705SXin Li
895*67e74705SXin Li // ImportedClassTemplate is explicitly imported.
896*67e74705SXin Li struct __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
897*67e74705SXin Li USEMEMFUNC(DerivedFromImportedTemplate, func)
898*67e74705SXin Li // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
899*67e74705SXin Li // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
900*67e74705SXin Li
901*67e74705SXin Li // Base class already implicitly instantiated without dll attribute.
902*67e74705SXin Li struct DerivedFromTemplateD : public ClassTemplate<double> {};
903*67e74705SXin Li struct __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
904*67e74705SXin Li USEMEMFUNC(DerivedFromTemplateD2, func)
905*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
906*67e74705SXin Li // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
907*67e74705SXin Li
908*67e74705SXin Li // MS: Base class already instantiated with different dll attribute.
909*67e74705SXin Li struct __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
910*67e74705SXin Li struct __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
911*67e74705SXin Li USEMEMFUNC(DerivedFromTemplateB2, func)
912*67e74705SXin Li // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
913*67e74705SXin Li // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
914*67e74705SXin Li
915*67e74705SXin Li // Base class already specialized without dll attribute.
916*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
917*67e74705SXin Li USEMEMFUNC(DerivedFromExplicitlySpecializedTemplate, func)
918*67e74705SXin Li // M32-DAG: define x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
919*67e74705SXin Li // G32-DAG: define x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
920*67e74705SXin Li
921*67e74705SXin Li // Base class alredy specialized with export attribute.
922*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
923*67e74705SXin Li USEMEMFUNC(DerivedFromExplicitlyExportSpecializedTemplate, func)
924*67e74705SXin Li // M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
925*67e74705SXin Li // G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
926*67e74705SXin Li
927*67e74705SXin Li // Base class already specialized with import attribute.
928*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
929*67e74705SXin Li USEMEMFUNC(DerivedFromExplicitlyImportSpecializedTemplate, func)
930*67e74705SXin Li // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
931*67e74705SXin Li // G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
932*67e74705SXin Li
933*67e74705SXin Li // Base class already instantiated without dll attribute.
934*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
935*67e74705SXin Li USEMEMFUNC(DerivedFromExplicitlyInstantiatedTemplate, func)
936*67e74705SXin Li // M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
937*67e74705SXin Li // G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
938*67e74705SXin Li
939*67e74705SXin Li // Base class already instantiated with export attribute.
940*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
941*67e74705SXin Li USEMEMFUNC(DerivedFromExplicitlyExportInstantiatedTemplate, func)
942*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
943*67e74705SXin Li // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
944*67e74705SXin Li
945*67e74705SXin Li // Base class already instantiated with import attribute.
946*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
947*67e74705SXin Li USEMEMFUNC(DerivedFromExplicitlyImportInstantiatedTemplate, func)
948*67e74705SXin Li // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
949*67e74705SXin Li // G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
950*67e74705SXin Li
951*67e74705SXin Li // MS: A dll attribute propagates through multiple levels of instantiation.
funcTopClass952*67e74705SXin Li template <typename T> struct TopClass { void func() {} };
953*67e74705SXin Li template <typename T> struct MiddleClass : public TopClass<T> { };
954*67e74705SXin Li struct __declspec(dllexport) BottomClass : public MiddleClass<int> { };
955*67e74705SXin Li USEMEMFUNC(BottomClass, func)
956*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
957*67e74705SXin Li // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
958*67e74705SXin Li
funcExplicitInstantiationDeclTemplateBase959*67e74705SXin Li template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
960*67e74705SXin Li extern template struct ExplicitInstantiationDeclTemplateBase<int>;
961*67e74705SXin Li struct __declspec(dllexport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
962*67e74705SXin Li template struct ExplicitInstantiationDeclTemplateBase<int>;
963*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ"
964*67e74705SXin Li // G32-DAG: define weak_odr x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv
965*67e74705SXin Li
966*67e74705SXin Li // PR26076
967*67e74705SXin Li struct LayerSelectionBound;
968*67e74705SXin Li template <typename> struct Selection {};
969*67e74705SXin Li typedef Selection<LayerSelectionBound> LayerSelection;
970*67e74705SXin Li struct LayerImpl;
971*67e74705SXin Li struct __declspec(dllexport) LayerTreeImpl {
972*67e74705SXin Li struct __declspec(dllexport) ElementLayers {
973*67e74705SXin Li LayerImpl *main = nullptr;
974*67e74705SXin Li };
975*67e74705SXin Li LayerSelection foo;
976*67e74705SXin Li };
977*67e74705SXin Li // M32-DAG: define weak_odr dllexport x86_thiscallcc %"struct.LayerTreeImpl::ElementLayers"* @"\01??0ElementLayers@LayerTreeImpl@@QAE@XZ"
978*67e74705SXin Li // M64-DAG: define weak_odr dllexport %"struct.LayerTreeImpl::ElementLayers"* @"\01??0ElementLayers@LayerTreeImpl@@QEAA@XZ"
979*67e74705SXin Li
980*67e74705SXin Li class __declspec(dllexport) ACE_Shared_Object {
981*67e74705SXin Li public:
982*67e74705SXin Li virtual ~ACE_Shared_Object();
983*67e74705SXin Li };
984*67e74705SXin Li class __declspec(dllexport) ACE_Service_Object : public ACE_Shared_Object {};
985*67e74705SXin Li // Implicit move constructor declaration.
986*67e74705SXin Li // MSVC2015-DAG: define weak_odr dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
987*67e74705SXin Li // The declarations should not be exported.
988*67e74705SXin Li // MSVC2013-NOT: define weak_odr dllexport {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
989