1 | // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -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 -fno-threadsafe-statics -fms-extensions -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 -fno-threadsafe-statics -fms-extensions -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 -fno-threadsafe-statics -fms-extensions -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 -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s |
6 | // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -disable-llvm-passes -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s |
7 | // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s |
8 | |
9 | // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines. |
10 | // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s |
11 | // RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s |
12 | |
13 | // Helper structs to make templates more expressive. |
14 | struct ImplicitInst_Imported {}; |
15 | struct ImplicitInst_NotImported {}; |
16 | struct ExplicitDecl_Imported {}; |
17 | struct ExplicitInst_Imported {}; |
18 | struct ExplicitSpec_Imported {}; |
19 | struct ExplicitSpec_Def_Imported {}; |
20 | struct ExplicitSpec_InlineDef_Imported {}; |
21 | struct ExplicitSpec_NotImported {}; |
22 | |
23 | #define JOIN2(x, y) x##y |
24 | #define JOIN(x, y) JOIN2(x, y) |
25 | #define UNIQ(name) JOIN(name, __LINE__) |
26 | #define USEVARTYPE(type, var) type UNIQ(use)() { return var; } |
27 | #define USEVAR(var) USEVARTYPE(int, var) |
28 | #define USE(func) void UNIQ(use)() { func(); } |
29 | #define USE1(func) void UNIQ(use)() { func(nullptr); } |
30 | #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; } |
31 | #define USESTATICMEMFUNC(class, func) void (*UNIQ(use)())() { return &class::func; } |
32 | #define USECLASS(class) void UNIQ(USE)() { class x; } |
33 | #define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; } |
34 | #define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; } |
35 | |
36 | //===----------------------------------------------------------------------===// |
37 | // Globals |
38 | //===----------------------------------------------------------------------===// |
39 | |
40 | // Import declaration. |
41 | // MSC-DAG: @"?ExternGlobalDecl@@3HA" = external dllimport global i32 |
42 | // GNU-DAG: @ExternGlobalDecl = external dllimport global i32 |
43 | __declspec(dllimport) extern int ExternGlobalDecl; |
44 | USEVAR(ExternGlobalDecl) |
45 | |
46 | // dllimport implies a declaration. |
47 | // MSC-DAG: @"?GlobalDecl@@3HA" = external dllimport global i32 |
48 | // GNU-DAG: @GlobalDecl = external dllimport global i32 |
49 | __declspec(dllimport) int GlobalDecl; |
50 | USEVAR(GlobalDecl) |
51 | |
52 | // Redeclarations |
53 | // MSC-DAG: @"?GlobalRedecl1@@3HA" = external dllimport global i32 |
54 | // GNU-DAG: @GlobalRedecl1 = external dllimport global i32 |
55 | __declspec(dllimport) extern int GlobalRedecl1; |
56 | __declspec(dllimport) extern int GlobalRedecl1; |
57 | USEVAR(GlobalRedecl1) |
58 | |
59 | // MSC-DAG: @"?GlobalRedecl2a@@3HA" = external dllimport global i32 |
60 | // GNU-DAG: @GlobalRedecl2a = external dllimport global i32 |
61 | __declspec(dllimport) int GlobalRedecl2a; |
62 | __declspec(dllimport) int GlobalRedecl2a; |
63 | USEVAR(GlobalRedecl2a) |
64 | |
65 | // M32-DAG: @"?GlobalRedecl2b@@3PAHA" = external dllimport global i32* |
66 | // M64-DAG: @"?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32* |
67 | // GNU-DAG: @GlobalRedecl2b = external dllimport global i32* |
68 | int *__attribute__((dllimport)) GlobalRedecl2b; |
69 | int *__attribute__((dllimport)) GlobalRedecl2b; |
70 | USEVARTYPE(int*, GlobalRedecl2b) |
71 | |
72 | // MSC-DAG: @"?GlobalRedecl2c@@3HA" = external dllimport global i32 |
73 | // GNU-DAG: @GlobalRedecl2c = external dllimport global i32 |
74 | int GlobalRedecl2c __attribute__((dllimport)); |
75 | int GlobalRedecl2c __attribute__((dllimport)); |
76 | USEVAR(GlobalRedecl2c) |
77 | |
78 | // NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC |
79 | // and drop the dllimport with a warning. |
80 | // MSC-DAG: @"?GlobalRedecl3@@3HA" = external dso_local global i32 |
81 | // GNU-DAG: @GlobalRedecl3 = external global i32 |
82 | __declspec(dllimport) extern int GlobalRedecl3; |
83 | extern int GlobalRedecl3; // dllimport ignored |
84 | USEVAR(GlobalRedecl3) |
85 | |
86 | // MSC-DAG: @"?ExternalGlobal@ns@@3HA" = external dllimport global i32 |
87 | // GNU-DAG: @_ZN2ns14ExternalGlobalE = external dllimport global i32 |
88 | namespace ns { __declspec(dllimport) int ExternalGlobal; } |
89 | USEVAR(ns::ExternalGlobal) |
90 | |
91 | int __declspec(dllimport) f(); |
92 | // MO1-DAG: @"?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0 |
93 | // MO1-DAG: @"??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0 |
94 | inline int __declspec(dllimport) inlineStaticLocalsFunc() { |
95 | static int x = f(); |
96 | return x++; |
97 | }; |
98 | USE(inlineStaticLocalsFunc); |
99 | |
100 | // The address of a dllimport global cannot be used in constant initialization. |
101 | // M32-DAG: @"?arr@?1??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer |
102 | // GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer |
103 | int *initializationFunc() { |
104 | static int *const arr[] = {&ExternGlobalDecl}; |
105 | return arr[0]; |
106 | } |
107 | USE(initializationFunc); |
108 | |
109 | |
110 | //===----------------------------------------------------------------------===// |
111 | // Variable templates |
112 | //===----------------------------------------------------------------------===// |
113 | |
114 | // Import declaration. |
115 | // MSC-DAG: @"??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 |
116 | // GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32 |
117 | template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl; |
118 | USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>) |
119 | |
120 | // dllimport implies a declaration. |
121 | // MSC-DAG: @"??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 |
122 | // GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE = external dllimport global i32 |
123 | template<typename T> __declspec(dllimport) int VarTmplDecl; |
124 | USEVAR(VarTmplDecl<ImplicitInst_Imported>) |
125 | |
126 | // Redeclarations |
127 | // MSC-DAG: @"??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 |
128 | // GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE = external dllimport global i32 |
129 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; |
130 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; |
131 | USEVAR(VarTmplRedecl1<ImplicitInst_Imported>) |
132 | |
133 | // MSC-DAG: @"??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 |
134 | // GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE = external dllimport global i32 |
135 | template<typename T> __declspec(dllimport) int VarTmplRedecl2; |
136 | template<typename T> __declspec(dllimport) int VarTmplRedecl2; |
137 | USEVAR(VarTmplRedecl2<ImplicitInst_Imported>) |
138 | |
139 | // MSC-DAG: @"??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external dso_local global i32 |
140 | // GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE = external global i32 |
141 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; |
142 | template<typename T> extern int VarTmplRedecl3; // dllimport ignored |
143 | USEVAR(VarTmplRedecl3<ImplicitInst_Imported>) |
144 | |
145 | |
146 | // MSC-DAG: @"??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32 |
147 | // GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE = external dllimport global i32 |
148 | namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; } |
149 | USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>) |
150 | |
151 | |
152 | template<typename T> int VarTmpl; |
153 | template<typename T> __declspec(dllimport) int ImportedVarTmpl; |
154 | |
155 | // Import implicit instantiation of an imported variable template. |
156 | // MSC-DAG: @"??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32 |
157 | // GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE = external dllimport global i32 |
158 | USEVAR(ImportedVarTmpl<ImplicitInst_Imported>) |
159 | |
160 | // Import explicit instantiation declaration of an imported variable template. |
161 | // MSC-DAG: @"??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32 |
162 | // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE = external dllimport global i32 |
163 | extern template int ImportedVarTmpl<ExplicitDecl_Imported>; |
164 | USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>) |
165 | |
166 | // An explicit instantiation definition of an imported variable template cannot |
167 | // be imported because the template must be defined which is illegal. |
168 | |
169 | // Import specialization of an imported variable template. |
170 | // MSC-DAG: @"??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32 |
171 | // GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE = external dllimport global i32 |
172 | template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>; |
173 | USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>) |
174 | |
175 | // Not importing specialization of an imported variable template without |
176 | // explicit dllimport. |
177 | // MSC-DAG: @"??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = dso_local global i32 0, align 4 |
178 | // GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE = dso_local global i32 0, align 4 |
179 | template<> int ImportedVarTmpl<ExplicitSpec_NotImported>; |
180 | USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>) |
181 | |
182 | // Import explicit instantiation declaration of a non-imported variable template. |
183 | // MSC-DAG: @"??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32 |
184 | // GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE = external dllimport global i32 |
185 | extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>; |
186 | USEVAR(VarTmpl<ExplicitDecl_Imported>) |
187 | |
188 | // Import explicit instantiation definition of a non-imported variable template. |
189 | // MSC-DAG: @"??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32 |
190 | // GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE = external dllimport global i32 |
191 | template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>; |
192 | USEVAR(VarTmpl<ExplicitInst_Imported>) |
193 | |
194 | // Import specialization of a non-imported variable template. |
195 | // MSC-DAG: @"??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32 |
196 | // GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE = external dllimport global i32 |
197 | template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>; |
198 | USEVAR(VarTmpl<ExplicitSpec_Imported>) |
199 | |
200 | |
201 | |
202 | //===----------------------------------------------------------------------===// |
203 | // Functions |
204 | //===----------------------------------------------------------------------===// |
205 | |
206 | // GNU-DAG: declare dso_local void @_ZdlPv(i8*) |
207 | |
208 | // Import function declaration. |
209 | // MSC-DAG: declare dllimport void @"?decl@@YAXXZ"() |
210 | // GNU-DAG: declare dllimport void @_Z4declv() |
211 | __declspec(dllimport) void decl(); |
212 | USE(decl) |
213 | |
214 | // extern "C" |
215 | // MSC-DAG: declare dllimport void @externC() |
216 | // GNU-DAG: declare dllimport void @externC() |
217 | extern "C" __declspec(dllimport) void externC(); |
218 | USE(externC) |
219 | |
220 | // Import inline function. |
221 | // MSC-DAG: declare dllimport void @"?inlineFunc@@YAXXZ"() |
222 | // GNU-DAG: define linkonce_odr dso_local void @_Z10inlineFuncv() |
223 | // MO1-DAG: define available_externally dllimport void @"?inlineFunc@@YAXXZ"() |
224 | // GO1-DAG: define linkonce_odr dso_local void @_Z10inlineFuncv() |
225 | __declspec(dllimport) inline void inlineFunc() {} |
226 | USE(inlineFunc) |
227 | |
228 | // MSC-DAG: declare dllimport void @"?inlineDecl@@YAXXZ"() |
229 | // GNU-DAG: define linkonce_odr dso_local void @_Z10inlineDeclv() |
230 | // MO1-DAG: define available_externally dllimport void @"?inlineDecl@@YAXXZ"() |
231 | // GO1-DAG: define linkonce_odr dso_local void @_Z10inlineDeclv() |
232 | __declspec(dllimport) inline void inlineDecl(); |
233 | void inlineDecl() {} |
234 | USE(inlineDecl) |
235 | |
236 | // MSC-DAG: declare dllimport void @"?inlineDef@@YAXXZ"() |
237 | // GNU-DAG: define linkonce_odr dso_local void @_Z9inlineDefv() |
238 | // MO1-DAG: define available_externally dllimport void @"?inlineDef@@YAXXZ"() |
239 | // GO1-DAG: define linkonce_odr dso_local void @_Z9inlineDefv() |
240 | __declspec(dllimport) void inlineDef(); |
241 | inline void inlineDef() {} |
242 | USE(inlineDef) |
243 | |
244 | // inline attributes |
245 | // MSC-DAG: declare dllimport void @"?noinline@@YAXXZ"() |
246 | // GNU-DAG: define linkonce_odr dso_local void @_Z8noinlinev() |
247 | __declspec(dllimport) __attribute__((noinline)) inline void noinline() {} |
248 | USE(noinline) |
249 | |
250 | // MSC2-NOT: @"?alwaysInline@@YAXXZ"() |
251 | // GNU2-NOT: @_Z12alwaysInlinev() |
252 | __declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {} |
253 | USE(alwaysInline) |
254 | |
255 | // Redeclarations |
256 | // MSC-DAG: declare dllimport void @"?redecl1@@YAXXZ"() |
257 | // GNU-DAG: declare dllimport void @_Z7redecl1v() |
258 | __declspec(dllimport) void redecl1(); |
259 | __declspec(dllimport) void redecl1(); |
260 | USE(redecl1) |
261 | |
262 | // NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC |
263 | // and drop the dllimport with a warning. |
264 | // MSC-DAG: declare dso_local void @"?redecl2@@YAXXZ"() |
265 | // GNU-DAG: declare dso_local void @_Z7redecl2v() |
266 | __declspec(dllimport) void redecl2(); |
267 | void redecl2(); |
268 | USE(redecl2) |
269 | |
270 | // MSC-DAG: define dso_local dllexport void @"?redecl3@@YAXXZ"() |
271 | // GNU-DAG: define dso_local void @_Z7redecl3v() |
272 | __declspec(dllimport) void redecl3(); |
273 | void redecl3() {} // dllimport ignored |
274 | USE(redecl3) |
275 | |
276 | |
277 | // Friend functions |
278 | // MSC-DAG: declare dllimport void @"?friend1@@YAXXZ"() |
279 | // GNU-DAG: declare dllimport void @_Z7friend1v() |
280 | // MSC-DAG: declare dso_local void @"?friend2@@YAXXZ"() |
281 | // GNU-DAG: declare dso_local void @_Z7friend2v() |
282 | // MSC-DAG: define dso_local dllexport void @"?friend3@@YAXXZ"() |
283 | // GNU-DAG: define dso_local void @_Z7friend3v() |
284 | // MSC-DAG: declare dso_local void @"?friend4@@YAXXZ"() |
285 | // GNU-DAG: declare dso_local void @_Z7friend4v() |
286 | // MSC-DAG: declare dllimport void @"?friend5@@YAXXZ"() |
287 | // GNU-DAG: declare dllimport void @_Z7friend5v() |
288 | |
289 | struct FuncFriend { |
290 | friend __declspec(dllimport) void friend1(); |
291 | friend __declspec(dllimport) void friend2(); |
292 | friend __declspec(dllimport) void friend3(); |
293 | }; |
294 | __declspec(dllimport) void friend1(); |
295 | void friend2(); // dllimport ignored |
296 | void friend3() {} // dllimport ignored |
297 | |
298 | __declspec(dllimport) void friend4(); |
299 | __declspec(dllimport) void friend5(); |
300 | struct FuncFriendRedecl { |
301 | friend void friend4(); // dllimport ignored |
302 | friend void ::friend5(); |
303 | }; |
304 | USE(friend1) |
305 | USE(friend2) |
306 | USE(friend3) |
307 | USE(friend4) |
308 | USE(friend5) |
309 | |
310 | // Implicit declarations can be redeclared with dllimport. |
311 | // MSC-DAG: declare dllimport noalias i8* @"??2@{{YAPAXI|YAPEAX_K}}@Z"( |
312 | // GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}( |
313 | __declspec(dllimport) void* operator new(__SIZE_TYPE__ n); |
314 | void UNIQ(use)() { ::operator new(42); } |
315 | |
316 | // MSC-DAG: declare dllimport void @"?externalFunc@ns@@YAXXZ"() |
317 | // GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv() |
318 | namespace ns { __declspec(dllimport) void externalFunc(); } |
319 | USE(ns::externalFunc) |
320 | |
321 | // A dllimport function referencing non-imported vars or functions must not be available_externally. |
322 | |
323 | __declspec(dllimport) int ImportedVar; |
324 | int NonImportedVar; |
325 | __declspec(dllimport) int ImportedFunc(); |
326 | int NonImportedFunc(); |
327 | struct ClassWithNonImportedMethod { int f(); }; |
328 | |
329 | __declspec(dllimport) inline int ReferencingImportedVar() { return ImportedVar; } |
330 | // MO1-DAG: define available_externally dllimport i32 @"?ReferencingImportedVar@@YAHXZ" |
331 | __declspec(dllimport) inline int ReferencingNonImportedVar() { return NonImportedVar; } |
332 | // MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedVar@@YAHXZ"() |
333 | __declspec(dllimport) inline int ReferencingImportedFunc() { return ImportedFunc(); } |
334 | // MO1-DAG: define available_externally dllimport i32 @"?ReferencingImportedFunc@@YAHXZ" |
335 | __declspec(dllimport) inline int ReferencingNonImportedFunc() { return NonImportedFunc(); } |
336 | // MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedFunc@@YAHXZ"() |
337 | __declspec(dllimport) inline int ReferencingNonImportedMethod(ClassWithNonImportedMethod *x) { return x->f(); } |
338 | // MO1-DAG: declare dllimport i32 @"?ReferencingNonImportedMethod |
339 | __declspec(dllimport) inline int ReferencingClassMemberPtr(int (ClassWithNonImportedMethod::*p)(), ClassWithNonImportedMethod *x) { return (x->*p)(); } |
340 | // MO1-DAG: define available_externally dllimport i32 @"?ReferencingClassMemberPtr@@YAHP8ClassWithNonImportedMethod@@AEHXZPAU1@@Z" |
341 | USE(ReferencingImportedVar) |
342 | USE(ReferencingNonImportedVar) |
343 | USE(ReferencingImportedFunc) |
344 | USE(ReferencingNonImportedFunc) |
345 | USE1(ReferencingNonImportedMethod) |
346 | void UNIQ(use)() { ReferencingClassMemberPtr(&ClassWithNonImportedMethod::f, nullptr); } |
347 | // References to operator new and delete count too, despite not being DeclRefExprs. |
348 | __declspec(dllimport) inline int *ReferencingNonImportedNew() { return new int[2]; } |
349 | // MO1-DAG: declare dllimport i32* @"?ReferencingNonImportedNew@@YAPAHXZ" |
350 | __declspec(dllimport) inline int *ReferencingNonImportedDelete() { delete (int*)nullptr; } |
351 | // MO1-DAG: declare dllimport i32* @"?ReferencingNonImportedDelete@@YAPAHXZ" |
352 | USE(ReferencingNonImportedNew) |
353 | USE(ReferencingNonImportedDelete) |
354 | __declspec(dllimport) void* operator new[](__SIZE_TYPE__); |
355 | __declspec(dllimport) void operator delete(void*); |
356 | __declspec(dllimport) inline int *ReferencingImportedNew() { return new int[2]; } |
357 | // MO1-DAG: define available_externally dllimport i32* @"?ReferencingImportedNew@@YAPAHXZ" |
358 | __declspec(dllimport) inline int *ReferencingImportedDelete() { delete (int*)nullptr; } |
359 | // MO1-DAG: define available_externally dllimport i32* @"?ReferencingImportedDelete@@YAPAHXZ" |
360 | USE(ReferencingImportedNew) |
361 | USE(ReferencingImportedDelete) |
362 | struct ClassWithDtor { ~ClassWithDtor() {} }; |
363 | struct __declspec(dllimport) ClassWithNonDllImportField { using X = ClassWithDtor; X t[2]; }; |
364 | struct __declspec(dllimport) ClassWithNonDllImportBase : public ClassWithDtor { }; |
365 | USECLASS(ClassWithNonDllImportField); |
366 | USECLASS(ClassWithNonDllImportBase); |
367 | // MO1-DAG: declare dllimport x86_thiscallcc void @"??1ClassWithNonDllImportBase@@QAE@XZ"(%struct.ClassWithNonDllImportBase*) |
368 | // MO1-DAG: declare dllimport x86_thiscallcc void @"??1ClassWithNonDllImportField@@QAE@XZ"(%struct.ClassWithNonDllImportField*) |
369 | struct ClassWithCtor { ClassWithCtor() {} }; |
370 | struct __declspec(dllimport) ClassWithNonDllImportFieldWithCtor { ClassWithCtor t; }; |
371 | USECLASS(ClassWithNonDllImportFieldWithCtor); |
372 | // MO1-DAG: declare dllimport x86_thiscallcc %struct.ClassWithNonDllImportFieldWithCtor* @"??0ClassWithNonDllImportFieldWithCtor@@QAE@XZ"(%struct.ClassWithNonDllImportFieldWithCtor* returned) |
373 | struct ClassWithImplicitDtor { __declspec(dllimport) ClassWithImplicitDtor(); ClassWithDtor member; }; |
374 | __declspec(dllimport) inline void ReferencingDtorThroughDefinition() { ClassWithImplicitDtor x; }; |
375 | USE(ReferencingDtorThroughDefinition) |
376 | // MO1-DAG: declare dllimport void @"?ReferencingDtorThroughDefinition@@YAXXZ"() |
377 | __declspec(dllimport) inline void ReferencingDtorThroughTemporary() { ClassWithImplicitDtor(); }; |
378 | USE(ReferencingDtorThroughTemporary) |
379 | // MO1-DAG: declare dllimport void @"?ReferencingDtorThroughTemporary@@YAXXZ"() |
380 | |
381 | // A dllimport function with a TLS variable must not be available_externally. |
382 | __declspec(dllimport) inline void FunctionWithTLSVar() { static __thread int x = 42; } |
383 | // MO1-DAG: declare dllimport void @"?FunctionWithTLSVar@@YAXXZ" |
384 | __declspec(dllimport) inline void FunctionWithNormalVar() { static int x = 42; } |
385 | // MO1-DAG: define available_externally dllimport void @"?FunctionWithNormalVar@@YAXXZ" |
386 | USE(FunctionWithTLSVar) |
387 | USE(FunctionWithNormalVar) |
388 | |
389 | |
390 | //===----------------------------------------------------------------------===// |
391 | // Function templates |
392 | //===----------------------------------------------------------------------===// |
393 | |
394 | // Import function template declaration. |
395 | // MSC-DAG: declare dllimport void @"??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() |
396 | // GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv() |
397 | template<typename T> __declspec(dllimport) void funcTmplDecl(); |
398 | USE(funcTmplDecl<ImplicitInst_Imported>) |
399 | |
400 | // Function template definitions cannot be imported. |
401 | |
402 | // Import inline function template. |
403 | // MSC-DAG: declare dllimport void @"??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"() |
404 | // GNU-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() |
405 | // MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"() |
406 | // GO1-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv() |
407 | template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} |
408 | USE(inlineFuncTmpl1<ImplicitInst_Imported>) |
409 | |
410 | // MSC-DAG: declare dllimport void @"??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"() |
411 | // GNU-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() |
412 | // MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"() |
413 | // GO1-DAG: define linkonce_odr dso_local void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv() |
414 | template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} |
415 | USE(inlineFuncTmpl2<ImplicitInst_Imported>) |
416 | |
417 | // MSC-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() |
418 | // GNU-DAG: define linkonce_odr dso_local void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() |
419 | // MO1-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() |
420 | // GO1-DAG: define linkonce_odr dso_local void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv() |
421 | template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); |
422 | template<typename T> void inlineFuncTmplDecl() {} |
423 | USE(inlineFuncTmplDecl<ImplicitInst_Imported>) |
424 | |
425 | // MSC-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"() |
426 | // GNU-DAG: define linkonce_odr dso_local void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() |
427 | // MO1-DAG: define linkonce_odr dso_local void @"??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"() |
428 | // GO1-DAG: define linkonce_odr dso_local void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv() |
429 | template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); |
430 | template<typename T> inline void inlineFuncTmplDef() {} |
431 | USE(inlineFuncTmplDef<ImplicitInst_Imported>) |
432 | |
433 | |
434 | // Redeclarations |
435 | // MSC-DAG: declare dllimport void @"??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"() |
436 | // GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv() |
437 | template<typename T> __declspec(dllimport) void funcTmplRedecl1(); |
438 | template<typename T> __declspec(dllimport) void funcTmplRedecl1(); |
439 | USE(funcTmplRedecl1<ImplicitInst_Imported>) |
440 | |
441 | // MSC-DAG: declare dso_local void @"??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"() |
442 | // GNU-DAG: declare dso_local void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv() |
443 | template<typename T> __declspec(dllimport) void funcTmplRedecl2(); |
444 | template<typename T> void funcTmplRedecl2(); // dllimport ignored |
445 | USE(funcTmplRedecl2<ImplicitInst_NotImported>) |
446 | |
447 | // MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"() |
448 | // GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv() |
449 | template<typename T> __declspec(dllimport) void funcTmplRedecl3(); |
450 | template<typename T> void funcTmplRedecl3() {} // dllimport ignored |
451 | USE(funcTmplRedecl3<ImplicitInst_NotImported>) |
452 | |
453 | |
454 | // Function template friends |
455 | // MSC-DAG: declare dllimport void @"??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"() |
456 | // GNU-DAG: declare dllimport void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv() |
457 | // MSC-DAG: declare dso_local void @"??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"() |
458 | // GNU-DAG: declare dso_local void @_Z15funcTmplFriend2I24ImplicitInst_NotImportedEvv() |
459 | // MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplFriend3@UImplicitInst_NotImported@@@@YAXXZ"() |
460 | // GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplFriend3I24ImplicitInst_NotImportedEvv() |
461 | // MSC-DAG: define linkonce_odr dso_local void @"??$funcTmplFriend4@UImplicitInst_Imported@@@@YAXXZ"() |
462 | // GNU-DAG: define linkonce_odr dso_local void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv() |
463 | struct FuncTmplFriend { |
464 | template<typename T> friend __declspec(dllimport) void funcTmplFriend1(); |
465 | template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); |
466 | template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); |
467 | template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4(); |
468 | }; |
469 | template<typename T> __declspec(dllimport) void funcTmplFriend1(); |
470 | template<typename T> void funcTmplFriend2(); // dllimport ignored |
471 | template<typename T> void funcTmplFriend3() {} // dllimport ignored |
472 | template<typename T> inline void funcTmplFriend4() {} |
473 | USE(funcTmplFriend1<ImplicitInst_Imported>) |
474 | USE(funcTmplFriend2<ImplicitInst_NotImported>) |
475 | USE(funcTmplFriend3<ImplicitInst_NotImported>) |
476 | USE(funcTmplFriend4<ImplicitInst_Imported>) |
477 | |
478 | // MSC-DAG: declare dllimport void @"??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"() |
479 | // GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv() |
480 | namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); } |
481 | USE(ns::externalFuncTmpl<ImplicitInst_Imported>) |
482 | |
483 | |
484 | template<typename T> void funcTmpl() {} |
485 | template<typename T> inline void inlineFuncTmpl() {} |
486 | template<typename T> __declspec(dllimport) void importedFuncTmplDecl(); |
487 | template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {} |
488 | |
489 | // Import implicit instantiation of an imported function template. |
490 | // MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"() |
491 | // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv() |
492 | USE(importedFuncTmplDecl<ImplicitInst_Imported>) |
493 | |
494 | // MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"() |
495 | // GNU-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() |
496 | // MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"() |
497 | // GO1-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv() |
498 | USE(importedFuncTmpl<ImplicitInst_Imported>) |
499 | |
500 | // Import explicit instantiation declaration of an imported function template. |
501 | // MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() |
502 | // GNU-DAG: declare dso_local void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() |
503 | // MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() |
504 | // GO1-DAG: define available_externally dso_local void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv() |
505 | extern template void importedFuncTmpl<ExplicitDecl_Imported>(); |
506 | USE(importedFuncTmpl<ExplicitDecl_Imported>) |
507 | |
508 | // Import explicit instantiation definition of an imported function template. |
509 | // MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() |
510 | // GNU-DAG: define weak_odr dso_local void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() |
511 | // MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() |
512 | // GO1-DAG: define weak_odr dso_local void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv() |
513 | template void importedFuncTmpl<ExplicitInst_Imported>(); |
514 | USE(importedFuncTmpl<ExplicitInst_Imported>) |
515 | |
516 | |
517 | // Import specialization of an imported function template. |
518 | // MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"() |
519 | // GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv() |
520 | template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>(); |
521 | USE(importedFuncTmplDecl<ExplicitSpec_Imported>) |
522 | |
523 | // MSC-DAG-FIXME: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"() |
524 | // MO1-DAG-FIXME: define available_externally dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"() |
525 | #ifdef MSABI |
526 | //template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {} |
527 | //USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>) |
528 | #endif |
529 | |
530 | // MSC-DAG: declare dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() |
531 | // GNU-DAG: define linkonce_odr dso_local void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv() |
532 | // MO1-DAG: define available_externally dllimport void @"??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() |
533 | // GO1-DAG: define linkonce_odr dso_local void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv() |
534 | template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {} |
535 | USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>) |
536 | |
537 | |
538 | // MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"() |
539 | // GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv() |
540 | template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>(); |
541 | USE(importedFuncTmpl<ExplicitSpec_Imported>) |
542 | |
543 | // MSC-DAG-FIXME: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() |
544 | // MO1-DAG-FIXME: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() |
545 | #ifdef MSABI |
546 | //template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} |
547 | //USE(importedFuncTmpl<ExplicitSpec_Def_Imported>) |
548 | #endif |
549 | |
550 | // MSC-DAG: declare dllimport void @"??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() |
551 | // GNU-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv() |
552 | // MO1-DAG: define available_externally dllimport void @"??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() |
553 | // GO1-DAG: define linkonce_odr dso_local void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv() |
554 | template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} |
555 | USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>) |
556 | |
557 | |
558 | // Not importing specialization of an imported function template without |
559 | // explicit dllimport. |
560 | // MSC-DAG: define dso_local void @"??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"() |
561 | // GNU-DAG: define dso_local void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv() |
562 | template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {} |
563 | USE(importedFuncTmpl<ExplicitSpec_NotImported>) |
564 | |
565 | |
566 | // Import explicit instantiation declaration of a non-imported function template. |
567 | // MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"() |
568 | // MSC-DAG: declare dllimport void @"??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() |
569 | // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv() |
570 | // GNU-DAG: declare dso_local void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() |
571 | // MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"() |
572 | // GO1-DAG: define available_externally dso_local void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv() |
573 | extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>(); |
574 | extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>(); |
575 | USE(funcTmpl<ExplicitDecl_Imported>) |
576 | USE(inlineFuncTmpl<ExplicitDecl_Imported>) |
577 | |
578 | |
579 | // Import explicit instantiation definition of a non-imported function template. |
580 | // MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"() |
581 | // MSC-DAG: declare dllimport void @"??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() |
582 | // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv() |
583 | // GNU-DAG: define weak_odr dso_local void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv() |
584 | // MO1-DAG: declare dllimport void @"??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"() |
585 | // MO1-DAG: define available_externally dllimport void @"??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"() |
586 | // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv() |
587 | // GO1-DAG: define weak_odr dso_local void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv() |
588 | template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>(); |
589 | template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>(); |
590 | USE(funcTmpl<ExplicitInst_Imported>) |
591 | USE(inlineFuncTmpl<ExplicitInst_Imported>) |
592 | |
593 | |
594 | // Import specialization of a non-imported function template. |
595 | // MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"() |
596 | // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv() |
597 | template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>(); |
598 | USE(funcTmpl<ExplicitSpec_Imported>) |
599 | |
600 | // MSC-DAG-FIXME: declare dllimport void @"??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() |
601 | // MO1-DAG-FIXME: define available_externally dllimport void @"??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"() |
602 | #ifdef MSABI |
603 | //template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} |
604 | //USE(funcTmpl<ExplicitSpec_Def_Imported>) |
605 | #endif |
606 | |
607 | // MSC-DAG: declare dllimport void @"??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() |
608 | // GNU-DAG: define linkonce_odr dso_local void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv() |
609 | // MO1-DAG: define available_externally dllimport void @"??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"() |
610 | // GO1-DAG: define linkonce_odr dso_local void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv() |
611 | template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} |
612 | USE(funcTmpl<ExplicitSpec_InlineDef_Imported>) |
613 | |
614 | #ifdef MSABI |
615 | namespace pr35435 { |
616 | struct X; |
617 | template <typename T> struct __declspec(dllimport) S { |
618 | void foo(T *t) { t->problem(); } |
619 | }; |
620 | template void S<X>::foo(X*); // Cannot be instantiated because X is incomplete; dllimport means it's treated as an instantiation decl. |
621 | } |
622 | #endif |
623 | |
624 | |
625 | //===----------------------------------------------------------------------===// |
626 | // Classes |
627 | //===----------------------------------------------------------------------===// |
628 | |
629 | struct __declspec(dllimport) T { |
630 | void a() {} |
631 | // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?a@T@@QAEXXZ" |
632 | |
633 | static void StaticMethod(); |
634 | // MSC-DAG: declare dllimport void @"?StaticMethod@T@@SAXXZ"() |
635 | // GNU-DAG: declare dllimport void @_ZN1T12StaticMethodEv() |
636 | |
637 | static int b; |
638 | // MO1-DAG: @"?b@T@@2HA" = external dllimport global i32 |
639 | |
640 | T& operator=(T&) = default; |
641 | // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@AAU0@@Z" |
642 | |
643 | T& operator=(T&&) = default; |
644 | // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them. |
645 | // M18-DAG: define linkonce_odr dso_local x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@$$QAU0@@Z" |
646 | // M19-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"??4T@@QAEAAU0@$$QAU0@@Z" |
647 | }; |
648 | USEMEMFUNC(T, a) |
649 | USESTATICMEMFUNC(T, StaticMethod) |
650 | USEVAR(T::b) |
651 | USECOPYASSIGN(T) |
652 | USEMOVEASSIGN(T) |
653 | |
654 | template <typename T> struct __declspec(dllimport) U { void foo() {} }; |
655 | // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"?foo@?$U@H@@QAEXXZ" |
656 | struct __declspec(dllimport) V : public U<int> { }; |
657 | USEMEMFUNC(V, foo) |
658 | |
659 | struct __declspec(dllimport) W { virtual void foo() {} }; |
660 | USECLASS(W) |
661 | // vftable: |
662 | // MO1-DAG: @"??_SW@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast (void (%struct.W*)* @"?foo@W@@UAEXXZ" to i8*)] } |
663 | // GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] } |
664 | |
665 | struct __declspec(dllimport) KeyFuncClass { |
666 | constexpr KeyFuncClass() {} |
667 | virtual void foo(); |
668 | }; |
669 | extern constexpr KeyFuncClass keyFuncClassVar = {}; |
670 | // G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant { [3 x i8*] } |
671 | |
672 | struct __declspec(dllimport) X : public virtual W {}; |
673 | USECLASS(X) |
674 | // vbtable: |
675 | // MO1-DAG: @"??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4] |
676 | |
677 | struct __declspec(dllimport) Y { |
678 | int x; |
679 | }; |
680 | |
681 | struct __declspec(dllimport) Z { virtual ~Z() {} }; |
682 | USECLASS(Z) |
683 | // User-defined dtor: |
684 | // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"??1Z@@UAE@XZ" |
685 | |
686 | namespace DontUseDtorAlias { |
687 | struct __declspec(dllimport) A { ~A(); }; |
688 | struct __declspec(dllimport) B : A { ~B(); }; |
689 | inline A::~A() { } |
690 | inline B::~B() { } |
691 | // Emit a real definition of B's constructor; don't alias it to A's. |
692 | // MO1-DAG: available_externally dllimport x86_thiscallcc void @"??1B@DontUseDtorAlias@@QAE@XZ" |
693 | USECLASS(B) |
694 | } |
695 | |
696 | namespace Vtordisp { |
697 | // Don't dllimport the vtordisp. |
698 | // MO1-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?f@?$C@H@Vtordisp@@$4PPPPPPPM@A@AEXXZ" |
699 | |
700 | class __declspec(dllimport) Base { |
701 | virtual void f() {} |
702 | }; |
703 | template <typename T> |
704 | class __declspec(dllimport) C : virtual public Base { |
705 | public: |
706 | C() {} |
707 | virtual void f() {} |
708 | }; |
709 | USECLASS(C<int>); |
710 | } |
711 | |
712 | namespace ClassTemplateStaticDef { |
713 | // Regular template static field: |
714 | template <typename T> struct __declspec(dllimport) S { |
715 | static int x; |
716 | }; |
717 | template <typename T> int S<T>::x; |
718 | // MSC-DAG: @"?x@?$S@H@ClassTemplateStaticDef@@2HA" = external dllimport global i32 |
719 | int f() { return S<int>::x; } |
720 | |
721 | // Partial class template specialization static field: |
722 | template <typename A> struct T; |
723 | template <typename A> struct __declspec(dllimport) T<A*> { |
724 | static int x; |
725 | }; |
726 | template <typename A> int T<A*>::x; |
727 | // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = external dllimport global i32 |
728 | int g() { return T<void*>::x; } |
729 | } |
730 | |
731 | namespace PR19933 { |
732 | // Don't dynamically initialize dllimport vars. |
733 | // MSC2-NOT: @llvm.global_ctors |
734 | // GNU2-NOT: @llvm.global_ctors |
735 | |
736 | struct NonPOD { NonPOD(); }; |
737 | template <typename T> struct A { static NonPOD x; }; |
738 | template <typename T> NonPOD A<T>::x; |
739 | template struct __declspec(dllimport) A<int>; |
740 | USEVARTYPE(NonPOD, A<int>::x); |
741 | // MSC-DAG: @"?x@?$A@H@PR19933@@2UNonPOD@2@A" = external dllimport global %"struct.PR19933::NonPOD" |
742 | |
743 | int f(); |
744 | template <typename T> struct B { static int x; }; |
745 | template <typename T> int B<T>::x = f(); |
746 | template struct __declspec(dllimport) B<int>; |
747 | USEVAR(B<int>::x); |
748 | // MSC-DAG: @"?x@?$B@H@PR19933@@2HA" = external dllimport global i32 |
749 | |
750 | constexpr int g() { return 42; } |
751 | template <typename T> struct C { static int x; }; |
752 | template <typename T> int C<T>::x = g(); |
753 | template struct __declspec(dllimport) C<int>; |
754 | USEVAR(C<int>::x); |
755 | // MSC-DAG: @"?x@?$C@H@PR19933@@2HA" = external dllimport global i32 |
756 | |
757 | template <int I> struct D { static int x, y; }; |
758 | template <int I> int D<I>::x = I + 1; |
759 | template <int I> int D<I>::y = I + f(); |
760 | template struct __declspec(dllimport) D<42>; |
761 | USEVAR(D<42>::x); |
762 | USEVAR(D<42>::y); |
763 | // MSC-DAG: @"?x@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32 |
764 | // MSC-DAG: @"?y@?$D@$0CK@@PR19933@@2HA" = external dllimport global i32 |
765 | } |
766 | |
767 | namespace PR21355 { |
768 | struct __declspec(dllimport) S { |
769 | virtual ~S(); |
770 | }; |
771 | S::~S() {} |
772 | |
773 | // S::~S is a key function, so we would ordinarily emit a strong definition for |
774 | // the vtable. However, S is imported, so the vtable should be too. |
775 | |
776 | // GNU-DAG: @_ZTVN7PR213551SE = available_externally dllimport unnamed_addr constant { [4 x i8*] } |
777 | } |
778 | |
779 | namespace PR21366 { |
780 | struct __declspec(dllimport) S { |
781 | void outOfLineMethod(); |
782 | void inlineMethod() {} |
783 | inline void anotherInlineMethod(); |
784 | void outOfClassInlineMethod(); |
785 | }; |
786 | void S::anotherInlineMethod() {} |
787 | inline void S::outOfClassInlineMethod() {} |
788 | } |
789 | |
790 | namespace PR27319 { |
791 | // Make sure we don't assert due to not having checked for operator delete on |
792 | // the destructor. |
793 | template <typename> struct A { |
794 | virtual ~A() = default; |
795 | }; |
796 | extern template struct __declspec(dllimport) A<int>; |
797 | void f() { new A<int>(); } |
798 | // MO1-DAG: @"??_S?$A@H@PR27319@@6B@" = linkonce_odr unnamed_addr constant { [1 x i8*] } |
799 | } |
800 | |
801 | // MS ignores DLL attributes on partial specializations. |
802 | template <typename T> struct PartiallySpecializedClassTemplate {}; |
803 | template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f(); }; |
804 | USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f); |
805 | // M32-DAG: declare dso_local x86_thiscallcc void @"?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ" |
806 | // G32-DAG: declare dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv |
807 | |
808 | // Attributes on explicit specializations are honored. |
809 | template <typename T> struct ExplicitlySpecializedClassTemplate {}; |
810 | template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f(); }; |
811 | USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f); |
812 | // M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" |
813 | // G32-DAG: declare dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv |
814 | |
815 | // MS inherits DLL attributes to partial specializations. |
816 | template <typename T> struct __declspec(dllimport) PartiallySpecializedImportedClassTemplate {}; |
817 | template <typename T> struct PartiallySpecializedImportedClassTemplate<T*> { void f() {} }; |
818 | USEMEMFUNC(PartiallySpecializedImportedClassTemplate<void*>, f); |
819 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$PartiallySpecializedImportedClassTemplate@PAX@@QAEXXZ" |
820 | // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN41PartiallySpecializedImportedClassTemplateIPvE1fEv |
821 | |
822 | // Attributes on the instantiation take precedence over attributes on the template. |
823 | template <typename T> struct __declspec(dllexport) ExplicitlyInstantiatedWithDifferentAttr { void f() {} }; |
824 | template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<int>; |
825 | USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f); |
826 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ" |
827 | |
828 | template <typename T> struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} ExplicitInstantiationDeclImportedDefTemplate() {}}; |
829 | extern template struct ExplicitInstantiationDeclImportedDefTemplate<int>; |
830 | template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate<int>; |
831 | USECLASS(ExplicitInstantiationDeclImportedDefTemplate<int>); |
832 | USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f); |
833 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ" |
834 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclImportedDefTemplate* @"??0?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAE@XZ" |
835 | // G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN44ExplicitInstantiationDeclImportedDefTemplateIiE1fEv |
836 | |
837 | template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} ExplicitInstantiationDeclExportedDefImportedTemplate() {} }; |
838 | extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>; |
839 | template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>; |
840 | USECLASS(ExplicitInstantiationDeclExportedDefImportedTemplate<int>); |
841 | USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f); |
842 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ" |
843 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"??0?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAE@XZ" |
844 | |
845 | template <typename T> struct PR23770BaseTemplate { void f() {} }; |
846 | template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {}; |
847 | extern template struct PR23770DerivedTemplate<int>; |
848 | template struct __declspec(dllimport) PR23770DerivedTemplate<int>; |
849 | USEMEMFUNC(PR23770BaseTemplate<int>, f); |
850 | // M32-DAG: declare dllimport x86_thiscallcc void @"?f@?$PR23770BaseTemplate@H@@QAEXXZ" |
851 | |
852 | namespace PR27810 { |
853 | template <class T> |
854 | struct basic_ostream { |
855 | struct sentry { |
856 | sentry() { } |
857 | void foo() { } |
858 | }; |
859 | }; |
860 | template class __declspec(dllimport) basic_ostream<char>; |
861 | // The explicit instantiation definition acts as an explicit instantiation |
862 | // *declaration*, dllimport is not inherited by the inner class, and no |
863 | // functions are emitted unless they are used. |
864 | |
865 | USEMEMFUNC(basic_ostream<char>::sentry, foo); |
866 | // M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?foo@sentry@?$basic_ostream@D@PR27810@@QAEXXZ" |
867 | // M32-NOT: ??0sentry@?$basic_ostream@D@PR27810@@QAE@XZ |
868 | } |
869 | |
870 | namespace PR27811 { |
871 | template <class T> struct codecvt { |
872 | virtual ~codecvt() { } |
873 | }; |
874 | template class __declspec(dllimport) codecvt<char>; |
875 | |
876 | // dllimport means this explicit instantiation definition gets treated as a |
877 | // declaration. Thus, the vtable should not be marked used, and in fact |
878 | // nothing for this class should be emitted at all since it's not used. |
879 | // M32-NOT: codecvt |
880 | } |
881 | |
882 | //===----------------------------------------------------------------------===// |
883 | // Classes with template base classes |
884 | //===----------------------------------------------------------------------===// |
885 | |
886 | template <typename T> struct ClassTemplate { void func() {} }; |
887 | template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); }; |
888 | template <typename T> void ExportedClassTemplate<T>::func() {} |
889 | template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); }; |
890 | |
891 | template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; |
892 | template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; |
893 | template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; |
894 | template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); }; |
895 | void ExplicitlyExportSpecializedTemplate<int>::func() {} |
896 | template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; |
897 | template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); }; |
898 | |
899 | template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; |
900 | template struct ExplicitlyInstantiatedTemplate<int>; |
901 | template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); }; |
902 | template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {} |
903 | template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; |
904 | template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); }; |
905 | template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; |
906 | |
907 | |
908 | // MS: ClassTemplate<int> gets imported. |
909 | struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {}; |
910 | USEMEMFUNC(ClassTemplate<int>, func) |
911 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$ClassTemplate@H@@QAEXXZ" |
912 | // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv |
913 | |
914 | // ImportedTemplate is explicitly imported. |
915 | struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {}; |
916 | USEMEMFUNC(ImportedClassTemplate<int>, func) |
917 | // M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ImportedClassTemplate@H@@QAEXXZ" |
918 | // G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv |
919 | |
920 | // ExportedTemplate is explicitly exported. |
921 | struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {}; |
922 | USEMEMFUNC(ExportedClassTemplate<int>, func) |
923 | // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExportedClassTemplate@H@@QAEXXZ" |
924 | // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv |
925 | |
926 | // Base class already implicitly instantiated without attribute. |
927 | struct DerivedFromTemplateD : public ClassTemplate<double> {}; |
928 | struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {}; |
929 | USEMEMFUNC(ClassTemplate<double>, func) |
930 | // M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ClassTemplate@N@@QAEXXZ" |
931 | // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv |
932 | |
933 | // MS: Base class already instantiated with dfferent attribute. |
934 | struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {}; |
935 | struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {}; |
936 | USEMEMFUNC(ClassTemplate<bool>, func) |
937 | // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ClassTemplate@_N@@QAEXXZ" |
938 | // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv |
939 | |
940 | // Base class already specialized without dll attribute. |
941 | struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; |
942 | USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func) |
943 | // M32-DAG: define linkonce_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ" |
944 | // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv |
945 | |
946 | // Base class alredy specialized with export attribute. |
947 | struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; |
948 | USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func) |
949 | // M32-DAG: define dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" |
950 | // G32-DAG: define dso_local dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv |
951 | |
952 | // Base class already specialized with import attribute. |
953 | struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; |
954 | USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func) |
955 | // M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ" |
956 | // G32-DAG: declare dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv |
957 | |
958 | // Base class already instantiated without dll attribute. |
959 | struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {}; |
960 | USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func) |
961 | // M32-DAG: define weak_odr dso_local x86_thiscallcc void @"?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ" |
962 | // G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv |
963 | |
964 | // Base class already instantiated with export attribute. |
965 | struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {}; |
966 | USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func) |
967 | // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @"?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ" |
968 | // G32-DAG: define weak_odr dso_local dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv |
969 | |
970 | // Base class already instantiated with import attribute. |
971 | struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {}; |
972 | USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func) |
973 | // M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ" |
974 | // G32-DAG: declare dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv |
975 | |
976 | // MS: A dll attribute propagates through multiple levels of instantiation. |
977 | template <typename T> struct TopClass { void func() {} }; |
978 | template <typename T> struct MiddleClass : public TopClass<T> { }; |
979 | struct __declspec(dllimport) BottomClass : public MiddleClass<int> { }; |
980 | USEMEMFUNC(TopClass<int>, func) |
981 | // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"?func@?$TopClass@H@@QAEXXZ" |
982 | // G32-DAG: define linkonce_odr dso_local x86_thiscallcc void @_ZN8TopClassIiE4funcEv |
983 | |
984 | template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} }; |
985 | extern template struct ExplicitInstantiationDeclTemplateBase<int>; |
986 | struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {}; |
987 | template struct ExplicitInstantiationDeclTemplateBase<int>; |
988 | USEMEMFUNC(ExplicitInstantiationDeclTemplateBase<int>, func) |
989 | // M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase@H@@QAEXXZ" |
990 | // G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN37ExplicitInstantiationDeclTemplateBaseIiE4funcEv |
991 | |
992 | template <typename T> struct ExplicitInstantiationDeclTemplateBase2 { void func() {} }; |
993 | extern template struct ExplicitInstantiationDeclTemplateBase2<int>; |
994 | struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase2 : public ExplicitInstantiationDeclTemplateBase2<int> {}; |
995 | template struct __declspec(dllexport) ExplicitInstantiationDeclTemplateBase2<int>; |
996 | USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2<int>, func) |
997 | // M32-DAG: declare dllimport x86_thiscallcc void @"?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ" |
998 | // G32-DAG: define weak_odr dso_local x86_thiscallcc void @_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv |
999 | |
1000 | namespace pr39496 { |
1001 | // Make sure dll attribute are inherited by static locals also in template |
1002 | // specializations. |
1003 | template <typename> struct __declspec(dllimport) S { int foo() { static int x; return x++; } }; |
1004 | int foo() { S<int> s; return s.foo(); } |
1005 | // MO1-DAG: @"?x@?{{1|2}}??foo@?$S@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4 |
1006 | |
1007 | template <typename> struct T { int foo() { static int x; return x++; } }; |
1008 | extern template struct __declspec(dllimport) T<int>; |
1009 | int bar() { T<int> t; return t.foo(); } |
1010 | // MO1-DAG: @"?x@?{{1|2}}??foo@?$T@H@pr39496@@Q{{[A-Z]*}}HXZ@4HA" = available_externally dllimport global i32 0, align 4 |
1011 | |
1012 | template <typename T> struct __declspec(dllimport) U { |
1013 | void foo() { |
1014 | // Don't inherit dllimport to src before attaching the initializer. |
1015 | static constexpr char src[] = {"hello"}; |
1016 | T arr[sizeof(src)]; |
1017 | } |
1018 | }; |
1019 | void baz() { U<int> u; u.foo(); } // No diagnostic. |
1020 | |
1021 | } |
1022 | |