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