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