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.
7struct ImplicitInst_Imported {};
8struct ExplicitDecl_Imported {};
9struct ExplicitInst_Imported {};
10struct ExplicitSpec_Imported {};
11struct ExplicitSpec_Def_Imported {};
12struct ExplicitSpec_InlineDef_Imported {};
13struct ExplicitSpec_NotImported {};
14namespace { struct Internal {}; }
15
16
17// Invalid usage.
18__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
19typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
20typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
21typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
22enum __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;
38int **__attribute__((dllimport))* GlobalDeclChunkAttr;
39int 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}}
44int __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
56int 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
67int GlobalDeclInit = 1;
68
69#ifdef GNU
70// expected-note@+2{{previous attribute is here}}
71#endif
72int *__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
78int *GlobalDeclChunkAttrInit = 0;
79
80#ifdef GNU
81// expected-note@+2{{previous attribute is here}}
82#endif
83int 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
89int 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
98int *__attribute__((dllimport)) GlobalRedecl2b;
99int *__attribute__((dllimport)) GlobalRedecl2b;
100
101int GlobalRedecl2c __attribute__((dllimport));
102int 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
110extern "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'}}
118namespace    { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
119namespace 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
128inline 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}}
137void 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.
157template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
158
159// dllimport implies a declaration.
160template<typename T> __declspec(dllimport) int VarTmplDecl;
161
162// Not allowed on definitions.
163template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
164template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
165template<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
171template <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
178template <typename T>
179int ExternVarTmplDeclInit = 1;
180
181#ifdef GNU
182// expected-note@+3{{previous attribute is here}}
183#endif
184template <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
191template <typename T>
192int VarTmplDeclInit = 1;
193
194// Redeclarations
195template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
196template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
197
198template<typename T> __declspec(dllimport) int VarTmplRedecl2;
199template<typename T> __declspec(dllimport) int VarTmplRedecl2;
200
201template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
202template<typename T>                       extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
203
204template<typename T>                       extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
205template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
206
207// External linkage is required.
208template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
209template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
210namespace    { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
211namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
212
213template<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
216template<typename T> int VarTmpl;
217template<typename T> __declspec(dllimport) int ImportedVarTmpl;
218
219// Import implicit instantiation of an imported variable template.
220int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
221
222// Import explicit instantiation declaration of an imported variable template.
223extern 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.
229template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
230template<> __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.
234template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
235
236
237// Import explicit instantiation declaration of a non-imported variable template.
238extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
239
240// Import explicit instantiation definition of a non-imported variable template.
241template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
242
243// Import specialization of a non-imported variable template.
244template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
245template<> __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
258void __attribute__((dllimport)) decl2A();
259void __declspec(dllimport)      decl2B();
260
261// Not allowed on function definitions.
262__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
263
264// extern  "C"
265extern "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
272__declspec(dllimport) inline void inlineFunc1() {}
273inline 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();
279                             void inlineDecl() {}
280
281__declspec(dllimport) void inlineDef();
282#ifdef GNU
283// expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}}
284#endif
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
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
309extern "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}}
316__declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}}
317#else
318                      void redecl6();
319__declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
320#endif
321
322// Friend functions
323struct 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
343                      void friend3() {}
344__declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}}
345#ifdef MS
346__declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}}
347#else
348__declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
349#endif
350
351
352void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
353void __declspec(dllimport) friend7();
354struct 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'}}
365namespace    { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
366namespace 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.
386template<typename T> __declspec(dllimport) void funcTmplDecl1();
387template<typename T> void __declspec(dllimport) funcTmplDecl2();
388
389// Import function template definition.
390template<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
399template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
400template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
401
402template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
403template<typename T>                              void inlineFuncTmplDecl() {}
404
405template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
406template<typename T>                inline void inlineFuncTmplDef() {}
407
408// Redeclarations
409template<typename T> __declspec(dllimport) void funcTmplRedecl1();
410template<typename T> __declspec(dllimport) void funcTmplRedecl1();
411
412template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
413template<typename T>                       void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
414
415template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
416template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
417
418template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
419template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
420
421#ifdef MS
422template<typename T>                       void funcTmplRedecl5(); // expected-note{{previous declaration is here}}
423template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
424#endif
425
426// Function template friends
427struct 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};
437template<typename T> __declspec(dllimport) void funcTmplFriend1();
438template<typename T>                       void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
439template<typename T>                       void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
440template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
441template<typename T>                       inline void funcTmplFriend5() {}
442
443// External linkage is required.
444template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
445template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
446namespace    { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
447namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
448
449
450template<typename T> void funcTmpl() {}
451template<typename T> inline void inlineFuncTmpl() {}
452template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
453#ifdef GNU
454// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
455#endif
456template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
457
458// Import implicit instantiation of an imported function template.
459void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }
460void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }
461
462// Import explicit instantiation declaration of an imported function template.
463extern 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.
468template void importedFuncTmpl<ExplicitInst_Imported>();
469
470// Import specialization of an imported function template. A definition must be
471// declared inline.
472template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
473template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
474#ifdef MS
475template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
476#endif
477
478// Not importing specialization of an imported function template without
479// explicit dllimport.
480template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
481
482
483// Import explicit instantiation declaration of a non-imported function template.
484extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
485#ifdef GNU
486// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
487#endif
488extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
489
490// Import explicit instantiation definition of a non-imported function template.
491template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
492#ifdef GNU
493// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
494#endif
495template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
496
497// Import specialization of a non-imported function template. A definition must
498// be declared inline.
499template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
500template<> __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
504template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
505
506
507//===----------------------------------------------------------------------===//
508// Class members
509//===----------------------------------------------------------------------===//
510
511// Import individual members of a class.
512struct 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}}
528  __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}}
538  __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}}
548  __declspec(dllimport) static         void staticInclass() {}
549  __declspec(dllimport) static         void staticInlineDef();
550  __declspec(dllimport) static  inline void staticInlineDecl();
551
552protected:
553  __declspec(dllimport)                void protectedDecl();
554private:
555  __declspec(dllimport)                void privateDecl();
556public:
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
574void 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
580void ImportMembers::normalDef() {}
581#ifdef GNU
582// expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
583#endif
584inline void ImportMembers::normalInlineDef() {}
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
591       void ImportMembers::virtualDef() {}
592#ifdef GNU
593// expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
594#endif
595inline void ImportMembers::virtualInlineDef() {}
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
602       void ImportMembers::staticDef() {}
603#ifdef GNU
604// expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
605#endif
606inline void ImportMembers::staticInlineDef() {}
607       void ImportMembers::staticInlineDecl() {}
608
609       int  ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
610const  int  ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
611constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
612
613
614// Import on member definitions.
615struct 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
633__declspec(dllimport)        void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
634__declspec(dllimport)        void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
635__declspec(dllimport)        void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
636#ifdef MS
637__declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {}
638__declspec(dllimport)        void ImportMemberDefs::normalInlineDecl() {}
639__declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {}
640__declspec(dllimport)        void ImportMemberDefs::virtualInlineDecl() {}
641__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
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.
651struct 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.
662struct 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.
684struct 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.
693struct 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.
712struct 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.
742ImportDefaultedDefs::~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;
750inline 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
758ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default;
759
760// Redeclarations cannot add dllimport.
761struct 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
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}}
785__declspec(dllimport)        void MemberRedecl::normalInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
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}}
788__declspec(dllimport)        void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}
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}}
791__declspec(dllimport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
792
793#ifdef MS
794__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
795__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}
796__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
797#else
798__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
799__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
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
821struct 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
835  template<typename T> __declspec(dllimport)               void normalInclass() {}
836  template<typename T> __declspec(dllimport)        inline void normalInlineDecl();
837  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
852template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
853template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
854template<typename T>        void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
855template<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
861template<typename T> inline void ImportMemberTmpl::normalInlineDef() {}
862template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
863
864#if __has_feature(cxx_variable_templates)
865template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
866template<typename T> const  int  ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
867template<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.
872struct 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
892template<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
895template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
896#else
897template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
898#endif
899template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
900template<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
903template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
904#else
905template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
906#endif
907template<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)
910template<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}}
913template<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}}
916template<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
923struct MemFunTmpl {
924  template<typename T>                              void normalDef() {}
925#ifdef GNU
926  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
927#endif
928  template<typename T> __declspec(dllimport)        void importedNormal() {}
929  template<typename T>                       static void staticDef() {}
930#ifdef GNU
931  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
932#endif
933  template<typename T> __declspec(dllimport) static void importedStatic() {}
934};
935
936// Import implicit instantiation of an imported member function template.
937void 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.
944extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
945extern 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.
950template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
951template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
952
953// Import specialization of an imported member function template.
954template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
955template<> __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
959template<> __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
965template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
966template<> __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
970template<> __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.
978template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
979template<> 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
988extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
989extern 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
997template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
998template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
999
1000// Import specialization of a non-imported member function template.
1001template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
1002template<> __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
1006template<> __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
1012template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
1013template<> __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
1017template<> __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)
1026struct 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.
1032int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
1033
1034// Import explicit instantiation declaration of an imported member variable
1035// template.
1036extern 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.
1043template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
1044template<> __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.
1050template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
1051
1052
1053// Import explicit instantiation declaration of a non-imported member variable
1054// template.
1055extern 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.
1062template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
1063template<> __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.
1076template<typename T>
1077struct 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
1105  __declspec(dllimport)                void normalInclass() {}
1106  __declspec(dllimport)         inline void normalInlineDecl();
1107  __declspec(dllimport) virtual        void virtualInclass() {}
1108  __declspec(dllimport) virtual inline void virtualInlineDecl();
1109  __declspec(dllimport) static         void staticInclass() {}
1110  __declspec(dllimport) static  inline void staticInlineDecl();
1111
1112protected:
1113  __declspec(dllimport)                void protectedDecl();
1114private:
1115  __declspec(dllimport)                void privateDecl();
1116public:
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
1136template <typename T>
1137void ImportClassTmplMembers<T>::normalDef() {}
1138#ifdef GNU
1139// expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1140#endif
1141template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}
1142template<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
1148template <typename T>
1149void ImportClassTmplMembers<T>::virtualDef() {}
1150#ifdef GNU
1151// expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1152#endif
1153template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}
1154template<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
1160template <typename T>
1161void ImportClassTmplMembers<T>::staticDef() {}
1162#ifdef GNU
1163// expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
1164#endif
1165template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
1166template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() {}
1167
1168template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
1169template<typename T> const  int  ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
1170template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
1171
1172
1173// Redeclarations cannot add dllimport.
1174template<typename T>
1175struct 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
1197template<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}}
1199template<typename T> __declspec(dllimport)        void CTMR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
1200template<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}}
1202template<typename T> __declspec(dllimport)        void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
1203template<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}}
1205template<typename T> __declspec(dllimport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
1206
1207#ifdef MS
1208template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
1209template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
1210template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
1211#else
1212template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1213template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
1214template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1215#endif
1216
1217template<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}}
1220template<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}}
1223template<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
1233template<typename T>
1234struct 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
1248  template<typename U> __declspec(dllimport)               void normalInclass() {}
1249  template<typename U> __declspec(dllimport)        inline void normalInlineDecl();
1250  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
1265template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1266template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
1267template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
1268template<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
1274template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {}
1275template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
1276
1277#if __has_feature(cxx_variable_templates)
1278template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
1279template<typename T> template<typename U> const  int  ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
1280template<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.
1285template<typename T>
1286struct 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
1306template<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}}
1308template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
1309template<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}}
1311template<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
1314template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
1315template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
1316#else
1317template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
1318template<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)
1322template<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}}
1325template<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}}
1328template<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
1339namespace {
1340  struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}}
1341}
1342
1343class __declspec(dllimport) ClassDecl;
1344
1345class __declspec(dllimport) ClassDef { };
1346
1347template <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
1355class __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
1366template <typename T> class __declspec(dllexport) ExportClassWithDllMember {
1367  void __declspec(dllimport) foo();
1368  void __declspec(dllexport) bar();
1369};
1370
1371namespace ImportedExplicitSpecialization {
1372template <typename T> struct S { static int x; };
1373template <typename T> int S<T>::x = sizeof(T);
1374template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
1375int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
1376}
1377
1378namespace PR19988 {
1379// Don't error about applying delete to dllimport member function when instantiating.
1380template <typename> struct __declspec(dllimport) S {
1381  void foo() = delete;
1382};
1383S<int> s;
1384}
1385
1386#ifdef MS
1387// expected-warning@+3{{'dllimport' attribute ignored}}
1388#endif
1389template <typename T> struct PartiallySpecializedClassTemplate {};
1390template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
1391
1392template <typename T> struct ExpliciallySpecializedClassTemplate {};
1393template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
1394
1395
1396//===----------------------------------------------------------------------===//
1397// Classes with template base classes
1398//===----------------------------------------------------------------------===//
1399
1400template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
1401
1402template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
1403
1404// ClassTemplate<int> gets imported.
1405class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
1406
1407// ClassTemplate<int> is already imported.
1408class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
1409
1410// ImportedClassTemplate is expliitly imported.
1411class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
1412
1413// ExportedClassTemplate is explicitly exported.
1414class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
1415
1416class DerivedFromTemplateD : public ClassTemplate<double> {};
1417// Base class previously implicitly instantiated without attribute; it will get propagated.
1418class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
1419
1420// Base class has explicit instantiation declaration; the attribute will get propagated.
1421extern template class ClassTemplate<float>;
1422class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {};
1423
1424class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
1425// The second derived class doesn't change anything, the attribute that was propagated first wins.
1426class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
1427
1428template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
1429#ifdef MS
1430// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
1431#endif
1432template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
1433template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
1434template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
1435template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
1436template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
1437
1438template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
1439#ifdef MS
1440// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
1441#endif
1442template struct ExplicitlyInstantiatedTemplate<int>;
1443template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
1444template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
1445template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
1446template 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
1452struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
1453
1454// Base class already specialized with export attribute.
1455struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
1456
1457// Base class already specialized with import attribute.
1458struct __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
1464struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
1465
1466// Base class already instantiated with export attribute.
1467struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
1468
1469// Base class already instantiated with import attribute.
1470struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
1471
1472template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
1473extern template struct ExplicitInstantiationDeclTemplateBase<int>;
1474struct __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
1485auto Lambda = []() __declspec(dllimport) -> bool { return true; };
1486