1 | // RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s |
2 | // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s |
3 | // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s |
4 | // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s |
5 | |
6 | // Helper structs to make templates more expressive. |
7 | struct ImplicitInst_Imported {}; |
8 | struct ExplicitDecl_Imported {}; |
9 | struct ExplicitInst_Imported {}; |
10 | struct ExplicitSpec_Imported {}; |
11 | struct ExplicitSpec_Def_Imported {}; |
12 | struct ExplicitSpec_InlineDef_Imported {}; |
13 | struct ExplicitSpec_NotImported {}; |
14 | namespace { struct Internal {}; } |
15 | |
16 | |
17 | // Invalid usage. |
18 | __declspec(dllimport) typedef int typedef1; |
19 | // expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} |
20 | typedef __declspec(dllimport) int typedef2; |
21 | // expected-warning@-1{{'dllimport' attribute only applies to}} |
22 | typedef int __declspec(dllimport) typedef3; |
23 | // expected-warning@-1{{'dllimport' attribute only applies to}} |
24 | typedef __declspec(dllimport) void (*FunTy)(); |
25 | // expected-warning@-1{{'dllimport' attribute only applies to}} |
26 | enum __declspec(dllimport) Enum {}; |
27 | // expected-warning@-1{{'dllimport' attribute only applies to}} |
28 | #if __has_feature(cxx_strong_enums) |
29 | enum class __declspec(dllimport) EnumClass {}; |
30 | // expected-warning@-1{{'dllimport' attribute only applies to}} |
31 | #endif |
32 | |
33 | |
34 | |
35 | //===----------------------------------------------------------------------===// |
36 | // Globals |
37 | //===----------------------------------------------------------------------===// |
38 | |
39 | // Import declaration. |
40 | __declspec(dllimport) extern int ExternGlobalDecl; |
41 | |
42 | // dllimport implies a declaration. |
43 | __declspec(dllimport) int GlobalDecl; |
44 | int **__attribute__((dllimport))* GlobalDeclChunkAttr; |
45 | int GlobalDeclAttr __attribute__((dllimport)); |
46 | |
47 | // Not allowed on definitions. |
48 | __declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}} |
49 | __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}} |
50 | int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}} |
51 | |
52 | // Declare, then reject definition. |
53 | #ifdef GNU |
54 | // expected-note@+2{{previous attribute is here}} |
55 | #endif |
56 | __declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} |
57 | #ifdef MS |
58 | // expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
59 | #else |
60 | // expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
61 | #endif |
62 | int ExternGlobalDeclInit = 1; |
63 | |
64 | #ifdef GNU |
65 | // expected-note@+2{{previous attribute is here}} |
66 | #endif |
67 | __declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} |
68 | #ifdef MS |
69 | // expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
70 | #else |
71 | // expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
72 | #endif |
73 | int GlobalDeclInit = 1; |
74 | |
75 | #ifdef GNU |
76 | // expected-note@+2{{previous attribute is here}} |
77 | #endif |
78 | int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} |
79 | #ifdef MS |
80 | // expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
81 | #else |
82 | // expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
83 | #endif |
84 | int *GlobalDeclChunkAttrInit = 0; |
85 | |
86 | #ifdef GNU |
87 | // expected-note@+2{{previous attribute is here}} |
88 | #endif |
89 | int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} |
90 | #ifdef MS |
91 | // expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
92 | #else |
93 | // expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
94 | #endif |
95 | int GlobalDeclAttrInit = 1; |
96 | |
97 | // Redeclarations |
98 | __declspec(dllimport) extern int GlobalRedecl1; |
99 | __declspec(dllimport) extern int GlobalRedecl1; |
100 | |
101 | __declspec(dllimport) int GlobalRedecl2a; |
102 | __declspec(dllimport) int GlobalRedecl2a; |
103 | |
104 | int *__attribute__((dllimport)) GlobalRedecl2b; |
105 | int *__attribute__((dllimport)) GlobalRedecl2b; |
106 | |
107 | int GlobalRedecl2c __attribute__((dllimport)); |
108 | int GlobalRedecl2c __attribute__((dllimport)); |
109 | |
110 | __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
111 | extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
112 | |
113 | extern int GlobalRedecl4; // expected-note{{previous declaration is here}} |
114 | __declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}} |
115 | |
116 | extern "C" { |
117 | extern int GlobalRedecl5; // expected-note{{previous declaration is here}} |
118 | __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}} |
119 | } |
120 | |
121 | // External linkage is required. |
122 | __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}} |
123 | __declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}} |
124 | #ifndef MS |
125 | namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}} |
126 | #endif |
127 | namespace ns { __declspec(dllimport) int ExternalGlobal; } |
128 | |
129 | __declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}} |
130 | // expected-error@-1{{definition of dllimport data}} |
131 | |
132 | // Thread local variables are invalid. |
133 | __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}} |
134 | // This doesn't work on MinGW, because there, dllimport on the inline function is ignored. |
135 | #ifndef GNU |
136 | inline void __declspec(dllimport) ImportedInlineWithThreadLocal() { |
137 | static __thread int OK; // no-error |
138 | } |
139 | #endif |
140 | |
141 | // Import in local scope. |
142 | __declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}} |
143 | __declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}} |
144 | __declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}} |
145 | void functionScope() { |
146 | __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}} |
147 | int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}} |
148 | int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}} |
149 | |
150 | __declspec(dllimport) int LocalVarDecl; |
151 | __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}} |
152 | __declspec(dllimport) extern int ExternLocalVarDecl; |
153 | __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}} |
154 | __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}} |
155 | } |
156 | |
157 | |
158 | |
159 | //===----------------------------------------------------------------------===// |
160 | // Variable templates |
161 | //===----------------------------------------------------------------------===// |
162 | #if __has_feature(cxx_variable_templates) |
163 | |
164 | // Import declaration. |
165 | template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl; |
166 | |
167 | // dllimport implies a declaration. |
168 | template<typename T> __declspec(dllimport) int VarTmplDecl; |
169 | |
170 | // Not allowed on definitions. |
171 | template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}} |
172 | template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}} |
173 | template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}} |
174 | |
175 | // Declare, then reject definition. |
176 | #ifdef GNU |
177 | // expected-note@+3{{previous attribute is here}} |
178 | #endif |
179 | template <typename T> |
180 | __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} |
181 | #ifdef MS |
182 | // expected-warning@+5{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
183 | #else |
184 | // expected-warning@+3{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
185 | #endif |
186 | template <typename T> |
187 | int ExternVarTmplDeclInit = 1; |
188 | |
189 | #ifdef GNU |
190 | // expected-note@+3{{previous attribute is here}} |
191 | #endif |
192 | template <typename T> |
193 | __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} |
194 | #ifdef MS |
195 | // expected-warning@+5{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
196 | #else |
197 | // expected-warning@+3{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
198 | #endif |
199 | template <typename T> |
200 | int VarTmplDeclInit = 1; |
201 | |
202 | // Redeclarations |
203 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; |
204 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl1; |
205 | |
206 | template<typename T> __declspec(dllimport) int VarTmplRedecl2; |
207 | template<typename T> __declspec(dllimport) int VarTmplRedecl2; |
208 | |
209 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
210 | template<typename T> extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
211 | |
212 | template<typename T> extern int VarTmplRedecl4; // expected-note{{previous declaration is here}} |
213 | template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}} |
214 | |
215 | // External linkage is required. |
216 | template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}} |
217 | template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}} |
218 | #ifndef MS |
219 | namespace { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}} |
220 | #endif |
221 | namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; } |
222 | |
223 | template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}} |
224 | |
225 | |
226 | template<typename T> int VarTmpl; |
227 | template<typename T> __declspec(dllimport) int ImportedVarTmpl; |
228 | |
229 | // Import implicit instantiation of an imported variable template. |
230 | int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; } |
231 | |
232 | // Import explicit instantiation declaration of an imported variable template. |
233 | extern template int ImportedVarTmpl<ExplicitDecl_Imported>; |
234 | |
235 | // An explicit instantiation definition of an imported variable template cannot |
236 | // be imported because the template must be defined which is illegal. |
237 | |
238 | // Import specialization of an imported variable template. |
239 | template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>; |
240 | template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}} |
241 | |
242 | // Not importing specialization of an imported variable template without |
243 | // explicit dllimport. |
244 | template<> int ImportedVarTmpl<ExplicitSpec_NotImported>; |
245 | |
246 | |
247 | // Import explicit instantiation declaration of a non-imported variable template. |
248 | extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>; |
249 | |
250 | // Import explicit instantiation definition of a non-imported variable template. |
251 | template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>; |
252 | |
253 | // Import specialization of a non-imported variable template. |
254 | template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>; |
255 | template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}} |
256 | |
257 | #endif // __has_feature(cxx_variable_templates) |
258 | |
259 | |
260 | //===----------------------------------------------------------------------===// |
261 | // Functions |
262 | //===----------------------------------------------------------------------===// |
263 | |
264 | // Import function declaration. Check different placements. |
265 | __attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__ |
266 | __declspec(dllimport) void decl1B(); |
267 | |
268 | void __attribute__((dllimport)) decl2A(); |
269 | void __declspec(dllimport) decl2B(); |
270 | |
271 | // Not allowed on function definitions. |
272 | __declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
273 | |
274 | // extern "C" |
275 | extern "C" __declspec(dllimport) void externC(); |
276 | |
277 | // Import inline function. |
278 | #ifdef GNU |
279 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
280 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
281 | #endif |
282 | __declspec(dllimport) inline void inlineFunc1() {} |
283 | inline void __attribute__((dllimport)) inlineFunc2() {} |
284 | |
285 | #ifdef GNU |
286 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
287 | #endif |
288 | __declspec(dllimport) inline void inlineDecl(); |
289 | void inlineDecl() {} |
290 | |
291 | __declspec(dllimport) void inlineDef(); |
292 | #ifdef GNU |
293 | // expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}} |
294 | #endif |
295 | inline void inlineDef() {} |
296 | |
297 | // Redeclarations |
298 | __declspec(dllimport) void redecl1(); |
299 | __declspec(dllimport) void redecl1(); |
300 | |
301 | __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
302 | void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
303 | |
304 | #ifdef GNU |
305 | // expected-note@+2{{previous attribute is here}} |
306 | #endif |
307 | __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} |
308 | // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport. |
309 | #ifdef MS |
310 | // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
311 | #else |
312 | // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
313 | #endif |
314 | void redecl3() {} |
315 | |
316 | void redecl4(); // expected-note{{previous declaration is here}} |
317 | __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}} |
318 | |
319 | extern "C" { |
320 | void redecl5(); // expected-note{{previous declaration is here}} |
321 | __declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}} |
322 | } |
323 | |
324 | #ifdef MS |
325 | void redecl6(); // expected-note{{previous declaration is here}} |
326 | __declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}} |
327 | #else |
328 | void redecl6(); |
329 | __declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
330 | #endif |
331 | |
332 | // Friend functions |
333 | struct FuncFriend { |
334 | friend __declspec(dllimport) void friend1(); |
335 | friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
336 | #ifdef GNU |
337 | // expected-note@+2{{previous attribute is here}} |
338 | #endif |
339 | friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} |
340 | friend void friend4(); // expected-note{{previous declaration is here}} |
341 | #ifdef MS |
342 | // expected-note@+2{{previous declaration is here}} |
343 | #endif |
344 | friend void friend5(); |
345 | }; |
346 | __declspec(dllimport) void friend1(); |
347 | void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
348 | #ifdef MS |
349 | // expected-warning@+4{{'friend3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
350 | #else |
351 | // expected-warning@+2{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
352 | #endif |
353 | void friend3() {} |
354 | __declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}} |
355 | #ifdef MS |
356 | __declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}} |
357 | #else |
358 | __declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
359 | #endif |
360 | |
361 | |
362 | void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
363 | void __declspec(dllimport) friend7(); |
364 | struct FuncFriend2 { |
365 | friend void friend6(); // expected-warning{{'friend6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
366 | friend void ::friend7(); |
367 | }; |
368 | |
369 | // Implicit declarations can be redeclared with dllimport. |
370 | __declspec(dllimport) void* operator new(__SIZE_TYPE__ n); |
371 | |
372 | // External linkage is required. |
373 | __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}} |
374 | __declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}} |
375 | namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}} |
376 | namespace ns { __declspec(dllimport) void externalFunc(); } |
377 | |
378 | // Import deleted functions. |
379 | // FIXME: Deleted functions are definitions so a missing inline is diagnosed |
380 | // here which is irrelevant. But because the delete keyword is parsed later |
381 | // there is currently no straight-forward way to avoid this diagnostic. |
382 | __declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}} |
383 | #ifdef MS |
384 | __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
385 | #else |
386 | __declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
387 | #endif |
388 | |
389 | |
390 | |
391 | //===----------------------------------------------------------------------===// |
392 | // Function templates |
393 | //===----------------------------------------------------------------------===// |
394 | |
395 | // Import function template declaration. Check different placements. |
396 | template<typename T> __declspec(dllimport) void funcTmplDecl1(); |
397 | template<typename T> void __declspec(dllimport) funcTmplDecl2(); |
398 | |
399 | // Import function template definition. |
400 | template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
401 | |
402 | // Import inline function template. |
403 | #ifdef GNU // MinGW always ignores dllimport on inline functions. |
404 | |
405 | template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
406 | template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
407 | |
408 | template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} |
409 | template<typename T> void inlineFuncTmplDecl() {} |
410 | |
411 | template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); |
412 | template<typename T> inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}} |
413 | |
414 | #else // MSVC drops dllimport when the function template is redeclared without it. (It doesn't warn, but we do.) |
415 | |
416 | template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} |
417 | template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} |
418 | |
419 | template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
420 | template<typename T> void inlineFuncTmplDecl() {} // expected-warning{{'inlineFuncTmplDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
421 | |
422 | template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
423 | template<typename T> inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
424 | #endif |
425 | |
426 | // Redeclarations |
427 | template<typename T> __declspec(dllimport) void funcTmplRedecl1(); |
428 | template<typename T> __declspec(dllimport) void funcTmplRedecl1(); |
429 | |
430 | template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
431 | template<typename T> void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
432 | |
433 | template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
434 | template<typename T> void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
435 | |
436 | template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}} |
437 | template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}} |
438 | |
439 | #ifdef MS |
440 | template<typename T> void funcTmplRedecl5(); // expected-note{{previous declaration is here}} |
441 | template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}} |
442 | #endif |
443 | |
444 | // Function template friends |
445 | struct FuncTmplFriend { |
446 | template<typename T> friend __declspec(dllimport) void funcTmplFriend1(); |
447 | template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
448 | template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
449 | template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} |
450 | #ifdef GNU |
451 | // expected-warning@+4{{'dllimport' attribute ignored on inline function}} |
452 | #else |
453 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
454 | #endif |
455 | template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5(); |
456 | }; |
457 | template<typename T> __declspec(dllimport) void funcTmplFriend1(); |
458 | template<typename T> void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
459 | template<typename T> void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
460 | template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}} |
461 | #ifdef MS |
462 | // expected-warning@+2{{'funcTmplFriend5' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
463 | #endif |
464 | template<typename T> inline void funcTmplFriend5() {} |
465 | |
466 | // External linkage is required. |
467 | template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}} |
468 | template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}} |
469 | namespace { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}} |
470 | namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); } |
471 | |
472 | |
473 | template<typename T> void funcTmpl() {} |
474 | template<typename T> inline void inlineFuncTmpl() {} |
475 | template<typename T> __declspec(dllimport) void importedFuncTmplDecl(); |
476 | #ifdef GNU |
477 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
478 | #endif |
479 | template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {} |
480 | |
481 | // Import implicit instantiation of an imported function template. |
482 | void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); } |
483 | void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); } |
484 | |
485 | // Import explicit instantiation declaration of an imported function template. |
486 | extern template void importedFuncTmpl<ExplicitDecl_Imported>(); |
487 | |
488 | // Import explicit instantiation definition of an imported function template. |
489 | // NB: MSVC fails this instantiation without explicit dllimport which is most |
490 | // likely a bug because an implicit instantiation is accepted. |
491 | template void importedFuncTmpl<ExplicitInst_Imported>(); |
492 | |
493 | // Import specialization of an imported function template. A definition must be |
494 | // declared inline. |
495 | template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>(); |
496 | template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
497 | #ifdef MS |
498 | template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {} |
499 | #endif |
500 | |
501 | // Not importing specialization of an imported function template without |
502 | // explicit dllimport. |
503 | template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {} |
504 | |
505 | |
506 | // Import explicit instantiation declaration of a non-imported function template. |
507 | extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>(); |
508 | #ifdef GNU |
509 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
510 | #endif |
511 | extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>(); |
512 | |
513 | // Import explicit instantiation definition of a non-imported function template. |
514 | template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>(); |
515 | #ifdef GNU |
516 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
517 | #endif |
518 | template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>(); |
519 | |
520 | // Import specialization of a non-imported function template. A definition must |
521 | // be declared inline. |
522 | template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>(); |
523 | template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
524 | #ifdef GNU |
525 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
526 | #endif |
527 | template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {} |
528 | |
529 | |
530 | //===----------------------------------------------------------------------===// |
531 | // Class members |
532 | //===----------------------------------------------------------------------===// |
533 | |
534 | // Import individual members of a class. |
535 | struct ImportMembers { |
536 | struct Nested { |
537 | __declspec(dllimport) void normalDecl(); |
538 | #ifdef GNU |
539 | // expected-note@+2{{previous attribute is here}} |
540 | #endif |
541 | __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} |
542 | }; |
543 | |
544 | #ifdef GNU |
545 | // expected-note@+5{{previous attribute is here}} |
546 | // expected-warning@+5{{'dllimport' attribute ignored on inline function}} |
547 | // expected-warning@+6{{'dllimport' attribute ignored on inline function}} |
548 | #endif |
549 | __declspec(dllimport) void normalDecl(); |
550 | __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} |
551 | __declspec(dllimport) void normalInclass() {} |
552 | __declspec(dllimport) void normalInlineDef(); |
553 | __declspec(dllimport) inline void normalInlineDecl(); |
554 | #ifdef GNU |
555 | // expected-note@+5{{previous attribute is here}} |
556 | // expected-warning@+5{{'dllimport' attribute ignored on inline function}} |
557 | // expected-warning@+6{{'dllimport' attribute ignored on inline function}} |
558 | #endif |
559 | __declspec(dllimport) virtual void virtualDecl(); |
560 | __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} |
561 | __declspec(dllimport) virtual void virtualInclass() {} |
562 | __declspec(dllimport) virtual void virtualInlineDef(); |
563 | __declspec(dllimport) virtual inline void virtualInlineDecl(); |
564 | #ifdef GNU |
565 | // expected-note@+5{{previous attribute is here}} |
566 | // expected-warning@+5{{'dllimport' attribute ignored on inline function}} |
567 | // expected-warning@+6{{'dllimport' attribute ignored on inline function}} |
568 | #endif |
569 | __declspec(dllimport) static void staticDecl(); |
570 | __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} |
571 | __declspec(dllimport) static void staticInclass() {} |
572 | __declspec(dllimport) static void staticInlineDef(); |
573 | __declspec(dllimport) static inline void staticInlineDecl(); |
574 | |
575 | protected: |
576 | __declspec(dllimport) void protectedDecl(); |
577 | private: |
578 | __declspec(dllimport) void privateDecl(); |
579 | public: |
580 | |
581 | __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}} |
582 | __declspec(dllimport) static int StaticField; |
583 | __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} |
584 | __declspec(dllimport) static const int StaticConstField; |
585 | __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} |
586 | __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; |
587 | __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; |
588 | __declspec(dllimport) constexpr static int ConstexprField = 1; |
589 | __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} |
590 | }; |
591 | |
592 | #ifdef MS |
593 | // expected-warning@+4{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
594 | #else |
595 | // expected-warning@+2{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
596 | #endif |
597 | void ImportMembers::Nested::normalDef() {} |
598 | #ifdef MS |
599 | // expected-warning@+4{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
600 | #else |
601 | // expected-warning@+2{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
602 | #endif |
603 | void ImportMembers::normalDef() {} |
604 | #ifdef GNU |
605 | // expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
606 | #endif |
607 | inline void ImportMembers::normalInlineDef() {} |
608 | void ImportMembers::normalInlineDecl() {} |
609 | #ifdef MS |
610 | // expected-warning@+4{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
611 | #else |
612 | // expected-warning@+2{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
613 | #endif |
614 | void ImportMembers::virtualDef() {} |
615 | #ifdef GNU |
616 | // expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
617 | #endif |
618 | inline void ImportMembers::virtualInlineDef() {} |
619 | void ImportMembers::virtualInlineDecl() {} |
620 | #ifdef MS |
621 | // expected-warning@+4{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
622 | #else |
623 | // expected-warning@+2{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
624 | #endif |
625 | void ImportMembers::staticDef() {} |
626 | #ifdef GNU |
627 | // expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
628 | #endif |
629 | inline void ImportMembers::staticInlineDef() {} |
630 | void ImportMembers::staticInlineDecl() {} |
631 | |
632 | int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} |
633 | const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} |
634 | constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}} |
635 | |
636 | |
637 | // Import on member definitions. |
638 | struct ImportMemberDefs { |
639 | __declspec(dllimport) void normalDef(); |
640 | __declspec(dllimport) void normalInlineDef(); |
641 | __declspec(dllimport) virtual void virtualDef(); |
642 | __declspec(dllimport) virtual void virtualInlineDef(); |
643 | __declspec(dllimport) static void staticDef(); |
644 | __declspec(dllimport) static void staticInlineDef(); |
645 | #ifdef MS |
646 | __declspec(dllimport) inline void normalInlineDecl(); |
647 | __declspec(dllimport) virtual inline void virtualInlineDecl(); |
648 | __declspec(dllimport) static inline void staticInlineDecl(); |
649 | #endif |
650 | |
651 | __declspec(dllimport) static int StaticField; |
652 | __declspec(dllimport) static const int StaticConstField; |
653 | __declspec(dllimport) constexpr static int ConstexprField = 1; |
654 | }; |
655 | |
656 | __declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
657 | __declspec(dllimport) void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
658 | __declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} |
659 | #ifdef MS |
660 | __declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {} |
661 | __declspec(dllimport) void ImportMemberDefs::normalInlineDecl() {} |
662 | __declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {} |
663 | __declspec(dllimport) void ImportMemberDefs::virtualInlineDecl() {} |
664 | __declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {} |
665 | __declspec(dllimport) void ImportMemberDefs::staticInlineDecl() {} |
666 | #endif |
667 | |
668 | __declspec(dllimport) int ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} |
669 | __declspec(dllimport) const int ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} |
670 | __declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} |
671 | |
672 | |
673 | // Import special member functions. |
674 | struct ImportSpecials { |
675 | __declspec(dllimport) ImportSpecials(); |
676 | __declspec(dllimport) ~ImportSpecials(); |
677 | __declspec(dllimport) ImportSpecials(const ImportSpecials&); |
678 | __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&); |
679 | __declspec(dllimport) ImportSpecials(ImportSpecials&&); |
680 | __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&); |
681 | }; |
682 | |
683 | |
684 | // Import deleted member functions. |
685 | struct ImportDeleted { |
686 | #ifdef MS |
687 | __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
688 | __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
689 | __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
690 | __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
691 | __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
692 | __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
693 | __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} |
694 | #else |
695 | __declspec(dllimport) ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
696 | __declspec(dllimport) ~ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
697 | __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
698 | __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
699 | __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
700 | __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
701 | __declspec(dllimport) void deleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} |
702 | #endif |
703 | }; |
704 | |
705 | |
706 | // Import allocation functions. |
707 | struct ImportAlloc { |
708 | __declspec(dllimport) void* operator new(__SIZE_TYPE__); |
709 | __declspec(dllimport) void* operator new[](__SIZE_TYPE__); |
710 | __declspec(dllimport) void operator delete(void*); |
711 | __declspec(dllimport) void operator delete[](void*); |
712 | }; |
713 | |
714 | |
715 | // Import defaulted member functions. |
716 | struct ImportDefaulted { |
717 | #ifdef GNU |
718 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
719 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
720 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
721 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
722 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
723 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
724 | #endif |
725 | __declspec(dllimport) ImportDefaulted() = default; |
726 | __declspec(dllimport) ~ImportDefaulted() = default; |
727 | __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default; |
728 | __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default; |
729 | __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default; |
730 | __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default; |
731 | }; |
732 | |
733 | |
734 | // Import defaulted member function definitions. |
735 | struct ImportDefaultedDefs { |
736 | __declspec(dllimport) ImportDefaultedDefs(); |
737 | #ifdef GNU |
738 | // expected-note@+2{{previous attribute is here}} |
739 | #endif |
740 | __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} |
741 | |
742 | #ifdef GNU |
743 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
744 | // expected-note@+2{{previous declaration is here}} |
745 | #endif |
746 | __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&); |
747 | __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&); |
748 | |
749 | __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&); |
750 | #ifdef GNU |
751 | // expected-note@+2{{previous attribute is here}} |
752 | #endif |
753 | __declspec(dllimport) ImportDefaultedDefs &operator=(ImportDefaultedDefs &&); // expected-note{{previous declaration is here}} |
754 | }; |
755 | |
756 | // Not allowed on definitions. |
757 | __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} |
758 | |
759 | #ifdef MS |
760 | // expected-warning@+5{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
761 | #else |
762 | // expected-warning@+3{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
763 | #endif |
764 | // dllimport cannot be dropped. |
765 | ImportDefaultedDefs::~ImportDefaultedDefs() = default; |
766 | |
767 | // Import inline declaration and definition. |
768 | #ifdef GNU |
769 | // expected-error@+3{{redeclaration of 'ImportDefaultedDefs::ImportDefaultedDefs' cannot add 'dllimport' attribute}} |
770 | // expected-warning@+3{{'ImportDefaultedDefs::operator=' redeclared inline; 'dllimport' attribute ignored}} |
771 | #endif |
772 | __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default; |
773 | inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default; |
774 | |
775 | __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} |
776 | #ifdef MS |
777 | // expected-warning@+4{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
778 | #else |
779 | // expected-warning@+2{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
780 | #endif |
781 | ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default; |
782 | |
783 | // Redeclarations cannot add dllimport. |
784 | struct MemberRedecl { |
785 | void normalDef(); // expected-note{{previous declaration is here}} |
786 | inline void normalInlineDecl(); // expected-note{{previous declaration is here}} |
787 | virtual void virtualDef(); // expected-note{{previous declaration is here}} |
788 | virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} |
789 | static void staticDef(); // expected-note{{previous declaration is here}} |
790 | static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} |
791 | |
792 | #ifdef MS |
793 | // expected-note@+4{{previous declaration is here}} |
794 | // expected-note@+4{{previous declaration is here}} |
795 | // expected-note@+4{{previous declaration is here}} |
796 | #endif |
797 | void normalInlineDef(); |
798 | virtual void virtualInlineDef(); |
799 | static void staticInlineDef(); |
800 | |
801 | static int StaticField; // expected-note{{previous declaration is here}} |
802 | static const int StaticConstField; // expected-note{{previous declaration is here}} |
803 | constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} |
804 | }; |
805 | |
806 | __declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}} |
807 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
808 | __declspec(dllimport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} |
809 | __declspec(dllimport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}} |
810 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
811 | __declspec(dllimport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}} |
812 | __declspec(dllimport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}} |
813 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
814 | __declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} |
815 | |
816 | #ifdef MS |
817 | __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}} |
818 | __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}} |
819 | __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}} |
820 | #else |
821 | __declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
822 | __declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
823 | __declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
824 | #endif |
825 | |
826 | |
827 | |
828 | __declspec(dllimport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}} |
829 | // expected-error@-1{{definition of dllimport static field not allowed}} |
830 | // expected-note@-2{{attribute is here}} |
831 | __declspec(dllimport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}} |
832 | // expected-error@-1{{definition of dllimport static field not allowed}} |
833 | // expected-note@-2{{attribute is here}} |
834 | __declspec(dllimport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}} |
835 | // expected-error@-1{{definition of dllimport static field not allowed}} |
836 | // expected-note@-2{{attribute is here}} |
837 | |
838 | |
839 | |
840 | //===----------------------------------------------------------------------===// |
841 | // Class member templates |
842 | //===----------------------------------------------------------------------===// |
843 | |
844 | struct ImportMemberTmpl { |
845 | template<typename T> __declspec(dllimport) void normalDecl(); |
846 | template<typename T> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
847 | #ifdef MS |
848 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
849 | #endif |
850 | template<typename T> __declspec(dllimport) void normalInlineDef(); |
851 | template<typename T> __declspec(dllimport) static void staticDecl(); |
852 | template<typename T> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
853 | #ifdef MS |
854 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
855 | #endif |
856 | template<typename T> __declspec(dllimport) static void staticInlineDef(); |
857 | |
858 | #ifdef GNU |
859 | template<typename T> __declspec(dllimport) void normalInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
860 | template<typename T> __declspec(dllimport) inline void normalInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} |
861 | template<typename T> __declspec(dllimport) static void staticInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
862 | template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} |
863 | #else |
864 | template<typename T> __declspec(dllimport) void normalInclass() {} |
865 | template<typename T> __declspec(dllimport) inline void normalInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
866 | template<typename T> __declspec(dllimport) static void staticInclass() {} |
867 | template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
868 | #endif |
869 | |
870 | #if __has_feature(cxx_variable_templates) |
871 | template<typename T> __declspec(dllimport) static int StaticField; |
872 | template<typename T> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} |
873 | template<typename T> __declspec(dllimport) static const int StaticConstField; |
874 | template<typename T> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} |
875 | template<typename T> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; |
876 | template<typename T> __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; |
877 | template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1; |
878 | template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} |
879 | #endif // __has_feature(cxx_variable_templates) |
880 | }; |
881 | |
882 | template<typename T> void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
883 | template<typename T> void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
884 | #ifdef GNU // dllimport was ignored above |
885 | template<typename T> void ImportMemberTmpl::normalInlineDecl() {} |
886 | template<typename T> void ImportMemberTmpl::staticInlineDecl() {} |
887 | #else // dllimport dropped here |
888 | template<typename T> void ImportMemberTmpl::normalInlineDecl() {} // expected-warning{{'ImportMemberTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
889 | template<typename T> void ImportMemberTmpl::staticInlineDecl() {} // expected-warning{{'ImportMemberTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
890 | #endif |
891 | |
892 | #ifdef GNU |
893 | template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
894 | template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
895 | #else |
896 | template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
897 | template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
898 | #endif |
899 | |
900 | #if __has_feature(cxx_variable_templates) |
901 | template<typename T> int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} |
902 | template<typename T> const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} |
903 | template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}} |
904 | #endif // __has_feature(cxx_variable_templates) |
905 | |
906 | |
907 | // Redeclarations cannot add dllimport. |
908 | struct MemTmplRedecl { |
909 | template<typename T> void normalDef(); // expected-note{{previous declaration is here}} |
910 | template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}} |
911 | template<typename T> static void staticDef(); // expected-note{{previous declaration is here}} |
912 | template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} |
913 | |
914 | #ifdef MS |
915 | // expected-note@+3{{previous declaration is here}} |
916 | // expected-note@+3{{previous declaration is here}} |
917 | #endif |
918 | template<typename T> void normalInlineDef(); |
919 | template<typename T> static void staticInlineDef(); |
920 | |
921 | #if __has_feature(cxx_variable_templates) |
922 | template<typename T> static int StaticField; // expected-note{{previous declaration is here}} |
923 | template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}} |
924 | template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} |
925 | #endif // __has_feature(cxx_variable_templates) |
926 | }; |
927 | |
928 | template<typename T> __declspec(dllimport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}} |
929 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
930 | #ifdef MS |
931 | template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}} |
932 | #else |
933 | template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
934 | #endif |
935 | template<typename T> __declspec(dllimport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} |
936 | template<typename T> __declspec(dllimport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}} |
937 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
938 | #ifdef MS |
939 | template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}} |
940 | #else |
941 | template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
942 | #endif |
943 | template<typename T> __declspec(dllimport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} |
944 | |
945 | #if __has_feature(cxx_variable_templates) |
946 | template<typename T> __declspec(dllimport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}} |
947 | // expected-error@-1{{definition of dllimport static field not allowed}} |
948 | // expected-note@-2{{attribute is here}} |
949 | template<typename T> __declspec(dllimport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}} |
950 | // expected-error@-1{{definition of dllimport static field not allowed}} |
951 | // expected-note@-2{{attribute is here}} |
952 | template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}} |
953 | // expected-error@-1{{definition of dllimport static field not allowed}} |
954 | // expected-note@-2{{attribute is here}} |
955 | #endif // __has_feature(cxx_variable_templates) |
956 | |
957 | |
958 | |
959 | struct MemFunTmpl { |
960 | template<typename T> void normalDef() {} |
961 | #ifdef GNU |
962 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
963 | #endif |
964 | template<typename T> __declspec(dllimport) void importedNormal() {} |
965 | template<typename T> static void staticDef() {} |
966 | #ifdef GNU |
967 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
968 | #endif |
969 | template<typename T> __declspec(dllimport) static void importedStatic() {} |
970 | }; |
971 | |
972 | // Import implicit instantiation of an imported member function template. |
973 | void useMemFunTmpl() { |
974 | MemFunTmpl().importedNormal<ImplicitInst_Imported>(); |
975 | MemFunTmpl().importedStatic<ImplicitInst_Imported>(); |
976 | } |
977 | |
978 | // Import explicit instantiation declaration of an imported member function |
979 | // template. |
980 | extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>(); |
981 | extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>(); |
982 | |
983 | // Import explicit instantiation definition of an imported member function |
984 | // template. |
985 | // NB: MSVC fails this instantiation without explicit dllimport. |
986 | template void MemFunTmpl::importedNormal<ExplicitInst_Imported>(); |
987 | template void MemFunTmpl::importedStatic<ExplicitInst_Imported>(); |
988 | |
989 | // Import specialization of an imported member function template. |
990 | template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>(); |
991 | template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw |
992 | #ifdef GNU |
993 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
994 | #endif |
995 | template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {} |
996 | #if 1 |
997 | // FIXME: This should not be an error when targeting MSVC. (PR21406) |
998 | // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} |
999 | #endif |
1000 | |
1001 | template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>(); |
1002 | template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw |
1003 | #ifdef GNU |
1004 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
1005 | #endif |
1006 | template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {} |
1007 | #if 1 |
1008 | // FIXME: This should not be an error when targeting MSVC. (PR21406) |
1009 | // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} |
1010 | #endif |
1011 | |
1012 | // Not importing specialization of an imported member function template without |
1013 | // explicit dllimport. |
1014 | template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {} |
1015 | template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {} |
1016 | |
1017 | |
1018 | // Import explicit instantiation declaration of a non-imported member function |
1019 | // template. |
1020 | #ifdef GNU |
1021 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
1022 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
1023 | #endif |
1024 | extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>(); |
1025 | extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>(); |
1026 | |
1027 | // Import explicit instantiation definition of a non-imported member function |
1028 | // template. |
1029 | #ifdef GNU |
1030 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
1031 | // expected-warning@+3{{'dllimport' attribute ignored on inline function}} |
1032 | #endif |
1033 | template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>(); |
1034 | template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>(); |
1035 | |
1036 | // Import specialization of a non-imported member function template. |
1037 | template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>(); |
1038 | template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw |
1039 | #ifdef GNU |
1040 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
1041 | #endif |
1042 | template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {} |
1043 | #if 1 |
1044 | // FIXME: This should not be an error when targeting MSVC. (PR21406) |
1045 | // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} |
1046 | #endif |
1047 | |
1048 | template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>(); |
1049 | template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw |
1050 | #ifdef GNU |
1051 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
1052 | #endif |
1053 | template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {} |
1054 | #if 1 |
1055 | // FIXME: This should not be an error when targeting MSVC. (PR21406) |
1056 | // expected-error@-7{{dllimport cannot be applied to non-inline function definition}} |
1057 | #endif |
1058 | |
1059 | |
1060 | |
1061 | #if __has_feature(cxx_variable_templates) |
1062 | struct MemVarTmpl { |
1063 | template<typename T> static const int StaticVar = 1; |
1064 | template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1; |
1065 | }; |
1066 | |
1067 | // Import implicit instantiation of an imported member variable template. |
1068 | int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; } |
1069 | |
1070 | // Import explicit instantiation declaration of an imported member variable |
1071 | // template. |
1072 | extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>; |
1073 | |
1074 | // An explicit instantiation definition of an imported member variable template |
1075 | // cannot be imported because the template must be defined which is illegal. The |
1076 | // in-class initializer does not count. |
1077 | |
1078 | // Import specialization of an imported member variable template. |
1079 | template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>; |
1080 | template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1; |
1081 | // expected-error@-1{{definition of dllimport static field not allowed}} |
1082 | // expected-note@-2{{attribute is here}} |
1083 | |
1084 | // Not importing specialization of a member variable template without explicit |
1085 | // dllimport. |
1086 | template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>; |
1087 | |
1088 | |
1089 | // Import explicit instantiation declaration of a non-imported member variable |
1090 | // template. |
1091 | extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>; |
1092 | |
1093 | // An explicit instantiation definition of a non-imported member variable template |
1094 | // cannot be imported because the template must be defined which is illegal. The |
1095 | // in-class initializer does not count. |
1096 | |
1097 | // Import specialization of a non-imported member variable template. |
1098 | template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>; |
1099 | template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1; |
1100 | // expected-error@-1{{definition of dllimport static field not allowed}} |
1101 | // expected-note@-2{{attribute is here}} |
1102 | |
1103 | #endif // __has_feature(cxx_variable_templates) |
1104 | |
1105 | |
1106 | |
1107 | //===----------------------------------------------------------------------===// |
1108 | // Class template members |
1109 | //===----------------------------------------------------------------------===// |
1110 | |
1111 | // Import individual members of a class template. |
1112 | template<typename T> |
1113 | struct ImportClassTmplMembers { |
1114 | __declspec(dllimport) void normalDecl(); |
1115 | #ifdef GNU |
1116 | // expected-note@+2{{previous attribute is here}} |
1117 | #endif |
1118 | __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} |
1119 | __declspec(dllimport) void normalInlineDef(); |
1120 | __declspec(dllimport) virtual void virtualDecl(); |
1121 | #ifdef GNU |
1122 | // expected-note@+2{{previous attribute is here}} |
1123 | #endif |
1124 | __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} |
1125 | __declspec(dllimport) virtual void virtualInlineDef(); |
1126 | __declspec(dllimport) static void staticDecl(); |
1127 | #ifdef GNU |
1128 | // expected-note@+2{{previous attribute is here}} |
1129 | #endif |
1130 | __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} |
1131 | __declspec(dllimport) static void staticInlineDef(); |
1132 | |
1133 | #ifdef GNU |
1134 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
1135 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
1136 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
1137 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
1138 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
1139 | // expected-warning@+7{{'dllimport' attribute ignored on inline function}} |
1140 | #endif |
1141 | __declspec(dllimport) void normalInclass() {} |
1142 | __declspec(dllimport) inline void normalInlineDecl(); |
1143 | __declspec(dllimport) virtual void virtualInclass() {} |
1144 | __declspec(dllimport) virtual inline void virtualInlineDecl(); |
1145 | __declspec(dllimport) static void staticInclass() {} |
1146 | __declspec(dllimport) static inline void staticInlineDecl(); |
1147 | |
1148 | protected: |
1149 | __declspec(dllimport) void protectedDecl(); |
1150 | private: |
1151 | __declspec(dllimport) void privateDecl(); |
1152 | public: |
1153 | |
1154 | __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}} |
1155 | __declspec(dllimport) static int StaticField; |
1156 | __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} |
1157 | __declspec(dllimport) static const int StaticConstField; |
1158 | __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} |
1159 | __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; |
1160 | __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; |
1161 | __declspec(dllimport) constexpr static int ConstexprField = 1; |
1162 | __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} |
1163 | }; |
1164 | |
1165 | // NB: MSVC is inconsistent here and disallows *InlineDef on class templates, |
1166 | // but allows it on classes. We allow both. |
1167 | #ifdef MS |
1168 | // expected-warning@+5{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
1169 | #else |
1170 | // expected-warning@+3{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1171 | #endif |
1172 | template <typename T> |
1173 | void ImportClassTmplMembers<T>::normalDef() {} |
1174 | #ifdef GNU |
1175 | // expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
1176 | #endif |
1177 | template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {} |
1178 | template<typename T> void ImportClassTmplMembers<T>::normalInlineDecl() {} |
1179 | #ifdef MS |
1180 | // expected-warning@+5{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
1181 | #else |
1182 | // expected-warning@+3{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1183 | #endif |
1184 | template <typename T> |
1185 | void ImportClassTmplMembers<T>::virtualDef() {} |
1186 | #ifdef GNU |
1187 | // expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
1188 | #endif |
1189 | template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {} |
1190 | template<typename T> void ImportClassTmplMembers<T>::virtualInlineDecl() {} |
1191 | #ifdef MS |
1192 | // expected-warning@+5{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} |
1193 | #else |
1194 | // expected-warning@+3{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1195 | #endif |
1196 | template <typename T> |
1197 | void ImportClassTmplMembers<T>::staticDef() {} |
1198 | #ifdef GNU |
1199 | // expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
1200 | #endif |
1201 | template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {} |
1202 | template<typename T> void ImportClassTmplMembers<T>::staticInlineDecl() {} |
1203 | |
1204 | template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}} |
1205 | template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} |
1206 | template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}} |
1207 | |
1208 | |
1209 | // Redeclarations cannot add dllimport. |
1210 | template<typename T> |
1211 | struct CTMR /*ClassTmplMemberRedecl*/ { |
1212 | void normalDef(); // expected-note{{previous declaration is here}} |
1213 | inline void normalInlineDecl(); // expected-note{{previous declaration is here}} |
1214 | virtual void virtualDef(); // expected-note{{previous declaration is here}} |
1215 | virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} |
1216 | static void staticDef(); // expected-note{{previous declaration is here}} |
1217 | static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} |
1218 | |
1219 | #ifdef MS |
1220 | // expected-note@+4{{previous declaration is here}} |
1221 | // expected-note@+4{{previous declaration is here}} |
1222 | // expected-note@+4{{previous declaration is here}} |
1223 | #endif |
1224 | void normalInlineDef(); |
1225 | virtual void virtualInlineDef(); |
1226 | static void staticInlineDef(); |
1227 | |
1228 | static int StaticField; // expected-note{{previous declaration is here}} |
1229 | static const int StaticConstField; // expected-note{{previous declaration is here}} |
1230 | constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} |
1231 | }; |
1232 | |
1233 | template<typename T> __declspec(dllimport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}} |
1234 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
1235 | template<typename T> __declspec(dllimport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}} |
1236 | template<typename T> __declspec(dllimport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}} |
1237 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
1238 | template<typename T> __declspec(dllimport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}} |
1239 | template<typename T> __declspec(dllimport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}} |
1240 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
1241 | template<typename T> __declspec(dllimport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}} |
1242 | |
1243 | #ifdef MS |
1244 | template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}} |
1245 | template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}} |
1246 | template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}} |
1247 | #else |
1248 | template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
1249 | template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
1250 | template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
1251 | #endif |
1252 | |
1253 | template<typename T> __declspec(dllimport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}} |
1254 | // expected-warning@-1{{definition of dllimport static field}} |
1255 | // expected-note@-2{{attribute is here}} |
1256 | template<typename T> __declspec(dllimport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}} |
1257 | // expected-warning@-1{{definition of dllimport static field}} |
1258 | // expected-note@-2{{attribute is here}} |
1259 | template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}} |
1260 | // expected-warning@-1{{definition of dllimport static field}} |
1261 | // expected-note@-2{{attribute is here}} |
1262 | |
1263 | |
1264 | |
1265 | //===----------------------------------------------------------------------===// |
1266 | // Class template member templates |
1267 | //===----------------------------------------------------------------------===// |
1268 | |
1269 | template<typename T> |
1270 | struct ImportClsTmplMemTmpl { |
1271 | template<typename U> __declspec(dllimport) void normalDecl(); |
1272 | template<typename U> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
1273 | #ifdef MS |
1274 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
1275 | #endif |
1276 | template<typename U> __declspec(dllimport) void normalInlineDef(); |
1277 | template<typename U> __declspec(dllimport) static void staticDecl(); |
1278 | template<typename U> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} |
1279 | #ifdef MS |
1280 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
1281 | #endif |
1282 | template<typename U> __declspec(dllimport) static void staticInlineDef(); |
1283 | |
1284 | #ifdef GNU |
1285 | // expected-warning@+5{{'dllimport' attribute ignored on inline function}} |
1286 | // expected-warning@+8{{'dllimport' attribute ignored on inline function}} |
1287 | // expected-warning@+8{{'dllimport' attribute ignored on inline function}} |
1288 | // expected-warning@+11{{'dllimport' attribute ignored on inline function}} |
1289 | #endif |
1290 | template<typename U> __declspec(dllimport) void normalInclass() {} |
1291 | #ifdef MS |
1292 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
1293 | #endif |
1294 | template<typename U> __declspec(dllimport) inline void normalInlineDecl(); |
1295 | template<typename U> __declspec(dllimport) static void staticInclass() {} |
1296 | #ifdef MS |
1297 | // expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} |
1298 | #endif |
1299 | template<typename U> __declspec(dllimport) static inline void staticInlineDecl(); |
1300 | |
1301 | #if __has_feature(cxx_variable_templates) |
1302 | template<typename U> __declspec(dllimport) static int StaticField; |
1303 | template<typename U> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} |
1304 | template<typename U> __declspec(dllimport) static const int StaticConstField; |
1305 | template<typename U> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} |
1306 | template<typename U> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; |
1307 | template<typename U> __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; |
1308 | template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1; |
1309 | template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} |
1310 | #endif // __has_feature(cxx_variable_templates) |
1311 | }; |
1312 | |
1313 | template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1314 | template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1315 | #ifdef GNU |
1316 | template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} |
1317 | template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} |
1318 | #else |
1319 | template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1320 | template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1321 | #endif |
1322 | |
1323 | #ifdef GNU |
1324 | template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
1325 | template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} |
1326 | #else |
1327 | template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1328 | template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} |
1329 | #endif |
1330 | |
1331 | #if __has_feature(cxx_variable_templates) |
1332 | template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}} |
1333 | template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} |
1334 | template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}} |
1335 | #endif // __has_feature(cxx_variable_templates) |
1336 | |
1337 | |
1338 | // Redeclarations cannot add dllimport. |
1339 | template<typename T> |
1340 | struct CTMTR /*ClassTmplMemberTmplRedecl*/ { |
1341 | template<typename U> void normalDef(); // expected-note{{previous declaration is here}} |
1342 | template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}} |
1343 | template<typename U> static void staticDef(); // expected-note{{previous declaration is here}} |
1344 | template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} |
1345 | |
1346 | #ifdef MS |
1347 | // expected-note@+3{{previous declaration is here}} |
1348 | // expected-note@+3{{previous declaration is here}} |
1349 | #endif |
1350 | template<typename U> void normalInlineDef(); |
1351 | template<typename U> static void staticInlineDef(); |
1352 | |
1353 | #if __has_feature(cxx_variable_templates) |
1354 | template<typename U> static int StaticField; // expected-note{{previous declaration is here}} |
1355 | template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}} |
1356 | template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} |
1357 | #endif // __has_feature(cxx_variable_templates) |
1358 | }; |
1359 | |
1360 | template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}} |
1361 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
1362 | template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}} |
1363 | template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}} |
1364 | // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} |
1365 | template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}} |
1366 | |
1367 | #ifdef MS |
1368 | template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}} |
1369 | template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}} |
1370 | #else |
1371 | template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
1372 | template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} |
1373 | #endif |
1374 | |
1375 | #if __has_feature(cxx_variable_templates) |
1376 | template<typename T> template<typename U> __declspec(dllimport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}} |
1377 | // expected-warning@-1{{definition of dllimport static field}} |
1378 | // expected-note@-2{{attribute is here}} |
1379 | template<typename T> template<typename U> __declspec(dllimport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}} |
1380 | // expected-warning@-1{{definition of dllimport static field}} |
1381 | // expected-note@-2{{attribute is here}} |
1382 | template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}} |
1383 | // expected-warning@-1{{definition of dllimport static field}} |
1384 | // expected-note@-2{{attribute is here}} |
1385 | #endif // __has_feature(cxx_variable_templates) |
1386 | |
1387 | |
1388 | |
1389 | //===----------------------------------------------------------------------===// |
1390 | // Classes |
1391 | //===----------------------------------------------------------------------===// |
1392 | |
1393 | namespace { |
1394 | struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}} |
1395 | } |
1396 | |
1397 | class __declspec(dllimport) ClassDecl; |
1398 | |
1399 | class __declspec(dllimport) ClassDef { }; |
1400 | |
1401 | template <typename T> class ClassTemplate {}; |
1402 | |
1403 | #ifdef MS |
1404 | // expected-note@+5{{previous attribute is here}} |
1405 | // expected-note@+4{{previous attribute is here}} |
1406 | // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}} |
1407 | // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}} |
1408 | #endif |
1409 | class __declspec(dllimport) ImportClassWithDllMember { |
1410 | void __declspec(dllexport) foo(); |
1411 | void __declspec(dllimport) bar(); |
1412 | }; |
1413 | |
1414 | #ifdef MS |
1415 | // expected-note@+5{{previous attribute is here}} |
1416 | // expected-note@+4{{previous attribute is here}} |
1417 | // expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}} |
1418 | // expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}} |
1419 | #endif |
1420 | template <typename T> class __declspec(dllexport) ExportClassWithDllMember { |
1421 | void __declspec(dllimport) foo(); |
1422 | void __declspec(dllexport) bar(); |
1423 | }; |
1424 | |
1425 | namespace ImportedExplicitSpecialization { |
1426 | template <typename T> struct S { static int x; }; |
1427 | template <typename T> int S<T>::x = sizeof(T); |
1428 | template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}} |
1429 | int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}} |
1430 | } |
1431 | |
1432 | namespace PR19988 { |
1433 | // Don't error about applying delete to dllimport member function when instantiating. |
1434 | template <typename> struct __declspec(dllimport) S { |
1435 | void foo() = delete; |
1436 | }; |
1437 | S<int> s; |
1438 | } |
1439 | |
1440 | #ifdef MS |
1441 | // expected-warning@+3{{'dllimport' attribute ignored}} |
1442 | #endif |
1443 | template <typename T> struct PartiallySpecializedClassTemplate {}; |
1444 | template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} }; |
1445 | |
1446 | template <typename T> struct ExpliciallySpecializedClassTemplate {}; |
1447 | template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} }; |
1448 | |
1449 | |
1450 | //===----------------------------------------------------------------------===// |
1451 | // Classes with template base classes |
1452 | //===----------------------------------------------------------------------===// |
1453 | |
1454 | template <typename T> class __declspec(dllexport) ExportedClassTemplate {}; |
1455 | |
1456 | template <typename T> class __declspec(dllimport) ImportedClassTemplate {}; |
1457 | |
1458 | // ClassTemplate<int> gets imported. |
1459 | class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {}; |
1460 | |
1461 | // ClassTemplate<int> is already imported. |
1462 | class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {}; |
1463 | |
1464 | // ImportedClassTemplate is expliitly imported. |
1465 | class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {}; |
1466 | |
1467 | // ExportedClassTemplate is explicitly exported. |
1468 | class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {}; |
1469 | |
1470 | class DerivedFromTemplateD : public ClassTemplate<double> {}; |
1471 | // Base class previously implicitly instantiated without attribute; it will get propagated. |
1472 | class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {}; |
1473 | |
1474 | // Base class has explicit instantiation declaration; the attribute will get propagated. |
1475 | extern template class ClassTemplate<float>; |
1476 | class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {}; |
1477 | |
1478 | class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {}; |
1479 | // The second derived class doesn't change anything, the attribute that was propagated first wins. |
1480 | class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {}; |
1481 | |
1482 | template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; |
1483 | #ifdef MS |
1484 | // expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}} |
1485 | #endif |
1486 | template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; |
1487 | template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; |
1488 | template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; |
1489 | template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; |
1490 | template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} }; |
1491 | |
1492 | template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; |
1493 | #ifdef MS |
1494 | // expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}} |
1495 | #endif |
1496 | template struct ExplicitlyInstantiatedTemplate<int>; |
1497 | template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; |
1498 | template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; |
1499 | template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} }; |
1500 | template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; |
1501 | |
1502 | #ifdef MS |
1503 | // expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}} |
1504 | // expected-note@+2{{attribute is here}} |
1505 | #endif |
1506 | struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; |
1507 | |
1508 | // Base class already specialized with export attribute. |
1509 | struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; |
1510 | |
1511 | // Base class already specialized with import attribute. |
1512 | struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; |
1513 | |
1514 | #ifdef MS |
1515 | // expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} |
1516 | // expected-note@+2{{attribute is here}} |
1517 | #endif |
1518 | struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {}; |
1519 | |
1520 | // Base class already instantiated with export attribute. |
1521 | struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {}; |
1522 | |
1523 | // Base class already instantiated with import attribute. |
1524 | struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {}; |
1525 | |
1526 | template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} }; |
1527 | extern template struct ExplicitInstantiationDeclTemplateBase<int>; |
1528 | struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {}; |
1529 | |
1530 | //===----------------------------------------------------------------------===// |
1531 | // Lambdas |
1532 | //===----------------------------------------------------------------------===// |
1533 | // The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported. |
1534 | #ifdef MS |
1535 | // expected-error@+4{{lambda cannot be declared 'dllimport'}} |
1536 | #else |
1537 | // expected-warning@+2{{'dllimport' attribute ignored on inline function}} |
1538 | #endif |
1539 | auto Lambda = []() __declspec(dllimport) -> bool { return true; }; |
1540 | |