Clang Project

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