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