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