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