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.
9 struct ImplicitInst_Exported {};
10 struct ExplicitDecl_Exported {};
11 struct ExplicitInst_Exported {};
12 struct ExplicitSpec_Exported {};
13 struct ExplicitSpec_Def_Exported {};
14 struct ExplicitSpec_InlineDef_Exported {};
15 struct ExplicitSpec_NotExported {};
16 struct 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 INSTVAR(var) template int var;
24 #define INST(func) template void func();
25 
26 
27 //===----------------------------------------------------------------------===//
28 // Globals
29 //===----------------------------------------------------------------------===//
30 
31 // Declarations are not exported.
32 // MSC-NOT: @"\01?ExternGlobalDecl@@3HA"
33 // GNU-NOT: @ExternGlobalDecl
34 __declspec(dllexport) extern int ExternGlobalDecl;
35 
36 // dllexport implies a definition.
37 // MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4
38 // GNU-DAG: @GlobalDef            = dllexport global i32 0, align 4
39 __declspec(dllexport) int GlobalDef;
40 
41 // Export definition.
42 // MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4
43 // GNU-DAG: @GlobalInit1            = dllexport global i32 1, align 4
44 __declspec(dllexport) int GlobalInit1 = 1;
45 
46 // MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4
47 // GNU-DAG: @GlobalInit2            = dllexport global i32 1, align 4
48 int __declspec(dllexport) GlobalInit2 = 1;
49 
50 // Declare, then export definition.
51 // MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4
52 // GNU-DAG: @GlobalDeclInit            = dllexport global i32 1, align 4
53 __declspec(dllexport) extern int GlobalDeclInit;
54 int GlobalDeclInit = 1;
55 
56 // Redeclarations
57 // MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4
58 // GNU-DAG: @GlobalRedecl1            = dllexport global i32 0, align 4
59 __declspec(dllexport) extern int GlobalRedecl1;
60 __declspec(dllexport)        int GlobalRedecl1;
61 
62 // MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4
63 // GNU-DAG: @GlobalRedecl2            = dllexport global i32 0, align 4
64 __declspec(dllexport) extern int GlobalRedecl2;
65                              int GlobalRedecl2;
66 
67 // MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = dllexport global i32 0, align 4
68 // GNU-DAG: @_ZN2ns14ExternalGlobalE      = dllexport global i32 0, align 4
69 namespace ns { __declspec(dllexport) int ExternalGlobal; }
70 
71 // MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4
72 // GNU-DAG: @ExternalAutoTypeGlobal                      = dllexport global %struct.External zeroinitializer, align 4
73 __declspec(dllexport) auto ExternalAutoTypeGlobal = External();
74 
75 int f();
76 // MSC-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0
77 // MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0
78 int __declspec(dllexport) nonInlineStaticLocalsFunc() {
79   static int x = f();
80   return x++;
81 };
82 
83 // MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0
84 // MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0
85 // Note: MinGW doesn't seem to export the static local here.
86 inline int __declspec(dllexport) inlineStaticLocalsFunc() {
87   static int x = f();
88   return x++;
89 }
90 
91 
92 
93 //===----------------------------------------------------------------------===//
94 // Variable templates
95 //===----------------------------------------------------------------------===//
96 
97 // Declarations are not exported.
98 
99 // dllexport implies a definition.
100 // MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA"
101 // GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
102 template<typename T> __declspec(dllexport) int VarTmplDef;
103 INSTVAR(VarTmplDef<ExplicitInst_Exported>)
104 
105 // MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global
106 // GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE          = external dllexport global
107 template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
108 USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
109 
110 // Export definition.
111 // MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
112 // GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
113 template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
114 INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
115 
116 // MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
117 // GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
118 template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
119 INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
120 
121 // Declare, then export definition.
122 // MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
123 // GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
124 template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
125 template<typename T>                              int VarTmplDeclInit = 1;
126 INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
127 
128 // Redeclarations
129 // MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
130 // GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
131 template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
132 template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
133 INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
134 
135 // MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
136 // GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
137 template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
138 template<typename T>                              int VarTmplRedecl2 = 1;
139 INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
140 
141 // MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4
142 // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE        = weak_odr dllexport global i32 1, align 4
143 namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
144 INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
145 
146 // MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4
147 // GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE                    = weak_odr dllexport global %struct.External zeroinitializer, align 4
148 template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
149 template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
150 
151 
152 template<typename T> int VarTmpl = 1;
153 template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
154 
155 // Export implicit instantiation of an exported variable template.
156 // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
157 // GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
158 USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
159 
160 // Export explicit instantiation declaration of an exported variable template.
161 // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
162 // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE          = weak_odr dllexport global i32 1, align 4
163 extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
164        template int ExportedVarTmpl<ExplicitDecl_Exported>;
165 
166 // Export explicit instantiation definition of an exported variable template.
167 // MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
168 // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
169 template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
170 
171 // Export specialization of an exported variable template.
172 // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
173 // GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE          = dllexport global i32 0, align 4
174 template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
175 
176 // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
177 // GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE          = dllexport global i32 1, align 4
178 template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
179 
180 // Not exporting specialization of an exported variable template without
181 // explicit dllexport.
182 // MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4
183 // GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE          = global i32 0, align 4
184 template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
185 
186 
187 // Export explicit instantiation declaration of a non-exported variable template.
188 // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
189 // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE           = weak_odr dllexport global i32 1, align 4
190 extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
191        template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
192 
193 // Export explicit instantiation definition of a non-exported variable template.
194 // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
195 // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE           = weak_odr dllexport global i32 1, align 4
196 template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
197 
198 // Export specialization of a non-exported variable template.
199 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
200 // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE           = dllexport global i32 0, align 4
201 template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
202 
203 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
204 // GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE           = dllexport global i32 1, align 4
205 template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
206 
207 
208 
209 //===----------------------------------------------------------------------===//
210 // Functions
211 //===----------------------------------------------------------------------===//
212 
213 // Declarations are not exported.
214 
215 // Export function definition.
216 // MSC-DAG: define dllexport void @"\01?def@@YAXXZ"()
217 // GNU-DAG: define dllexport void @_Z3defv()
218 __declspec(dllexport) void def() {}
219 
220 // extern "C"
221 // MSC-DAG: define dllexport void @externC()
222 // GNU-DAG: define dllexport void @externC()
223 extern "C" __declspec(dllexport) void externC() {}
224 
225 // Export inline function.
226 // MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"()
227 // GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv()
228 __declspec(dllexport) inline void inlineFunc() {}
229 
230 // MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"()
231 // GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv()
232 __declspec(dllexport) inline void inlineDecl();
233                              void inlineDecl() {}
234 
235 // MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"()
236 // GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv()
237 __declspec(dllexport) void inlineDef();
238                inline void inlineDef() {}
239 
240 // Redeclarations
241 // MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"()
242 // GNU-DAG: define dllexport void @_Z7redecl1v()
243 __declspec(dllexport) void redecl1();
244 __declspec(dllexport) void redecl1() {}
245 
246 // MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"()
247 // GNU-DAG: define dllexport void @_Z7redecl2v()
248 __declspec(dllexport) void redecl2();
249                       void redecl2() {}
250 
251 // Friend functions
252 // MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"()
253 // GNU-DAG: define dllexport void @_Z7friend1v()
254 // MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"()
255 // GNU-DAG: define dllexport void @_Z7friend2v()
256 struct FuncFriend {
257   friend __declspec(dllexport) void friend1();
258   friend __declspec(dllexport) void friend2();
259 };
260 __declspec(dllexport) void friend1() {}
261                       void friend2() {}
262 
263 // Implicit declarations can be redeclared with dllexport.
264 // MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
265 // GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}(
266 void* alloc(__SIZE_TYPE__ n);
267 __declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); }
268 
269 // MSC-DAG: define dllexport void @"\01?externalFunc@ns@@YAXXZ"()
270 // GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv()
271 namespace ns { __declspec(dllexport) void externalFunc() {} }
272 
273 
274 
275 //===----------------------------------------------------------------------===//
276 // Function templates
277 //===----------------------------------------------------------------------===//
278 
279 // Export function template definition.
280 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
281 // GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv()
282 template<typename T> __declspec(dllexport) void funcTmplDef() {}
283 INST(funcTmplDef<ExplicitInst_Exported>)
284 
285 // Export inline function template.
286 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"()
287 // GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv()
288 template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
289 INST(inlineFuncTmpl1<ExplicitInst_Exported>)
290 
291 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"()
292 // GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv()
293 template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
294 INST(inlineFuncTmpl2<ExplicitInst_Exported>)
295 
296 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"()
297 // GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv()
298 template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
299 template<typename T>                              void inlineFuncTmplDecl() {}
300 INST(inlineFuncTmplDecl<ExplicitInst_Exported>)
301 
302 // MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
303 // GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv()
304 template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
305 template<typename T>                inline void inlineFuncTmplDef() {}
306 INST(inlineFuncTmplDef<ExplicitInst_Exported>)
307 
308 
309 // Redeclarations
310 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"()
311 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv()
312 template<typename T> __declspec(dllexport) void funcTmplRedecl1();
313 template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
314 INST(funcTmplRedecl1<ExplicitInst_Exported>)
315 
316 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"()
317 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv()
318 template<typename T> __declspec(dllexport) void funcTmplRedecl2();
319 template<typename T>                       void funcTmplRedecl2() {}
320 INST(funcTmplRedecl2<ExplicitInst_Exported>)
321 
322 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"()
323 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv()
324 template<typename T> __declspec(dllexport) void funcTmplRedecl3();
325 template<typename T>                       void funcTmplRedecl3() {}
326 INST(funcTmplRedecl3<ExplicitInst_Exported>)
327 
328 
329 // Function template friends
330 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"()
331 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv()
332 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"()
333 // GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv()
334 struct FuncTmplFriend {
335   template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
336   template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
337 };
338 template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
339 template<typename T>                       void funcTmplFriend2() {}
340 INST(funcTmplFriend1<ExplicitInst_Exported>)
341 INST(funcTmplFriend2<ExplicitInst_Exported>)
342 
343 // MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"()
344 // GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv()
345 namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} }
346 INST(ns::externalFuncTmpl<ExplicitInst_Exported>)
347 
348 
349 template<typename T> void funcTmpl() {}
350 template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
351 
352 // Export implicit instantiation of an exported function template.
353 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"()
354 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv()
355 USE(exportedFuncTmpl<ImplicitInst_Exported>)
356 
357 // Export explicit instantiation declaration of an exported function template.
358 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
359 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv()
360 extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
361        template void exportedFuncTmpl<ExplicitDecl_Exported>();
362 
363 // Export explicit instantiation definition of an exported function template.
364 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"()
365 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv()
366 template void exportedFuncTmpl<ExplicitInst_Exported>();
367 
368 // Export specialization of an exported function template.
369 // MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
370 // GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv()
371 template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
372 
373 // MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
374 // GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv()
375 template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
376 
377 // Not exporting specialization of an exported function template without
378 // explicit dllexport.
379 // MSC-DAG: define void @"\01??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"()
380 // GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv()
381 template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
382 
383 
384 // Export explicit instantiation declaration of a non-exported function template.
385 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
386 // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv()
387 extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
388        template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
389 
390 // Export explicit instantiation definition of a non-exported function template.
391 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"()
392 // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv()
393 template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
394 
395 // Export specialization of a non-exported function template.
396 // MSC-DAG: define dllexport void @"\01??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
397 // GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv()
398 template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
399 
400 // MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
401 // GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv()
402 template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
403 
404 
405 
406 //===----------------------------------------------------------------------===//
407 // Precedence
408 //===----------------------------------------------------------------------===//
409 
410 // dllexport takes precedence over the dllimport if both are specified.
411 // MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4
412 // MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4
413 // GNU-DAG: @PrecedenceGlobal1A            = dllexport global i32 0, align 4
414 // GNU-DAG: @PrecedenceGlobal1B            = dllexport global i32 0, align 4
415 __attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // dllimport ignored
416 __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored
417 
418 // MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4
419 // MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4
420 // GNU-DAG: @PrecedenceGlobal2A            = dllexport global i32 0, align 4
421 // GNU-DAG: @PrecedenceGlobal2B            = dllexport global i32 0, align 4
422 __attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // dllimport ignored
423 __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored
424 
425 // MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4
426 // GNU-DAG: @PrecedenceGlobalRedecl1            = dllexport global i32 0, align 4
427 __declspec(dllexport) extern int PrecedenceGlobalRedecl1;
428 __declspec(dllimport)        int PrecedenceGlobalRedecl1 = 0;
429 
430 // MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4
431 // GNU-DAG: @PrecedenceGlobalRedecl2            = dllexport global i32 0, align 4
432 __declspec(dllimport) extern int PrecedenceGlobalRedecl2;
433 __declspec(dllexport)        int PrecedenceGlobalRedecl2;
434 
435 // MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4
436 // GNU-DAG: @PrecedenceGlobalMixed1            = dllexport global i32 0, align 4
437 __attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
438 __declspec(dllimport)             int PrecedenceGlobalMixed1 = 0;
439 
440 // MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4
441 // GNU-DAG: @PrecedenceGlobalMixed2            = dllexport global i32 0, align 4
442 __attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
443 __declspec(dllexport)             int PrecedenceGlobalMixed2;
444 
445 // MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ"
446 // MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ"
447 // GNU-DAG: define dllexport void @_Z12precedence1Av()
448 // GNU-DAG: define dllexport void @_Z12precedence1Bv()
449 void __attribute__((dllimport, dllexport))       precedence1A() {}
450 void __declspec(dllimport) __declspec(dllexport) precedence1B() {}
451 
452 // MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ"
453 // MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ"
454 // GNU-DAG: define dllexport void @_Z12precedence2Av()
455 // GNU-DAG: define dllexport void @_Z12precedence2Bv()
456 void __attribute__((dllexport, dllimport))       precedence2A() {}
457 void __declspec(dllexport) __declspec(dllimport) precedence2B() {}
458 
459 // MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ"
460 // GNU-DAG: define dllexport void @_Z17precedenceRedecl1v()
461 void __declspec(dllimport) precedenceRedecl1();
462 void __declspec(dllexport) precedenceRedecl1() {}
463 
464 // MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ"
465 // GNU-DAG: define dllexport void @_Z17precedenceRedecl2v()
466 void __declspec(dllexport) precedenceRedecl2();
467 void __declspec(dllimport) precedenceRedecl2() {}
468 
469 
470 
471 //===----------------------------------------------------------------------===//
472 // Classes
473 //===----------------------------------------------------------------------===//
474 
475 struct S {
476   void __declspec(dllexport) a() {}
477   // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ"
478 
479   struct T {
480     void __declspec(dllexport) a() {}
481     // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ"
482   };
483 };
484 
485 
486 struct __declspec(dllexport) T {
487   // Copy assignment operator:
488   // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z"
489 
490   // Explicitly defaulted copy constructur:
491   T(const T&) = default;
492   // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
493 
494   void a() {}
495   // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
496 
497   static int b;
498   // M32-DAG: @"\01?b@T@@2HA" = external dllexport global i32
499 
500   static int c;
501   // M32-DAG: @"\01?c@T@@2HA" = dllexport global i32 0, align 4
502 };
503 
504 USEVAR(T::b)
505 int T::c;
506 
507 template <typename T> struct __declspec(dllexport) U { void foo() {} };
508 // The U<int> specialization below must cause the following to be emitted:
509 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
510 // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
511 struct __declspec(dllexport) V : public U<int> { };
512 
513 
514 struct __declspec(dllexport) W { virtual void foo() {} };
515 // Default ctor:
516 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ"
517 // Copy ctor:
518 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z"
519 // vftable:
520 // M32-DAG: @"\01??_7W@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
521 // 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*)]
522 
523 struct __declspec(dllexport) X : public virtual W {};
524 // vbtable:
525 // M32-DAG: @"\01??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4]
526 
527 struct __declspec(dllexport) Y {
528   // Move assignment operator:
529   // M32-DAG: define weak_odr dllexport x86_thiscallcc nonnull %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
530 
531   int x;
532 };
533 
534 struct __declspec(dllexport) Z { virtual ~Z() {} };
535 // The scalar deleting dtor does not get exported:
536 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_GZ@@UAEPAXI@Z"
537 
538 
539 // The user-defined dtor does get exported:
540 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
541 
542 namespace DontUseDtorAlias {
543   struct __declspec(dllexport) A { ~A(); };
544   struct __declspec(dllexport) B : A { ~B(); };
545   A::~A() { }
546   B::~B() { }
547   // Emit a real definition of B's constructor; don't alias it to A's.
548   // M32-DAG: define dllexport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
549 }
550 
551 struct __declspec(dllexport) DefaultedCtorsDtors {
552   DefaultedCtorsDtors() = default;
553   // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
554   ~DefaultedCtorsDtors() = default;
555   // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
556 };
557 
558 namespace ReferencedInlineMethodInNestedClass {
559   struct __declspec(dllexport) S {
560     void foo() {
561       t->bar();
562     }
563     struct T {
564       void bar() {}
565     };
566     T *t;
567   };
568   // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
569   // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
570 }
571