1 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s
2 // RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s
3 // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s
4 // RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s
5 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 %s
6 // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s
7
8 // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
9 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s
10 // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s
11
12 // Helper structs to make templates more expressive.
13 struct ImplicitInst_Imported {};
14 struct ImplicitInst_NotImported {};
15 struct ExplicitDecl_Imported {};
16 struct ExplicitInst_Imported {};
17 struct ExplicitSpec_Imported {};
18 struct ExplicitSpec_Def_Imported {};
19 struct ExplicitSpec_InlineDef_Imported {};
20 struct ExplicitSpec_NotImported {};
21
22 #define JOIN2(x, y) x##y
23 #define JOIN(x, y) JOIN2(x, y)
24 #define UNIQ(name) JOIN(name, __LINE__)
25 #define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
26 #define USEVAR(var) USEVARTYPE(int, var)
27 #define USE(func) void UNIQ(use)() { func(); }
28 #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
29 #define USECLASS(class) void UNIQ(USE)() { class x; }
30 #define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
31 #define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
32
33 //===----------------------------------------------------------------------===//
34 // Globals
35 //===----------------------------------------------------------------------===//
36
37 // Import declaration.
38 // MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32
39 // GNU-DAG: @ExternGlobalDecl = external dllimport global i32
40 __declspec(dllimport) extern int ExternGlobalDecl;
41 USEVAR(ExternGlobalDecl)
42
43 // dllimport implies a declaration.
44 // MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32
45 // GNU-DAG: @GlobalDecl = external dllimport global i32
46 __declspec(dllimport) int GlobalDecl;
47 USEVAR(GlobalDecl)
48
49 // Redeclarations
50 // MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32
51 // GNU-DAG: @GlobalRedecl1 = external dllimport global i32
52 __declspec(dllimport) extern int GlobalRedecl1;
53 __declspec(dllimport) extern int GlobalRedecl1;
54 USEVAR(GlobalRedecl1)
55
56 // MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32
57 // GNU-DAG: @GlobalRedecl2a = external dllimport global i32
58 __declspec(dllimport) int GlobalRedecl2a;
59 __declspec(dllimport) int GlobalRedecl2a;
60 USEVAR(GlobalRedecl2a)
61
62 // M32-DAG: @"\01?GlobalRedecl2b@@3PAHA" = external dllimport global i32*
63 // M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
64 // GNU-DAG: @GlobalRedecl2b = external dllimport global i32*
65 int *__attribute__((dllimport)) GlobalRedecl2b;
66 int *__attribute__((dllimport)) GlobalRedecl2b;
67 USEVARTYPE(int*, GlobalRedecl2b)
68
69 // MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32
70 // GNU-DAG: @GlobalRedecl2c = external dllimport global i32
71 int GlobalRedecl2c __attribute__((dllimport));
72 int GlobalRedecl2c __attribute__((dllimport));
73 USEVAR(GlobalRedecl2c)
74
75 // NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
76 // and drop the dllimport with a warning.
77 // MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32
78 // GNU-DAG: @GlobalRedecl3 = external global i32
79 __declspec(dllimport) extern int GlobalRedecl3;
80 extern int GlobalRedecl3; // dllimport ignored
81 USEVAR(GlobalRedecl3)
82
83 // MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = external dllimport global i32
84 // GNU-DAG: @_ZN2ns14ExternalGlobalE = external dllimport global i32
85 namespace ns { __declspec(dllimport) int ExternalGlobal; }
86 USEVAR(ns::ExternalGlobal)
87
88 int f();
89 // MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0
90 // MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0
inlineStaticLocalsFunc()91 inline int __declspec(dllimport) inlineStaticLocalsFunc() {
92 static int x = f();
93 return x++;
94 };
95 USE(inlineStaticLocalsFunc);
96
97 // The address of a dllimport global cannot be used in constant initialization.
98 // M32-DAG: @"\01?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer
99 // GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
initializationFunc()100 int *initializationFunc() {
101 static int *const arr[] = {&ExternGlobalDecl};
102 return arr[0];
103 }
104 USE(initializationFunc);
105
106
107 //===----------------------------------------------------------------------===//
108 // Variable templates
109 //===----------------------------------------------------------------------===//
110
111 // Import declaration.
112 // MSC-DAG: @"\01??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
113 // GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32
114 template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
115 USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
116
117 // dllimport implies a declaration.
118 // MSC-DAG: @"\01??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
119 // GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32
120 template<typename T> __declspec(dllimport) int VarTmplDecl;
121 USEVAR(VarTmplDecl<ImplicitInst_Imported>)
122
123 // Redeclarations
124 // MSC-DAG: @"\01??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
125 // GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE = external dllimport global i32
126 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
127 template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
128 USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
129
130 // MSC-DAG: @"\01??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
131 // GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE = external dllimport global i32
132 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
133 template<typename T> __declspec(dllimport) int VarTmplRedecl2;
134 USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
135
136 // MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32
137 // GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32
138 template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
139 template<typename T> extern int VarTmplRedecl3; // dllimport ignored
140 USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
141
142
143 // MSC-DAG: @"\01??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
144 // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE = external dllimport global i32
145 namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
146 USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
147
148
149 template<typename T> int VarTmpl;
150 template<typename T> __declspec(dllimport) int ImportedVarTmpl;
151
152 // Import implicit instantiation of an imported variable template.
153 // MSC-DAG: @"\01??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
154 // GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE = external dllimport global i32
155 USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
156
157 // Import explicit instantiation declaration of an imported variable template.
158 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
159 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE = external dllimport global i32
160 extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
161 USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
162
163 // An explicit instantiation definition of an imported variable template cannot
164 // be imported because the template must be defined which is illegal.
165
166 // Import specialization of an imported variable template.
167 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
168 // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE = external dllimport global i32
169 template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
170 USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
171
172 // Not importing specialization of an imported variable template without
173 // explicit dllimport.
174 // MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4
175 // GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE = global i32 0, align 4
176 template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
177 USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
178
179 // Import explicit instantiation declaration of a non-imported variable template.
180 // MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
181 // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE = external dllimport global i32
182 extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
183 USEVAR(VarTmpl<ExplicitDecl_Imported>)
184
185 // Import explicit instantiation definition of a non-imported variable template.
186 // MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32
187 // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE = external dllimport global i32
188 template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
189 USEVAR(VarTmpl<ExplicitInst_Imported>)
190
191 // Import specialization of a non-imported variable template.
192 // MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
193 // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE = external dllimport global i32
194 template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
195 USEVAR(VarTmpl<ExplicitSpec_Imported>)
196
197
198
199 //===----------------------------------------------------------------------===//
200 // Functions
201 //===----------------------------------------------------------------------===//
202
203 // Import function declaration.
204 // MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"()
205 // GNU-DAG: declare dllimport void @_Z4declv()
206 __declspec(dllimport) void decl();
207 USE(decl)
208
209 // extern "C"
210 // MSC-DAG: declare dllimport void @externC()
211 // GNU-DAG: declare dllimport void @externC()
212 extern "C" __declspec(dllimport) void externC();
USE(externC)213 USE(externC)
214
215 // Import inline function.
216 // MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"()
217 // GNU-DAG: define linkonce_odr void @_Z10inlineFuncv()
218 // MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"()
219 // GO1-DAG: define linkonce_odr void @_Z10inlineFuncv()
220 __declspec(dllimport) inline void inlineFunc() {}
221 USE(inlineFunc)
222
223 // MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"()
224 // GNU-DAG: define linkonce_odr void @_Z10inlineDeclv()
225 // MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"()
226 // GO1-DAG: define linkonce_odr void @_Z10inlineDeclv()
227 __declspec(dllimport) inline void inlineDecl();
inlineDecl()228 void inlineDecl() {}
229 USE(inlineDecl)
230
231 // MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"()
232 // GNU-DAG: define linkonce_odr void @_Z9inlineDefv()
233 // MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"()
234 // GO1-DAG: define linkonce_odr void @_Z9inlineDefv()
235 __declspec(dllimport) void inlineDef();
inlineDef()236 inline void inlineDef() {}
USE(inlineDef)237 USE(inlineDef)
238
239 // inline attributes
240 // MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"()
241 // GNU-DAG: define linkonce_odr void @_Z8noinlinev()
242 __declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
USE(noinline)243 USE(noinline)
244
245 // MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
246 // GNU-DAG: define linkonce_odr void @_Z12alwaysInlinev() {{.*}} comdat {
247 __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
248 USE(alwaysInline)
249
250 // Redeclarations
251 // MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
252 // GNU-DAG: declare dllimport void @_Z7redecl1v()
253 __declspec(dllimport) void redecl1();
254 __declspec(dllimport) void redecl1();
255 USE(redecl1)
256
257 // NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
258 // and drop the dllimport with a warning.
259 // MSC-DAG: declare void @"\01?redecl2@@YAXXZ"()
260 // GNU-DAG: declare void @_Z7redecl2v()
261 __declspec(dllimport) void redecl2();
262 void redecl2();
263 USE(redecl2)
264
265 // MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
266 // GNU-DAG: define void @_Z7redecl3v()
267 __declspec(dllimport) void redecl3();
redecl3()268 void redecl3() {} // dllimport ignored
269 USE(redecl3)
270
271
272 // Friend functions
273 // MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"()
274 // GNU-DAG: declare dllimport void @_Z7friend1v()
275 // MSC-DAG: declare void @"\01?friend2@@YAXXZ"()
276 // GNU-DAG: declare void @_Z7friend2v()
277 // MSC-DAG: define void @"\01?friend3@@YAXXZ"()
278 // GNU-DAG: define void @_Z7friend3v()
279 // MSC-DAG: declare void @"\01?friend4@@YAXXZ"()
280 // GNU-DAG: declare void @_Z7friend4v()
281 // MSC-DAG: declare dllimport void @"\01?friend5@@YAXXZ"()
282 // GNU-DAG: declare dllimport void @_Z7friend5v()
283
284 struct FuncFriend {
285 friend __declspec(dllimport) void friend1();
286 friend __declspec(dllimport) void friend2();
287 friend __declspec(dllimport) void friend3();
288 };
289 __declspec(dllimport) void friend1();
290 void friend2(); // dllimport ignored
friend3()291 void friend3() {} // dllimport ignored
292
293 __declspec(dllimport) void friend4();
294 __declspec(dllimport) void friend5();
295 struct FuncFriendRedecl {
296 friend void friend4(); // dllimport ignored
297 friend void ::friend5();
298 };
299 USE(friend1)
300 USE(friend2)
301 USE(friend3)
302 USE(friend4)
303 USE(friend5)
304
305 // Implicit declarations can be redeclared with dllimport.
306 // MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
307 // GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
308 __declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
UNIQ(use)309 void UNIQ(use)() { ::operator new(42); }
310
311 // MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"()
312 // GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
313 namespace ns { __declspec(dllimport) void externalFunc(); }
314 USE(ns::externalFunc)
315
316
317
318 //===----------------------------------------------------------------------===//
319 // Function templates
320 //===----------------------------------------------------------------------===//
321
322 // Import function template declaration.
323 // MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
324 // GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
325 template<typename T> __declspec(dllimport) void funcTmplDecl();
USE(funcTmplDecl<ImplicitInst_Imported>)326 USE(funcTmplDecl<ImplicitInst_Imported>)
327
328 // Function template definitions cannot be imported.
329
330 // Import inline function template.
331 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
332 // GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
333 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
334 // GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
335 template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
USE(inlineFuncTmpl1<ImplicitInst_Imported>)336 USE(inlineFuncTmpl1<ImplicitInst_Imported>)
337
338 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
339 // GNU-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
340 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
341 // GO1-DAG: define linkonce_odr void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
342 template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
343 USE(inlineFuncTmpl2<ImplicitInst_Imported>)
344
345 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
346 // GNU-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
347 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
348 // GO1-DAG: define linkonce_odr void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
349 template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
inlineFuncTmplDecl()350 template<typename T> void inlineFuncTmplDecl() {}
351 USE(inlineFuncTmplDecl<ImplicitInst_Imported>)
352
353 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
354 // GNU-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
355 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
356 // GO1-DAG: define linkonce_odr void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
357 template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
inlineFuncTmplDef()358 template<typename T> inline void inlineFuncTmplDef() {}
359 USE(inlineFuncTmplDef<ImplicitInst_Imported>)
360
361
362 // Redeclarations
363 // MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
364 // GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
365 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
366 template<typename T> __declspec(dllimport) void funcTmplRedecl1();
367 USE(funcTmplRedecl1<ImplicitInst_Imported>)
368
369 // MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
370 // GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
371 template<typename T> __declspec(dllimport) void funcTmplRedecl2();
372 template<typename T> void funcTmplRedecl2(); // dllimport ignored
373 USE(funcTmplRedecl2<ImplicitInst_NotImported>)
374
375 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
376 // GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
377 template<typename T> __declspec(dllimport) void funcTmplRedecl3();
funcTmplRedecl3()378 template<typename T> void funcTmplRedecl3() {} // dllimport ignored
379 USE(funcTmplRedecl3<ImplicitInst_NotImported>)
380
381
382 // Function template friends
383 // MSC-DAG: declare dllimport void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
384 // GNU-DAG: declare dllimport void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
385 // MSC-DAG: declare void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
386 // GNU-DAG: declare void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv()
387 // MSC-DAG: define linkonce_odr void @"\01??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"()
388 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv()
389 // MSC-DAG: declare dllimport void @"\01??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"()
390 // GNU-DAG: define linkonce_odr void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
391 struct FuncTmplFriend {
392 template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
393 template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
394 template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
395 template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
396 };
397 template<typename T> __declspec(dllimport) void funcTmplFriend1();
398 template<typename T> void funcTmplFriend2(); // dllimport ignored
funcTmplFriend3()399 template<typename T> void funcTmplFriend3() {} // dllimport ignored
funcTmplFriend4()400 template<typename T> inline void funcTmplFriend4() {}
401 USE(funcTmplFriend1<ImplicitInst_Imported>)
402 USE(funcTmplFriend2<ImplicitInst_NotImported>)
403 USE(funcTmplFriend3<ImplicitInst_NotImported>)
404 USE(funcTmplFriend4<ImplicitInst_Imported>)
405
406 // MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
407 // GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
408 namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
USE(ns::externalFuncTmpl<ImplicitInst_Imported>)409 USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
410
411
412 template<typename T> void funcTmpl() {}
inlineFuncTmpl()413 template<typename T> inline void inlineFuncTmpl() {}
414 template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
importedFuncTmpl()415 template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
416
417 // Import implicit instantiation of an imported function template.
418 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
419 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
420 USE(importedFuncTmplDecl<ImplicitInst_Imported>)
421
422 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
423 // GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
424 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
425 // GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
426 USE(importedFuncTmpl<ImplicitInst_Imported>)
427
428 // Import explicit instantiation declaration of an imported function template.
429 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
430 // GNU-DAG: declare void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
431 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
432 // GO1-DAG: define available_externally void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
433 extern template void importedFuncTmpl<ExplicitDecl_Imported>();
434 USE(importedFuncTmpl<ExplicitDecl_Imported>)
435
436 // Import explicit instantiation definition of an imported function template.
437 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
438 // GNU-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
439 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
440 // GO1-DAG: define weak_odr void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
441 template void importedFuncTmpl<ExplicitInst_Imported>();
442 USE(importedFuncTmpl<ExplicitInst_Imported>)
443
444
445 // Import specialization of an imported function template.
446 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
447 // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
448 template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
USE(importedFuncTmplDecl<ExplicitSpec_Imported>)449 USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
450
451 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
452 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
453 #ifdef MSABI
454 //template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
455 //USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
456 #endif
457
458 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
459 // GNU-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
460 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
461 // GO1-DAG: define linkonce_odr void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
462 template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
463 USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
464
465
466 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
467 // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
468 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
USE(importedFuncTmpl<ExplicitSpec_Imported>)469 USE(importedFuncTmpl<ExplicitSpec_Imported>)
470
471 // MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
472 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
473 #ifdef MSABI
474 //template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
475 //USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
476 #endif
477
478 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
479 // GNU-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
480 // MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
481 // GO1-DAG: define linkonce_odr void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
482 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)483 USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
484
485
486 // Not importing specialization of an imported function template without
487 // explicit dllimport.
488 // MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
489 // GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
490 template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
491 USE(importedFuncTmpl<ExplicitSpec_NotImported>)
492
493
494 // Import explicit instantiation declaration of a non-imported function template.
495 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
496 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
497 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
498 // GNU-DAG: declare void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
499 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
500 // GO1-DAG: define available_externally void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
501 extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
502 extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
503 USE(funcTmpl<ExplicitDecl_Imported>)
504 USE(inlineFuncTmpl<ExplicitDecl_Imported>)
505
506
507 // Import explicit instantiation definition of a non-imported function template.
508 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
509 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
510 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
511 // GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
512 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
513 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
514 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
515 // GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
516 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
517 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
518 USE(funcTmpl<ExplicitInst_Imported>)
519 USE(inlineFuncTmpl<ExplicitInst_Imported>)
520
521
522 // Import specialization of a non-imported function template.
523 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
524 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
525 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
USE(funcTmpl<ExplicitSpec_Imported>)526 USE(funcTmpl<ExplicitSpec_Imported>)
527
528 // MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
529 // MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
530 #ifdef MSABI
531 //template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
532 //USE(funcTmpl<ExplicitSpec_Def_Imported>)
533 #endif
534
535 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
536 // GNU-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
537 // MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
538 // GO1-DAG: define linkonce_odr void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
539 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
540 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
541
542
543
544 //===----------------------------------------------------------------------===//
545 // Classes
546 //===----------------------------------------------------------------------===//
547
548 struct __declspec(dllimport) T {
aT549 void a() {}
550 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
551
552 static int b;
553 // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
554
555 T& operator=(T&) = default;
556 // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
557
558 T& operator=(T&&) = default;
559 // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
560 // MO1-DAG: define linkonce_odr x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
561 };
562 USEMEMFUNC(T, a)
563 USEVAR(T::b)
564 USECOPYASSIGN(T)
565 USEMOVEASSIGN(T)
566
fooU567 template <typename T> struct __declspec(dllimport) U { void foo() {} };
568 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
569 struct __declspec(dllimport) V : public U<int> { };
570 USEMEMFUNC(V, foo)
571
fooW572 struct __declspec(dllimport) W { virtual void foo() {} };
573 USECLASS(W)
574 // vftable:
575 // MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
576 // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
577
578 struct __declspec(dllimport) KeyFuncClass {
KeyFuncClassKeyFuncClass579 constexpr KeyFuncClass() {}
580 virtual void foo();
581 };
582 constexpr KeyFuncClass keyFuncClassVar;
583 // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
584
585 struct __declspec(dllimport) X : public virtual W {};
586 USECLASS(X)
587 // vbtable:
588 // MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
589
590 struct __declspec(dllimport) Y {
591 int x;
592 };
593
~ZZ594 struct __declspec(dllimport) Z { virtual ~Z() {} };
595 USECLASS(Z)
596 // User-defined dtor:
597 // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
598
599 namespace DontUseDtorAlias {
600 struct __declspec(dllimport) A { ~A(); };
601 struct __declspec(dllimport) B : A { ~B(); };
~A()602 inline A::~A() { }
~B()603 inline B::~B() { }
604 // Emit a real definition of B's constructor; don't alias it to A's.
605 // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
606 USECLASS(B)
607 }
608
609 namespace Vtordisp {
610 // Don't dllimport the vtordisp.
611 // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
612
613 class Base {
f()614 virtual void f() {}
615 };
616 template <typename T>
617 class __declspec(dllimport) C : virtual public Base {
618 public:
C()619 C() {}
f()620 virtual void f() {}
621 };
622 template class C<char>;
623 }
624
625 namespace ClassTemplateStaticDef {
626 // Regular template static field:
627 template <typename T> struct __declspec(dllimport) S {
628 static int x;
629 };
630 template <typename T> int S<T>::x;
631 // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
f()632 int f() { return S<int>::x; }
633
634 // Partial class template specialization static field:
635 template <typename A> struct T;
636 template <typename A> struct __declspec(dllimport) T<A*> {
637 static int x;
638 };
639 template <typename A> int T<A*>::x;
640 // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
g()641 int g() { return T<void*>::x; }
642 }
643
644 namespace PR19933 {
645 // Don't dynamically initialize dllimport vars.
646 // MSC2-NOT: @llvm.global_ctors
647 // GNU2-NOT: @llvm.global_ctors
648
649 struct NonPOD { NonPOD(); };
650 template <typename T> struct A { static NonPOD x; };
651 template <typename T> NonPOD A<T>::x;
652 template struct __declspec(dllimport) A<int>;
653 // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
654
655 int f();
656 template <typename T> struct B { static int x; };
657 template <typename T> int B<T>::x = f();
658 template struct __declspec(dllimport) B<int>;
659 // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
660
g()661 constexpr int g() { return 42; }
662 template <typename T> struct C { static int x; };
663 template <typename T> int C<T>::x = g();
664 template struct __declspec(dllimport) C<int>;
665 // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
666
667 template <int I> struct D { static int x, y; };
668 template <int I> int D<I>::x = I + 1;
669 template <int I> int D<I>::y = I + f();
670 template struct __declspec(dllimport) D<42>;
671 // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
672 // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
673 }
674
675 namespace PR21355 {
676 struct __declspec(dllimport) S {
677 virtual ~S();
678 };
~S()679 S::~S() {}
680
681 // S::~S is a key function, so we would ordinarily emit a strong definition for
682 // the vtable. However, S is imported, so the vtable should be too.
683
684 // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant [4 x i8*]
685 }
686
687 namespace PR21366 {
688 struct __declspec(dllimport) S {
689 void outOfLineMethod();
inlineMethodPR21366::S690 void inlineMethod() {}
691 inline void anotherInlineMethod();
692 void outOfClassInlineMethod();
693 };
anotherInlineMethod()694 void S::anotherInlineMethod() {}
outOfClassInlineMethod()695 inline void S::outOfClassInlineMethod() {}
696 }
697
698 // MS ignores DLL attributes on partial specializations.
699 template <typename T> struct PartiallySpecializedClassTemplate {};
700 template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); };
701 USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
702 // M32-DAG: declare x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
703 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
704
705 // Attributes on explicit specializations are honored.
706 template <typename T> struct ExplicitlySpecializedClassTemplate {};
707 template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); };
708 USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
709 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
710 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
711
712 // MS inherits DLL attributes to partial specializations.
713 template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {};
fPartiallySpecializedImportedClassTemplate714 template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} };
715 USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f);
716 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ"
717 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv
718
719 // Attributes on the instantiation take precedence over attributes on the template.
fExplicitlyInstantiatedWithDifferentAttr720 template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} };
721 template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>;
722 USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f);
723 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ"
724
725
726 //===----------------------------------------------------------------------===//
727 // Classes with template base classes
728 //===----------------------------------------------------------------------===//
729
funcClassTemplate730 template <typename T> struct ClassTemplate { void func() {} };
731 template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); };
func()732 template <typename T> void ExportedClassTemplate<T>::func() {}
733 template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); };
734
funcExplicitlySpecializedTemplate735 template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
funcExplicitlySpecializedTemplate736 template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
funcExplicitlyExportSpecializedTemplate737 template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
738 template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); };
func()739 void ExplicitlyExportSpecializedTemplate<int>::func() {}
funcExplicitlyImportSpecializedTemplate740 template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
741 template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); };
742
funcExplicitlyInstantiatedTemplate743 template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
744 template struct ExplicitlyInstantiatedTemplate<int>;
745 template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); };
func()746 template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {}
747 template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
748 template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); };
749 template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
750
751
752 // MS: ClassTemplate<int> gets imported.
753 struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
754 USEMEMFUNC(ClassTemplate<int>, func)
755 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
756 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
757
758 // ImportedTemplate is explicitly imported.
759 struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
760 USEMEMFUNC(ImportedClassTemplate<int>, func)
761 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
762 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
763
764 // ExportedTemplate is explicitly exported.
765 struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
766 USEMEMFUNC(ExportedClassTemplate<int>, func)
767 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
768 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
769
770 // Base class already instantiated without attribute.
771 struct DerivedFromTemplateD : public ClassTemplate<double> {};
772 struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
773 USEMEMFUNC(ClassTemplate<double>, func)
774 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
775 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
776
777 // MS: Base class already instantiated with dfferent attribute.
778 struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
779 struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
780 USEMEMFUNC(ClassTemplate<bool>, func)
781 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
782 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
783
784 // Base class already specialized without dll attribute.
785 struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
786 USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
787 // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
788 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
789
790 // Base class alredy specialized with export attribute.
791 struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
792 USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
793 // M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
794 // G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
795
796 // Base class already specialized with import attribute.
797 struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
798 USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
799 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
800 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
801
802 // Base class already instantiated without dll attribute.
803 struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
804 USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
805 // M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
806 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
807
808 // Base class already instantiated with export attribute.
809 struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
810 USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
811 // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
812 // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
813
814 // Base class already instantiated with import attribute.
815 struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
816 USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
817 // M32-DAG: declare dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
818 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
819
820 // MS: A dll attribute propagates through multiple levels of instantiation.
funcTopClass821 template <typename T> struct TopClass { void func() {} };
822 template <typename T> struct MiddleClass : public TopClass<T> { };
823 struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
824 USEMEMFUNC(TopClass<int>, func)
825 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
826 // G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
827