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