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