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