1// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
2// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
3// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
4// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
5
6// RUN: %clang_cc1 -triple i686-pc-win32 -O1 -mconstructor-aliases -std=c++1y -emit-llvm -o - %s | FileCheck %s --check-prefix=MSC --check-prefix=M32
7
8// Helper structs to make templates more expressive.
9struct ImplicitInst_Exported {};
10struct ExplicitDecl_Exported {};
11struct ExplicitInst_Exported {};
12struct ExplicitSpec_Exported {};
13struct ExplicitSpec_Def_Exported {};
14struct ExplicitSpec_InlineDef_Exported {};
15struct ExplicitSpec_NotExported {};
16struct External { int v; };
17
18#define JOIN2(x, y) x##y
19#define JOIN(x, y) JOIN2(x, y)
20#define UNIQ(name) JOIN(name, __LINE__)
21#define USEVAR(var) int UNIQ(use)() { return var; }
22#define USE(func) void UNIQ(use)() { func(); }
23#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
24#define INSTVAR(var) template int var;
25#define INST(func) template void func();
26
27// The vftable for struct W is comdat largest because we have RTTI.
28// M32-DAG: $"\01??_7W@@6B@" = comdat largest
29
30
31//===----------------------------------------------------------------------===//
32// Globals
33//===----------------------------------------------------------------------===//
34
35// Declarations are not exported.
36// MSC-NOT: @"\01?ExternGlobalDecl@@3HA"
37// GNU-NOT: @ExternGlobalDecl
38__declspec(dllexport) extern int ExternGlobalDecl;
39
40// dllexport implies a definition.
41// MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4
42// GNU-DAG: @GlobalDef            = dllexport global i32 0, align 4
43__declspec(dllexport) int GlobalDef;
44
45// Export definition.
46// MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4
47// GNU-DAG: @GlobalInit1            = dllexport global i32 1, align 4
48__declspec(dllexport) int GlobalInit1 = 1;
49
50// MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4
51// GNU-DAG: @GlobalInit2            = dllexport global i32 1, align 4
52int __declspec(dllexport) GlobalInit2 = 1;
53
54// Declare, then export definition.
55// MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4
56// GNU-DAG: @GlobalDeclInit            = dllexport global i32 1, align 4
57__declspec(dllexport) extern int GlobalDeclInit;
58int GlobalDeclInit = 1;
59
60// Redeclarations
61// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4
62// GNU-DAG: @GlobalRedecl1            = dllexport global i32 0, align 4
63__declspec(dllexport) extern int GlobalRedecl1;
64__declspec(dllexport)        int GlobalRedecl1;
65
66// MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4
67// GNU-DAG: @GlobalRedecl2            = dllexport global i32 0, align 4
68__declspec(dllexport) extern int GlobalRedecl2;
69                             int GlobalRedecl2;
70
71// MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = dllexport global i32 0, align 4
72// GNU-DAG: @_ZN2ns14ExternalGlobalE      = dllexport global i32 0, align 4
73namespace ns { __declspec(dllexport) int ExternalGlobal; }
74
75// MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4
76// GNU-DAG: @ExternalAutoTypeGlobal                      = dllexport global %struct.External zeroinitializer, align 4
77__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
78
79int f();
80// MSC-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0
81// MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0
82int __declspec(dllexport) nonInlineStaticLocalsFunc() {
83  static int x = f();
84  return x++;
85};
86
87// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0
88// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0
89// Note: MinGW doesn't seem to export the static local here.
90inline int __declspec(dllexport) inlineStaticLocalsFunc() {
91  static int x = f();
92  return x++;
93}
94
95
96
97//===----------------------------------------------------------------------===//
98// Variable templates
99//===----------------------------------------------------------------------===//
100
101// Declarations are not exported.
102
103// dllexport implies a definition.
104// MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA"
105// GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
106template<typename T> __declspec(dllexport) int VarTmplDef;
107INSTVAR(VarTmplDef<ExplicitInst_Exported>)
108
109// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global
110// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE          = external dllexport global
111template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
112USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
113
114// Export definition.
115// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
116// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
117template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
118INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
119
120// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
121// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
122template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
123INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
124
125// Declare, then export definition.
126// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
127// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
128template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
129template<typename T>                              int VarTmplDeclInit = 1;
130INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
131
132// Redeclarations
133// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
134// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
135template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
136template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
137INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
138
139// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
140// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
141template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
142template<typename T>                              int VarTmplRedecl2 = 1;
143INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
144
145// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4
146// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE        = weak_odr dllexport global i32 1, align 4
147namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
148INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
149
150// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4
151// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE                    = weak_odr dllexport global %struct.External zeroinitializer, align 4
152template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
153template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
154
155
156template<typename T> int VarTmpl = 1;
157template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
158
159// Export implicit instantiation of an exported variable template.
160// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
161// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
162USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
163
164// Export explicit instantiation declaration of an exported variable template.
165// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
166// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE          = weak_odr dllexport global i32 1, align 4
167extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
168       template int ExportedVarTmpl<ExplicitDecl_Exported>;
169
170// Export explicit instantiation definition of an exported variable template.
171// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
172// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
173template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
174
175// Export specialization of an exported variable template.
176// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
177// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE          = dllexport global i32 0, align 4
178template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
179
180// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
181// GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE          = dllexport global i32 1, align 4
182template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
183
184// Not exporting specialization of an exported variable template without
185// explicit dllexport.
186// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4
187// GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE          = global i32 0, align 4
188template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
189
190
191// Export explicit instantiation declaration of a non-exported variable template.
192// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
193// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE           = weak_odr dllexport global i32 1, align 4
194extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
195       template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
196
197// Export explicit instantiation definition of a non-exported variable template.
198// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
199// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE           = weak_odr dllexport global i32 1, align 4
200template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
201
202// Export specialization of a non-exported variable template.
203// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
204// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE           = dllexport global i32 0, align 4
205template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
206
207// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
208// GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE           = dllexport global i32 1, align 4
209template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
210
211
212
213//===----------------------------------------------------------------------===//
214// Functions
215//===----------------------------------------------------------------------===//
216
217// Declarations are not exported.
218
219// Export function definition.
220// MSC-DAG: define dllexport void @"\01?def@@YAXXZ"()
221// GNU-DAG: define dllexport void @_Z3defv()
222__declspec(dllexport) void def() {}
223
224// extern "C"
225// MSC-DAG: define dllexport void @externC()
226// GNU-DAG: define dllexport void @externC()
227extern "C" __declspec(dllexport) void externC() {}
228
229// Export inline function.
230// MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"()
231// GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv()
232__declspec(dllexport) inline void inlineFunc() {}
233
234// MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"()
235// GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv()
236__declspec(dllexport) inline void inlineDecl();
237                             void inlineDecl() {}
238
239// MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"()
240// GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv()
241__declspec(dllexport) void inlineDef();
242               inline void inlineDef() {}
243
244// Redeclarations
245// MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"()
246// GNU-DAG: define dllexport void @_Z7redecl1v()
247__declspec(dllexport) void redecl1();
248__declspec(dllexport) void redecl1() {}
249
250// MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"()
251// GNU-DAG: define dllexport void @_Z7redecl2v()
252__declspec(dllexport) void redecl2();
253                      void redecl2() {}
254
255// Friend functions
256// MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"()
257// GNU-DAG: define dllexport void @_Z7friend1v()
258// MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"()
259// GNU-DAG: define dllexport void @_Z7friend2v()
260struct FuncFriend {
261  friend __declspec(dllexport) void friend1();
262  friend __declspec(dllexport) void friend2();
263};
264__declspec(dllexport) void friend1() {}
265                      void friend2() {}
266
267// Implicit declarations can be redeclared with dllexport.
268// MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
269// GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}(
270void* alloc(__SIZE_TYPE__ n);
271__declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); }
272
273// MSC-DAG: define dllexport void @"\01?externalFunc@ns@@YAXXZ"()
274// GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv()
275namespace ns { __declspec(dllexport) void externalFunc() {} }
276
277
278
279//===----------------------------------------------------------------------===//
280// Function templates
281//===----------------------------------------------------------------------===//
282
283// Export function template definition.
284// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
285// GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv()
286template<typename T> __declspec(dllexport) void funcTmplDef() {}
287INST(funcTmplDef<ExplicitInst_Exported>)
288
289// Export inline function template.
290// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"()
291// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv()
292template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
293INST(inlineFuncTmpl1<ExplicitInst_Exported>)
294
295// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"()
296// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv()
297template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
298INST(inlineFuncTmpl2<ExplicitInst_Exported>)
299
300// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"()
301// GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv()
302template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
303template<typename T>                              void inlineFuncTmplDecl() {}
304INST(inlineFuncTmplDecl<ExplicitInst_Exported>)
305
306// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
307// GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv()
308template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
309template<typename T>                inline void inlineFuncTmplDef() {}
310INST(inlineFuncTmplDef<ExplicitInst_Exported>)
311
312
313// Redeclarations
314// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"()
315// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv()
316template<typename T> __declspec(dllexport) void funcTmplRedecl1();
317template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
318INST(funcTmplRedecl1<ExplicitInst_Exported>)
319
320// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"()
321// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv()
322template<typename T> __declspec(dllexport) void funcTmplRedecl2();
323template<typename T>                       void funcTmplRedecl2() {}
324INST(funcTmplRedecl2<ExplicitInst_Exported>)
325
326// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"()
327// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv()
328template<typename T> __declspec(dllexport) void funcTmplRedecl3();
329template<typename T>                       void funcTmplRedecl3() {}
330INST(funcTmplRedecl3<ExplicitInst_Exported>)
331
332
333// Function template friends
334// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"()
335// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv()
336// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"()
337// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv()
338struct FuncTmplFriend {
339  template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
340  template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
341};
342template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
343template<typename T>                       void funcTmplFriend2() {}
344INST(funcTmplFriend1<ExplicitInst_Exported>)
345INST(funcTmplFriend2<ExplicitInst_Exported>)
346
347// MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"()
348// GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv()
349namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} }
350INST(ns::externalFuncTmpl<ExplicitInst_Exported>)
351
352
353template<typename T> void funcTmpl() {}
354template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
355
356// Export implicit instantiation of an exported function template.
357// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"()
358// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv()
359USE(exportedFuncTmpl<ImplicitInst_Exported>)
360
361// Export explicit instantiation declaration of an exported function template.
362// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
363// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv()
364extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
365       template void exportedFuncTmpl<ExplicitDecl_Exported>();
366
367// Export explicit instantiation definition of an exported function template.
368// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"()
369// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv()
370template void exportedFuncTmpl<ExplicitInst_Exported>();
371
372// Export specialization of an exported function template.
373// MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
374// GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv()
375template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
376
377// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
378// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv()
379template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
380
381// Not exporting specialization of an exported function template without
382// explicit dllexport.
383// MSC-DAG: define void @"\01??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"()
384// GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv()
385template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
386
387
388// Export explicit instantiation declaration of a non-exported function template.
389// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
390// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv()
391extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
392       template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
393
394// Export explicit instantiation definition of a non-exported function template.
395// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"()
396// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv()
397template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
398
399// Export specialization of a non-exported function template.
400// MSC-DAG: define dllexport void @"\01??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
401// GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv()
402template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
403
404// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
405// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv()
406template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
407
408
409
410//===----------------------------------------------------------------------===//
411// Precedence
412//===----------------------------------------------------------------------===//
413
414// dllexport takes precedence over the dllimport if both are specified.
415// MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4
416// MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4
417// GNU-DAG: @PrecedenceGlobal1A            = dllexport global i32 0, align 4
418// GNU-DAG: @PrecedenceGlobal1B            = dllexport global i32 0, align 4
419__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // dllimport ignored
420__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored
421
422// MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4
423// MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4
424// GNU-DAG: @PrecedenceGlobal2A            = dllexport global i32 0, align 4
425// GNU-DAG: @PrecedenceGlobal2B            = dllexport global i32 0, align 4
426__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // dllimport ignored
427__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored
428
429// MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4
430// GNU-DAG: @PrecedenceGlobalRedecl1            = dllexport global i32 0, align 4
431__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
432__declspec(dllimport)        int PrecedenceGlobalRedecl1 = 0;
433
434// MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4
435// GNU-DAG: @PrecedenceGlobalRedecl2            = dllexport global i32 0, align 4
436__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
437__declspec(dllexport)        int PrecedenceGlobalRedecl2;
438
439// MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4
440// GNU-DAG: @PrecedenceGlobalMixed1            = dllexport global i32 0, align 4
441__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
442__declspec(dllimport)             int PrecedenceGlobalMixed1 = 0;
443
444// MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4
445// GNU-DAG: @PrecedenceGlobalMixed2            = dllexport global i32 0, align 4
446__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
447__declspec(dllexport)             int PrecedenceGlobalMixed2;
448
449// MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ"
450// MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ"
451// GNU-DAG: define dllexport void @_Z12precedence1Av()
452// GNU-DAG: define dllexport void @_Z12precedence1Bv()
453void __attribute__((dllimport, dllexport))       precedence1A() {}
454void __declspec(dllimport) __declspec(dllexport) precedence1B() {}
455
456// MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ"
457// MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ"
458// GNU-DAG: define dllexport void @_Z12precedence2Av()
459// GNU-DAG: define dllexport void @_Z12precedence2Bv()
460void __attribute__((dllexport, dllimport))       precedence2A() {}
461void __declspec(dllexport) __declspec(dllimport) precedence2B() {}
462
463// MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ"
464// GNU-DAG: define dllexport void @_Z17precedenceRedecl1v()
465void __declspec(dllimport) precedenceRedecl1();
466void __declspec(dllexport) precedenceRedecl1() {}
467
468// MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ"
469// GNU-DAG: define dllexport void @_Z17precedenceRedecl2v()
470void __declspec(dllexport) precedenceRedecl2();
471void __declspec(dllimport) precedenceRedecl2() {}
472
473
474
475//===----------------------------------------------------------------------===//
476// Classes
477//===----------------------------------------------------------------------===//
478
479struct S {
480  void __declspec(dllexport) a() {}
481  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ"
482
483  struct T {
484    void __declspec(dllexport) a() {}
485    // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ"
486  };
487};
488
489
490struct __declspec(dllexport) T {
491  // Copy assignment operator:
492  // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z"
493
494  // Explicitly defaulted copy constructur:
495  T(const T&) = default;
496  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
497
498  void a() {}
499  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
500
501  static int b;
502  // M32-DAG: @"\01?b@T@@2HA" = external dllexport global i32
503
504  static int c;
505  // M32-DAG: @"\01?c@T@@2HA" = dllexport global i32 0, align 4
506};
507
508USEVAR(T::b)
509int T::c;
510
511template <typename T> struct __declspec(dllexport) U { void foo() {} };
512// The U<int> specialization below must cause the following to be emitted:
513// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
514// M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
515struct __declspec(dllexport) V : public U<int> { };
516
517
518struct __declspec(dllexport) W { virtual void foo() {} };
519// Default ctor:
520// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ"
521// Copy ctor:
522// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z"
523// vftable:
524// 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@"
525// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[W_VTABLE]], i32 0, i32 1)
526// G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
527
528struct __declspec(dllexport) X : public virtual W {};
529// vbtable:
530// M32-DAG: @"\01??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4]
531
532struct __declspec(dllexport) Y {
533  // Move assignment operator:
534  // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
535
536  int x;
537};
538
539struct __declspec(dllexport) Z { virtual ~Z() {} };
540// The scalar deleting dtor does not get exported:
541// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_GZ@@UAEPAXI@Z"
542
543
544// The user-defined dtor does get exported:
545// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
546
547namespace DontUseDtorAlias {
548  struct __declspec(dllexport) A { ~A(); };
549  struct __declspec(dllexport) B : A { ~B(); };
550  A::~A() { }
551  B::~B() { }
552  // Emit a real definition of B's constructor; don't alias it to A's.
553  // M32-DAG: define dllexport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
554}
555
556struct __declspec(dllexport) DefaultedCtorsDtors {
557  DefaultedCtorsDtors() = default;
558  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
559  ~DefaultedCtorsDtors() = default;
560  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
561};
562
563namespace ReferencedInlineMethodInNestedClass {
564  struct __declspec(dllexport) S {
565    void foo() {
566      t->bar();
567    }
568    struct T {
569      void bar() {}
570    };
571    T *t;
572  };
573  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
574  // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
575}
576
577// MS ignores DLL attributes on partial specializations.
578template <typename T> struct PartiallySpecializedClassTemplate {};
579template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
580USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
581// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
582// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
583
584template <typename T> struct ExplicitlySpecializedClassTemplate {};
585template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
586USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
587// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
588// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
589
590//===----------------------------------------------------------------------===//
591// Classes with template base classes
592//===----------------------------------------------------------------------===//
593
594template <typename T> struct ClassTemplate { void func() {} };
595template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
596template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
597
598template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
599template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
600template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
601template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
602template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
603template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
604
605template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
606template struct ExplicitlyInstantiatedTemplate<int>;
607template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
608template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
609template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
610template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
611
612
613// MS: ClassTemplate<int> gets exported.
614struct __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
615USEMEMFUNC(ClassTemplate<int>, func)
616// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
617// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
618
619// ExportedTemplate is explicitly exported.
620struct __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
621// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
622// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
623
624// ImportedClassTemplate is explicitly imported.
625struct __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
626USEMEMFUNC(ImportedClassTemplate<int>, func)
627// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
628// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
629
630// Base class already instantiated without dll attribute.
631struct DerivedFromTemplateD : public ClassTemplate<double> {};
632struct __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
633USEMEMFUNC(ClassTemplate<double>, func)
634// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
635// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
636
637// MS: Base class already instantiated with different dll attribute.
638struct __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
639struct __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
640USEMEMFUNC(ClassTemplate<bool>, func)
641// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
642// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
643
644// Base class already specialized without dll attribute.
645struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
646USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
647// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
648// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
649
650// Base class alredy specialized with export attribute.
651struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
652USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
653// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
654// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
655
656// Base class already specialized with import attribute.
657struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
658USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
659// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
660// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
661
662// Base class already instantiated without dll attribute.
663struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
664USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
665// M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
666// G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
667
668// Base class already instantiated with export attribute.
669struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
670USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
671// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
672// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
673
674// Base class already instantiated with import attribute.
675struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
676USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
677// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
678// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
679
680// MS: A dll attribute propagates through multiple levels of instantiation.
681template <typename T> struct TopClass { void func() {} };
682template <typename T> struct MiddleClass : public TopClass<T> { };
683struct __declspec(dllexport) BottomClas : public MiddleClass<int> { };
684USEMEMFUNC(TopClass<int>, func)
685// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
686// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
687