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