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