1636 lines · cpp
1// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DMS %s2// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s3// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s4// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s5// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DGNU %s6// RUN: %clang_cc1 -triple i686-pc-cygwin -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s7// RUN: %clang_cc1 -triple x86_64-pc-cygwin -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s8// RUN: %clang_cc1 -triple x86_64-pc-cygwin -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DGNU %s9// RUN: %clang_cc1 -triple i686-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DWI %s10// RUN: %clang_cc1 -triple x86_64-windows-itanium -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DWI %s11// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++11 -Wunsupported-dll-base-class-template -DPS %s12// RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DPS %s13// RUN: %clang_cc1 -triple x86_64-sie-ps5 -fsyntax-only -fdeclspec -verify -std=c++17 -Wunsupported-dll-base-class-template -DPS %s14 15// Helper structs to make templates more expressive.16struct ImplicitInst_Imported {};17struct ExplicitDecl_Imported {};18struct ExplicitInst_Imported {};19struct ExplicitSpec_Imported {};20struct ExplicitSpec_Def_Imported {};21struct ExplicitSpec_InlineDef_Imported {};22struct ExplicitSpec_NotImported {};23namespace { struct Internal {}; }24 25 26// Invalid usage.27__declspec(dllimport) typedef int typedef1;28// expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}}29typedef __declspec(dllimport) int typedef2;30// expected-warning@-1{{'dllimport' attribute only applies to}}31typedef int __declspec(dllimport) typedef3;32// expected-warning@-1{{'dllimport' attribute only applies to}}33typedef __declspec(dllimport) void (*FunTy)();34// expected-warning@-1{{'dllimport' attribute only applies to}}35enum __declspec(dllimport) Enum {};36// expected-warning@-1{{'dllimport' attribute only applies to}}37#if __has_feature(cxx_strong_enums)38enum class __declspec(dllimport) EnumClass {};39// expected-warning@-1{{'dllimport' attribute only applies to}}40#endif41 42 43 44//===----------------------------------------------------------------------===//45// Globals46//===----------------------------------------------------------------------===//47 48// Import declaration.49__declspec(dllimport) extern int ExternGlobalDecl;50 51// dllimport implies a declaration.52__declspec(dllimport) int GlobalDecl;53int **__attribute__((dllimport))* GlobalDeclChunkAttr;54int GlobalDeclAttr __attribute__((dllimport));55 56// Not allowed on definitions.57__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}58__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}59int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}60 61// Declare, then reject definition.62#ifdef GNU63// expected-note@+2{{previous attribute is here}}64#endif65__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}}66#if defined(MS) || defined(WI) || defined(PS)67// expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}68#else69// expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}70#endif71int ExternGlobalDeclInit = 1;72 73#ifdef GNU74// expected-note@+2{{previous attribute is here}}75#endif76__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}}77#if defined(MS) || defined(WI) || defined(PS)78// expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}79#else80// expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}81#endif82int GlobalDeclInit = 1;83 84#ifdef GNU85// expected-note@+2{{previous attribute is here}}86#endif87int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}}88#if defined(MS) || defined(WI) || defined(PS)89// expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}90#else91// expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}92#endif93int *GlobalDeclChunkAttrInit = 0;94 95#ifdef GNU96// expected-note@+2{{previous attribute is here}}97#endif98int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}}99#if defined(MS) || defined(WI) || defined(PS)100// expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}101#else102// expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}103#endif104int GlobalDeclAttrInit = 1;105 106// Redeclarations107__declspec(dllimport) extern int GlobalRedecl1;108__declspec(dllimport) extern int GlobalRedecl1;109 110__declspec(dllimport) int GlobalRedecl2a;111__declspec(dllimport) int GlobalRedecl2a;112 113int *__attribute__((dllimport)) GlobalRedecl2b;114int *__attribute__((dllimport)) GlobalRedecl2b;115 116int GlobalRedecl2c __attribute__((dllimport));117int GlobalRedecl2c __attribute__((dllimport));118 119__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}120 extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}121 122 extern int GlobalRedecl4; // expected-note{{previous declaration is here}}123__declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}}124 125extern "C" {126 extern int GlobalRedecl5; // expected-note{{previous declaration is here}}127__declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}}128}129 130// External linkage is required.131__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}132__declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}133#ifndef MS134namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}135#endif136namespace ns { __declspec(dllimport) int ExternalGlobal; }137 138__declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}139 // expected-error@-1{{definition of dllimport data}}140 141// Thread local variables are invalid.142__declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}143// This doesn't work on MinGW, because there, dllimport on the inline function is ignored.144#ifndef GNU145inline void __declspec(dllimport) ImportedInlineWithThreadLocal() {146 static __thread int OK; // no-error147}148#endif149 150// Import in local scope.151__declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}}152__declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}}153__declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}}154void functionScope() {155 __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}}156 int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}157 int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}}158 159 __declspec(dllimport) int LocalVarDecl;160 __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}}161 __declspec(dllimport) extern int ExternLocalVarDecl;162 __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}163 __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}164}165 166 167 168//===----------------------------------------------------------------------===//169// Variable templates170//===----------------------------------------------------------------------===//171#if __has_feature(cxx_variable_templates)172 173// Import declaration.174template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;175 176// dllimport implies a declaration.177template<typename T> __declspec(dllimport) int VarTmplDecl;178 179// Not allowed on definitions.180template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}181template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}182template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}}183 184// Declare, then reject definition.185#ifdef GNU186// expected-note@+3{{previous attribute is here}}187#endif188template <typename T>189__declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}}190#if defined(MS) || defined(WI) || defined(PS)191// expected-warning@+5{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}192#else193// expected-warning@+3{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}194#endif195template <typename T>196int ExternVarTmplDeclInit = 1;197 198#ifdef GNU199// expected-note@+3{{previous attribute is here}}200#endif201template <typename T>202__declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}}203#if defined(MS) || defined(WI) || defined(PS)204// expected-warning@+5{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}205#else206// expected-warning@+3{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}207#endif208template <typename T>209int VarTmplDeclInit = 1;210 211// Redeclarations212template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;213template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;214 215template<typename T> __declspec(dllimport) int VarTmplRedecl2;216template<typename T> __declspec(dllimport) int VarTmplRedecl2;217 218template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}219template<typename T> extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}220 221template<typename T> extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}222template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}223 224// External linkage is required.225template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}226template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}227#ifndef MS228namespace { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}229#endif230namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }231 232template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}233 234 235template<typename T> int VarTmpl;236template<typename T> __declspec(dllimport) int ImportedVarTmpl;237 238// Import implicit instantiation of an imported variable template.239int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }240 241// Import explicit instantiation declaration of an imported variable template.242extern template int ImportedVarTmpl<ExplicitDecl_Imported>;243 244// An explicit instantiation definition of an imported variable template cannot245// be imported because the template must be defined which is illegal.246 247// Import specialization of an imported variable template.248template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;249template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}250 251// Not importing specialization of an imported variable template without252// explicit dllimport.253template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;254 255 256// Import explicit instantiation declaration of a non-imported variable template.257extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;258 259// Import explicit instantiation definition of a non-imported variable template.260template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;261 262// Import specialization of a non-imported variable template.263template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;264template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}265 266#endif // __has_feature(cxx_variable_templates)267 268 269//===----------------------------------------------------------------------===//270// Functions271//===----------------------------------------------------------------------===//272 273// Import function declaration. Check different placements.274__attribute__((dllimport)) void decl1A(); // Validation check with __attribute__275__declspec(dllimport) void decl1B();276 277void __attribute__((dllimport)) decl2A();278void __declspec(dllimport) decl2B();279 280// Not allowed on function definitions.281__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}282 283// extern "C"284extern "C" __declspec(dllimport) void externC();285 286// Import inline function.287#ifdef GNU288// expected-warning@+3{{'dllimport' attribute ignored on inline function}}289// expected-warning@+3{{'dllimport' attribute ignored on inline function}}290#endif291__declspec(dllimport) inline void inlineFunc1() {}292inline void __attribute__((dllimport)) inlineFunc2() {}293 294#ifdef GNU295// expected-warning@+2{{'dllimport' attribute ignored on inline function}}296#endif297__declspec(dllimport) inline void inlineDecl();298 void inlineDecl() {}299 300__declspec(dllimport) void inlineDef();301#ifdef GNU302// expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}}303#endif304 inline void inlineDef() {}305 306// Redeclarations307__declspec(dllimport) void redecl1();308__declspec(dllimport) void redecl1();309 310__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}311 void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}312 313#ifdef GNU314 // expected-note@+2{{previous attribute is here}}315#endif316 __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}}317 // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport.318#if defined(MS) || defined(WI) || defined(PS)319 // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}320#else321 // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}322#endif323 void redecl3() {}324 325 void redecl4(); // expected-note{{previous declaration is here}}326__declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}}327 328extern "C" {329 void redecl5(); // expected-note{{previous declaration is here}}330__declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}331}332 333#if defined(MS) || defined(WI) || defined(PS)334 void redecl6(); // expected-note{{previous declaration is here}}335__declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}}336#else337 void redecl6();338__declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}}339#endif340 341// Friend functions342struct FuncFriend {343 friend __declspec(dllimport) void friend1();344 friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}345#ifdef GNU346// expected-note@+2{{previous attribute is here}}347#endif348 friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}}349 friend void friend4(); // expected-note{{previous declaration is here}}350#if defined(MS) || defined(WI) || defined(PS)351// expected-note@+2{{previous declaration is here}}352#endif353 friend void friend5();354};355__declspec(dllimport) void friend1();356 void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}357#if defined(MS) || defined(WI) || defined(PS)358 // expected-warning@+4{{'friend3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}359#else360 // expected-warning@+2{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}361#endif362 void friend3() {}363__declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}}364#if defined(MS) || defined(WI) || defined(PS)365__declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}}366#else367__declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}}368#endif369 370 371void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}372void __declspec(dllimport) friend7();373struct FuncFriend2 {374 friend void friend6(); // expected-warning{{'friend6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}375 friend void ::friend7();376};377 378// Implicit declarations can be redeclared with dllimport.379__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);380 381// External linkage is required.382__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}383__declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}384namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}385namespace ns { __declspec(dllimport) void externalFunc(); }386 387// Import deleted functions.388// FIXME: Deleted functions are definitions so a missing inline is diagnosed389// here which is irrelevant. But because the delete keyword is parsed later390// there is currently no straight-forward way to avoid this diagnostic.391__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}}392#if defined(MS) || defined(WI) || defined(PS)393__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}394#else395__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}396#endif397 398 399 400//===----------------------------------------------------------------------===//401// Function templates402//===----------------------------------------------------------------------===//403 404// Import function template declaration. Check different placements.405template<typename T> __declspec(dllimport) void funcTmplDecl1();406template<typename T> void __declspec(dllimport) funcTmplDecl2();407 408// Import function template definition.409template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}410 411// Import inline function template.412#ifdef GNU // MinGW always ignores dllimport on inline functions.413 414template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} // expected-warning{{'dllimport' attribute ignored on inline function}}415template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} // expected-warning{{'dllimport' attribute ignored on inline function}}416 417template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}418template<typename T> void inlineFuncTmplDecl() {}419 420template<typename T> __declspec(dllimport) void inlineFuncTmplDef();421template<typename T> inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}}422 423#else // MSVC drops dllimport when the function template is redeclared without it. (It doesn't warn, but we do.)424 425template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}426template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}427 428template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}429template<typename T> void inlineFuncTmplDecl() {} // expected-warning{{'inlineFuncTmplDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}430 431template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}432template<typename T> inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}433#endif434 435// Redeclarations436template<typename T> __declspec(dllimport) void funcTmplRedecl1();437template<typename T> __declspec(dllimport) void funcTmplRedecl1();438 439template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}440template<typename T> void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}441 442template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}443template<typename T> void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}444 445template<typename T> void funcTmplRedecl4(); // expected-note{{previous declaration is here}}446template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}447 448#ifdef MS449template<typename T> void funcTmplRedecl5(); // expected-note{{previous declaration is here}}450template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}451#endif452 453// Function template friends454struct FuncTmplFriend {455 template<typename T> friend __declspec(dllimport) void funcTmplFriend1();456 template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}457 template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}458 template<typename T> friend void funcTmplFriend4(); // expected-note{{previous declaration is here}}459#ifdef GNU460// expected-warning@+4{{'dllimport' attribute ignored on inline function}}461#else462// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}463#endif464 template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();465};466template<typename T> __declspec(dllimport) void funcTmplFriend1();467template<typename T> void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}468template<typename T> void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}469template<typename T> __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}470#if defined(MS) || defined(WI) || defined(PS)471// expected-warning@+2{{'funcTmplFriend5' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}472#endif473template<typename T> inline void funcTmplFriend5() {}474 475// External linkage is required.476template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}477template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}478namespace { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}479namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }480 481 482template<typename T> void funcTmpl() {}483template<typename T> inline void inlineFuncTmpl() {}484template<typename T> __declspec(dllimport) void importedFuncTmplDecl();485#ifdef GNU486// expected-warning@+2{{'dllimport' attribute ignored on inline function}}487#endif488template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}489 490// Import implicit instantiation of an imported function template.491void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }492void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }493 494// Import explicit instantiation declaration of an imported function template.495extern template void importedFuncTmpl<ExplicitDecl_Imported>();496 497// Import explicit instantiation definition of an imported function template.498// NB: MSVC fails this instantiation without explicit dllimport which is most499// likely a bug because an implicit instantiation is accepted.500template void importedFuncTmpl<ExplicitInst_Imported>();501 502// Import specialization of an imported function template. A definition must be503// declared inline.504template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();505template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}506#ifdef MS507template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}508#endif509 510// Not importing specialization of an imported function template without511// explicit dllimport.512template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}513 514 515// Import explicit instantiation declaration of a non-imported function template.516extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();517#ifdef GNU518// expected-warning@+2{{'dllimport' attribute ignored on inline function}}519#endif520extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();521 522// Import explicit instantiation definition of a non-imported function template.523template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();524#ifdef GNU525// expected-warning@+2{{'dllimport' attribute ignored on inline function}}526#endif527template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();528 529// Import specialization of a non-imported function template. A definition must530// be declared inline.531template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();532template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}533#ifdef GNU534// expected-warning@+2{{'dllimport' attribute ignored on inline function}}535#endif536template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}537 538 539//===----------------------------------------------------------------------===//540// Class members541//===----------------------------------------------------------------------===//542 543// Import individual members of a class.544struct ImportMembers {545 struct Nested {546 __declspec(dllimport) void normalDecl();547#ifdef GNU548// expected-note@+2{{previous attribute is here}}549#endif550 __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}}551 };552 553#ifdef GNU554// expected-note@+5{{previous attribute is here}}555// expected-warning@+5{{'dllimport' attribute ignored on inline function}}556// expected-warning@+6{{'dllimport' attribute ignored on inline function}}557#endif558 __declspec(dllimport) void normalDecl();559 __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}}560 __declspec(dllimport) void normalInclass() {}561 __declspec(dllimport) void normalInlineDef();562 __declspec(dllimport) inline void normalInlineDecl();563#ifdef GNU564// expected-note@+5{{previous attribute is here}}565// expected-warning@+5{{'dllimport' attribute ignored on inline function}}566// expected-warning@+6{{'dllimport' attribute ignored on inline function}}567#endif568 __declspec(dllimport) virtual void virtualDecl();569 __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}}570 __declspec(dllimport) virtual void virtualInclass() {}571 __declspec(dllimport) virtual void virtualInlineDef();572 __declspec(dllimport) virtual inline void virtualInlineDecl();573#ifdef GNU574// expected-note@+5{{previous attribute is here}}575// expected-warning@+5{{'dllimport' attribute ignored on inline function}}576// expected-warning@+6{{'dllimport' attribute ignored on inline function}}577#endif578 __declspec(dllimport) static void staticDecl();579 __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}}580 __declspec(dllimport) static void staticInclass() {}581 __declspec(dllimport) static void staticInlineDef();582 __declspec(dllimport) static inline void staticInlineDecl();583 584protected:585 __declspec(dllimport) void protectedDecl();586private:587 __declspec(dllimport) void privateDecl();588public:589 590 __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}}591 __declspec(dllimport) static int StaticField;592 __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}593 __declspec(dllimport) static const int StaticConstField;594 __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}595 __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;596 __declspec(dllimport) static const int StaticConstFieldBraceInit{1};597 __declspec(dllimport) constexpr static int ConstexprField = 1;598#if __cplusplus < 201703L && !defined(MS)599 // expected-note@+2{{attribute is here}}600#endif601 __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;602};603 604#if defined(MS) || defined(WI) || defined(PS)605// expected-warning@+4{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}606#else607 // expected-warning@+2{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}608#endif609void ImportMembers::Nested::normalDef() {}610#if defined(MS) || defined(WI) || defined(PS)611// expected-warning@+4{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}612#else613 // expected-warning@+2{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}614#endif615void ImportMembers::normalDef() {}616#ifdef GNU617// expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}618#endif619inline void ImportMembers::normalInlineDef() {}620 void ImportMembers::normalInlineDecl() {}621#if defined(MS) || defined(WI) || defined(PS)622 // expected-warning@+4{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}623#else624 // expected-warning@+2{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}625#endif626 void ImportMembers::virtualDef() {}627#ifdef GNU628// expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}629#endif630inline void ImportMembers::virtualInlineDef() {}631 void ImportMembers::virtualInlineDecl() {}632#if defined(MS) || defined(WI) || defined(PS)633 // expected-warning@+4{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}634#else635 // expected-warning@+2{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}636#endif637 void ImportMembers::staticDef() {}638#ifdef GNU639// expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}640#endif641inline void ImportMembers::staticInlineDef() {}642 void ImportMembers::staticInlineDecl() {}643 644 int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}645const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}646#if __cplusplus < 201703L && !defined(MS)647// expected-error@+2{{definition of dllimport static field not allowed}}648#endif649constexpr int ImportMembers::ConstexprFieldDef;650 651 652// Import on member definitions.653struct ImportMemberDefs {654 __declspec(dllimport) void normalDef();655 __declspec(dllimport) void normalInlineDef();656 __declspec(dllimport) virtual void virtualDef();657 __declspec(dllimport) virtual void virtualInlineDef();658 __declspec(dllimport) static void staticDef();659 __declspec(dllimport) static void staticInlineDef();660#ifdef MS661 __declspec(dllimport) inline void normalInlineDecl();662 __declspec(dllimport) virtual inline void virtualInlineDecl();663 __declspec(dllimport) static inline void staticInlineDecl();664#endif665 666 __declspec(dllimport) static int StaticField;667 __declspec(dllimport) static const int StaticConstField;668 __declspec(dllimport) constexpr static int ConstexprField = 1;669};670 671__declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}672__declspec(dllimport) void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}673__declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}674#ifdef MS675__declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {}676__declspec(dllimport) void ImportMemberDefs::normalInlineDecl() {}677__declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {}678__declspec(dllimport) void ImportMemberDefs::virtualInlineDecl() {}679__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}680__declspec(dllimport) void ImportMemberDefs::staticInlineDecl() {}681#endif682 683__declspec(dllimport) int ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}684__declspec(dllimport) const int ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}685#if __cplusplus < 201703L && !defined(MS)686// expected-error@+3{{definition of dllimport static field not allowed}}687// expected-note@+2{{attribute is here}}688#endif689__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField;690 691 692// Import special member functions.693struct ImportSpecials {694 __declspec(dllimport) ImportSpecials();695 __declspec(dllimport) ~ImportSpecials();696 __declspec(dllimport) ImportSpecials(const ImportSpecials&);697 __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);698 __declspec(dllimport) ImportSpecials(ImportSpecials&&);699 __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);700};701 702 703// Import deleted member functions.704struct ImportDeleted {705#if defined(MS) || defined(WI) || defined(PS)706 __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}707 __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}708 __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}709 __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}710 __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}711 __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}712 __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}713#else714 __declspec(dllimport) ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}715 __declspec(dllimport) ~ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}716 __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}717 __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}718 __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}719 __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}720 __declspec(dllimport) void deleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}}721#endif722};723 724 725// Import allocation functions.726struct ImportAlloc {727 __declspec(dllimport) void* operator new(__SIZE_TYPE__);728 __declspec(dllimport) void* operator new[](__SIZE_TYPE__);729 __declspec(dllimport) void operator delete(void*);730 __declspec(dllimport) void operator delete[](void*);731};732 733 734// Import defaulted member functions.735struct ImportDefaulted {736#ifdef GNU737 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}738 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}739 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}740 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}741 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}742 // expected-warning@+7{{'dllimport' attribute ignored on inline function}}743#endif744 __declspec(dllimport) ImportDefaulted() = default;745 __declspec(dllimport) ~ImportDefaulted() = default;746 __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;747 __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;748 __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;749 __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;750};751 752 753// Import defaulted member function definitions.754struct ImportDefaultedDefs {755 __declspec(dllimport) ImportDefaultedDefs();756#ifdef GNU757// expected-note@+2{{previous attribute is here}}758#endif759 __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}}760 761#ifdef GNU762// expected-warning@+3{{'dllimport' attribute ignored on inline function}}763// expected-note@+2{{previous declaration is here}}764#endif765 __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&);766 __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);767 768 __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);769#ifdef GNU770// expected-note@+2{{previous attribute is here}}771#endif772 __declspec(dllimport) ImportDefaultedDefs &operator=(ImportDefaultedDefs &&); // expected-note{{previous declaration is here}}773};774 775// Not allowed on definitions.776__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}777 778#if defined(MS) || defined(WI) || defined(PS)779// expected-warning@+5{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}780#else781// expected-warning@+3{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}782#endif783// dllimport cannot be dropped.784ImportDefaultedDefs::~ImportDefaultedDefs() = default;785 786// Import inline declaration and definition.787#ifdef GNU788// expected-error@+3{{redeclaration of 'ImportDefaultedDefs::ImportDefaultedDefs' cannot add 'dllimport' attribute}}789// expected-warning@+3{{'ImportDefaultedDefs::operator=' redeclared inline; 'dllimport' attribute ignored}}790#endif791__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;792inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;793 794__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}795#if defined(MS) || defined(WI) || defined(PS)796// expected-warning@+4{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}797#else798// expected-warning@+2{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}799#endif800ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default;801 802// Redeclarations cannot add dllimport.803struct MemberRedecl {804 void normalDef(); // expected-note{{previous declaration is here}}805 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}806 virtual void virtualDef(); // expected-note{{previous declaration is here}}807 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}808 static void staticDef(); // expected-note{{previous declaration is here}}809 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}810 811#if defined(MS) || defined(WI) || defined(PS)812 // expected-note@+4{{previous declaration is here}}813 // expected-note@+4{{previous declaration is here}}814 // expected-note@+4{{previous declaration is here}}815#endif816 void normalInlineDef();817 virtual void virtualInlineDef();818 static void staticInlineDef();819 820 static int StaticField; // expected-note{{previous declaration is here}}821 static const int StaticConstField; // expected-note{{previous declaration is here}}822 constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}823};824 825__declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}826 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}827__declspec(dllimport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}828__declspec(dllimport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}}829 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}830__declspec(dllimport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}831__declspec(dllimport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}}832 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}833__declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}834 835#if defined(MS) || defined(WI) || defined(PS)836__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}837__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}838__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}839#else840__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}841__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}842__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}843#endif844 845 846 847__declspec(dllimport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}848 // expected-error@-1{{definition of dllimport static field not allowed}}849 // expected-note@-2{{attribute is here}}850__declspec(dllimport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}851 // expected-error@-1{{definition of dllimport static field not allowed}}852 // expected-note@-2{{attribute is here}}853 854#if __cplusplus < 201703L && !defined(MS)855// expected-error@+6{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}856// expected-error@+5{{definition of dllimport static field not allowed}}857// expected-note@+4{{attribute is here}}858#else859// expected-warning@+2{{attribute declaration must precede definition}}860#endif861__declspec(dllimport) constexpr int MemberRedecl::ConstexprField;862 863 864 865//===----------------------------------------------------------------------===//866// Class member templates867//===----------------------------------------------------------------------===//868 869struct ImportMemberTmpl {870 template<typename T> __declspec(dllimport) void normalDecl();871 template<typename T> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}872#if defined(MS) || defined(WI) || defined(PS)873// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}874#endif875 template<typename T> __declspec(dllimport) void normalInlineDef();876 template<typename T> __declspec(dllimport) static void staticDecl();877 template<typename T> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}878#if defined(MS) || defined(WI) || defined(PS)879// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}880#endif881 template<typename T> __declspec(dllimport) static void staticInlineDef();882 883#ifdef GNU884 template<typename T> __declspec(dllimport) void normalInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}}885 template<typename T> __declspec(dllimport) inline void normalInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}886 template<typename T> __declspec(dllimport) static void staticInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}}887 template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}888#else889 template<typename T> __declspec(dllimport) void normalInclass() {}890 template<typename T> __declspec(dllimport) inline void normalInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}891 template<typename T> __declspec(dllimport) static void staticInclass() {}892 template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}893#endif894 895#if __has_feature(cxx_variable_templates)896 template<typename T> __declspec(dllimport) static int StaticField;897 template<typename T> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}898 template<typename T> __declspec(dllimport) static const int StaticConstField;899 template<typename T> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}900 template<typename T> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;901 template<typename T> __declspec(dllimport) static const int StaticConstFieldBraceInit{1};902 template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;903 template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;904#endif // __has_feature(cxx_variable_templates)905};906 907template<typename T> void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}908template<typename T> void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}909#ifdef GNU // dllimport was ignored above910template<typename T> void ImportMemberTmpl::normalInlineDecl() {}911template<typename T> void ImportMemberTmpl::staticInlineDecl() {}912#else // dllimport dropped here913template<typename T> void ImportMemberTmpl::normalInlineDecl() {} // expected-warning{{'ImportMemberTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}914template<typename T> void ImportMemberTmpl::staticInlineDecl() {} // expected-warning{{'ImportMemberTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}915#endif916 917#ifdef GNU918template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}919template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}920#else921template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}922template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}923#endif924 925#if __has_feature(cxx_variable_templates)926template<typename T> int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}927template<typename T> const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}928#ifdef MS929template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef;930#endif931#endif // __has_feature(cxx_variable_templates)932 933 934// Redeclarations cannot add dllimport.935struct MemTmplRedecl {936 template<typename T> void normalDef(); // expected-note{{previous declaration is here}}937 template<typename T> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}938 template<typename T> static void staticDef(); // expected-note{{previous declaration is here}}939 template<typename T> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}940 941#if defined(MS) || defined(WI) || defined(PS)942// expected-note@+3{{previous declaration is here}}943// expected-note@+3{{previous declaration is here}}944#endif945 template<typename T> void normalInlineDef();946 template<typename T> static void staticInlineDef();947 948#if __has_feature(cxx_variable_templates)949 template<typename T> static int StaticField; // expected-note{{previous declaration is here}}950 template<typename T> static const int StaticConstField; // expected-note{{previous declaration is here}}951#ifdef MS952 template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous definition is here}}953#endif954#endif // __has_feature(cxx_variable_templates)955};956 957template<typename T> __declspec(dllimport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}958 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}959#if defined(MS) || defined(WI) || defined(PS)960template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}961#else962template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}963#endif964template<typename T> __declspec(dllimport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}965template<typename T> __declspec(dllimport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}}966 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}967#if defined(MS) || defined(WI) || defined(PS)968template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}969#else970template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}971#endif972template<typename T> __declspec(dllimport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}973 974#if __has_feature(cxx_variable_templates)975template<typename T> __declspec(dllimport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}976 // expected-error@-1{{definition of dllimport static field not allowed}}977 // expected-note@-2{{attribute is here}}978template<typename T> __declspec(dllimport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}979 // expected-error@-1{{definition of dllimport static field not allowed}}980 // expected-note@-2{{attribute is here}}981#ifdef MS982// expected-warning@+1{{attribute declaration must precede definition}}983template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField;984#endif985#endif // __has_feature(cxx_variable_templates)986 987 988 989struct MemFunTmpl {990 template<typename T> void normalDef() {}991#ifdef GNU992 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}993#endif994 template<typename T> __declspec(dllimport) void importedNormal() {}995 template<typename T> static void staticDef() {}996#ifdef GNU997 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}998#endif999 template<typename T> __declspec(dllimport) static void importedStatic() {}1000};1001 1002// Import implicit instantiation of an imported member function template.1003void useMemFunTmpl() {1004 MemFunTmpl().importedNormal<ImplicitInst_Imported>();1005 MemFunTmpl().importedStatic<ImplicitInst_Imported>();1006}1007 1008// Import explicit instantiation declaration of an imported member function1009// template.1010extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();1011extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();1012 1013// Import explicit instantiation definition of an imported member function1014// template.1015// NB: MSVC fails this instantiation without explicit dllimport.1016template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();1017template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();1018 1019// Import specialization of an imported member function template.1020template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();1021template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw1022#ifdef GNU1023 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}1024#endif1025template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}1026#if 11027// FIXME: This should not be an error when targeting MSVC. (PR21406)1028// expected-error@-7{{dllimport cannot be applied to non-inline function definition}}1029#endif1030 1031template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();1032template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw1033#ifdef GNU1034 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}1035#endif1036template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}1037#if 11038// FIXME: This should not be an error when targeting MSVC. (PR21406)1039// expected-error@-7{{dllimport cannot be applied to non-inline function definition}}1040#endif1041 1042// Not importing specialization of an imported member function template without1043// explicit dllimport.1044template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}1045template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}1046 1047 1048// Import explicit instantiation declaration of a non-imported member function1049// template.1050#ifdef GNU1051// expected-warning@+3{{'dllimport' attribute ignored on inline function}}1052// expected-warning@+3{{'dllimport' attribute ignored on inline function}}1053#endif1054extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();1055extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();1056 1057// Import explicit instantiation definition of a non-imported member function1058// template.1059#ifdef GNU1060// expected-warning@+3{{'dllimport' attribute ignored on inline function}}1061// expected-warning@+3{{'dllimport' attribute ignored on inline function}}1062#endif1063template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();1064template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();1065 1066// Import specialization of a non-imported member function template.1067template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();1068template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw1069#ifdef GNU1070 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}1071#endif1072template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}1073#if 11074// FIXME: This should not be an error when targeting MSVC. (PR21406)1075// expected-error@-7{{dllimport cannot be applied to non-inline function definition}}1076#endif1077 1078template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();1079template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw1080#ifdef GNU1081 // expected-warning@+2{{'dllimport' attribute ignored on inline function}}1082#endif1083template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}1084#if 11085// FIXME: This should not be an error when targeting MSVC. (PR21406)1086// expected-error@-7{{dllimport cannot be applied to non-inline function definition}}1087#endif1088 1089 1090 1091#if __has_feature(cxx_variable_templates)1092struct MemVarTmpl {1093 template<typename T> static const int StaticVar = 1;1094 template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;1095};1096 1097// Import implicit instantiation of an imported member variable template.1098int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }1099 1100// Import explicit instantiation declaration of an imported member variable1101// template.1102extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;1103 1104// An explicit instantiation definition of an imported member variable template1105// cannot be imported because the template must be defined which is illegal. The1106// in-class initializer does not count.1107 1108// Import specialization of an imported member variable template.1109template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;1110template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;1111 // expected-error@-1{{definition of dllimport static field not allowed}}1112 // expected-note@-2{{attribute is here}}1113 1114// Not importing specialization of a member variable template without explicit1115// dllimport.1116template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;1117 1118 1119// Import explicit instantiation declaration of a non-imported member variable1120// template.1121extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;1122 1123// An explicit instantiation definition of a non-imported member variable template1124// cannot be imported because the template must be defined which is illegal. The1125// in-class initializer does not count.1126 1127// Import specialization of a non-imported member variable template.1128template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;1129template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;1130 // expected-error@-1{{definition of dllimport static field not allowed}}1131 // expected-note@-2{{attribute is here}}1132 1133#endif // __has_feature(cxx_variable_templates)1134 1135 1136 1137//===----------------------------------------------------------------------===//1138// Class template members1139//===----------------------------------------------------------------------===//1140 1141// Import individual members of a class template.1142template<typename T>1143struct ImportClassTmplMembers {1144#ifndef GNU1145// expected-note@+2{{attribute is here}}1146#endif1147 __declspec(dllimport) void normalDecl();1148#ifdef GNU1149// expected-note@+2{{previous attribute is here}}1150#endif1151 __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}}1152 __declspec(dllimport) void normalInlineDef();1153 __declspec(dllimport) virtual void virtualDecl();1154#ifdef GNU1155// expected-note@+2{{previous attribute is here}}1156#endif1157 __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}}1158 __declspec(dllimport) virtual void virtualInlineDef();1159 __declspec(dllimport) static void staticDecl();1160#ifdef GNU1161// expected-note@+2{{previous attribute is here}}1162#endif1163 __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}}1164 __declspec(dllimport) static void staticInlineDef();1165 1166#ifdef GNU1167// expected-warning@+7{{'dllimport' attribute ignored on inline function}}1168// expected-warning@+7{{'dllimport' attribute ignored on inline function}}1169// expected-warning@+7{{'dllimport' attribute ignored on inline function}}1170// expected-warning@+7{{'dllimport' attribute ignored on inline function}}1171// expected-warning@+7{{'dllimport' attribute ignored on inline function}}1172// expected-warning@+7{{'dllimport' attribute ignored on inline function}}1173#endif1174 __declspec(dllimport) void normalInclass() {}1175 __declspec(dllimport) inline void normalInlineDecl();1176 __declspec(dllimport) virtual void virtualInclass() {}1177 __declspec(dllimport) virtual inline void virtualInlineDecl();1178 __declspec(dllimport) static void staticInclass() {}1179 __declspec(dllimport) static inline void staticInlineDecl();1180 1181protected:1182 __declspec(dllimport) void protectedDecl();1183private:1184 __declspec(dllimport) void privateDecl();1185public:1186 1187 __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to}}1188 __declspec(dllimport) static int StaticField;1189 __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}1190 __declspec(dllimport) static const int StaticConstField;1191 __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}1192 __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;1193 __declspec(dllimport) static const int StaticConstFieldBraceInit{1};1194 __declspec(dllimport) constexpr static int ConstexprField = 1;1195#if __cplusplus < 201703L && !defined(MS)1196 // expected-note@+2{{attribute is here}}1197#endif1198 __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;1199};1200 1201// NB: MSVC is inconsistent here and disallows *InlineDef on class templates,1202// but allows it on classes. We allow both.1203#if defined(MS) || defined(WI) || defined(PS)1204// expected-warning@+5{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}1205#else1206// expected-warning@+3{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1207#endif1208template <typename T>1209void ImportClassTmplMembers<T>::normalDef() {}1210#ifdef GNU1211// expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}1212#endif1213template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}1214template<typename T> void ImportClassTmplMembers<T>::normalInlineDecl() {}1215#if defined(MS) || defined(WI) || defined(PS)1216// expected-warning@+5{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}1217#else1218// expected-warning@+3{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1219#endif1220template <typename T>1221void ImportClassTmplMembers<T>::virtualDef() {}1222#ifdef GNU1223// expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}1224#endif1225template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}1226template<typename T> void ImportClassTmplMembers<T>::virtualInlineDecl() {}1227#if defined(MS) || defined(WI) || defined(PS)1228// expected-warning@+5{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}}1229#else1230// expected-warning@+3{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1231#endif1232template <typename T>1233void ImportClassTmplMembers<T>::staticDef() {}1234#ifdef GNU1235// expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}1236#endif1237template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}1238template<typename T> void ImportClassTmplMembers<T>::staticInlineDecl() {}1239 1240template<typename T> int ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}1241template<typename T> const int ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}1242#if __cplusplus < 201703L && !defined(MS)1243// expected-warning@+2{{definition of dllimport static field}}1244#endif1245template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef;1246 1247 1248// Redeclarations cannot add dllimport.1249template<typename T>1250struct CTMR /*ClassTmplMemberRedecl*/ {1251 void normalDef(); // expected-note{{previous declaration is here}}1252 inline void normalInlineDecl(); // expected-note{{previous declaration is here}}1253 virtual void virtualDef(); // expected-note{{previous declaration is here}}1254 virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}1255 static void staticDef(); // expected-note{{previous declaration is here}}1256 static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}1257 1258#if defined(MS) || defined(WI) || defined(PS)1259// expected-note@+4{{previous declaration is here}}1260// expected-note@+4{{previous declaration is here}}1261// expected-note@+4{{previous declaration is here}}1262#endif1263 void normalInlineDef();1264 virtual void virtualInlineDef();1265 static void staticInlineDef();1266 1267 static int StaticField; // expected-note{{previous declaration is here}}1268 static const int StaticConstField; // expected-note{{previous declaration is here}}1269 constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}1270};1271 1272template<typename T> __declspec(dllimport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}1273 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}1274template<typename T> __declspec(dllimport) void CTMR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}1275template<typename T> __declspec(dllimport) void CTMR<T>::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}1276 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}1277template<typename T> __declspec(dllimport) void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}1278template<typename T> __declspec(dllimport) void CTMR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}1279 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}1280template<typename T> __declspec(dllimport) void CTMR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}1281 1282#if defined(MS) || defined(WI) || defined(PS)1283template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}1284template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}1285template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}1286#else1287template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}1288template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}1289template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}1290#endif1291 1292template<typename T> __declspec(dllimport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}1293 // expected-warning@-1{{definition of dllimport static field}}1294 // expected-note@-2{{attribute is here}}1295template<typename T> __declspec(dllimport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}1296 // expected-warning@-1{{definition of dllimport static field}}1297 // expected-note@-2{{attribute is here}}1298 1299#if __cplusplus < 201703L && !defined(MS)1300// expected-error@+6{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}1301// expected-warning@+5{{definition of dllimport static field}}1302// expected-note@+4{{attribute is here}}1303#else1304// expected-warning@+2{{attribute declaration must precede definition}}1305#endif1306template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField;1307 1308 1309// MSVC imports explicit specialization of imported class template member1310// function, and errors on such definitions. MinGW does not treat them as1311// dllimport.1312template <typename> struct ClassTmpl {1313#if !defined(GNU)1314// expected-note@+2{{attribute is here}}1315#endif1316 void __declspec(dllimport) importedNormal();1317#if !defined(GNU)1318// expected-note@+2{{attribute is here}}1319#endif1320 static void __declspec(dllimport) importedStatic();1321};1322#if !defined(GNU)1323// expected-error@+2{{cannot define non-inline dllimport template specialization}}1324#endif1325template<> void ClassTmpl<int>::importedNormal() {}1326#if !defined(GNU)1327// expected-error@+2{{cannot define non-inline dllimport template specialization}}1328#endif1329template<> void ClassTmpl<int>::importedStatic() {}1330 1331#if !defined(GNU)1332// expected-error@+3{{cannot define non-inline dllimport template specialization}}1333// expected-error@+2{{attribute 'dllimport' cannot be applied to a deleted function}}1334#endif1335template <> void ImportClassTmplMembers<int>::normalDecl() = delete;1336 1337 1338//===----------------------------------------------------------------------===//1339// Class template member templates1340//===----------------------------------------------------------------------===//1341 1342template<typename T>1343struct ImportClsTmplMemTmpl {1344 template<typename U> __declspec(dllimport) void normalDecl();1345 template<typename U> __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}1346#if defined(MS) || defined(WI) || defined(PS)1347// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}1348#endif1349 template<typename U> __declspec(dllimport) void normalInlineDef();1350 template<typename U> __declspec(dllimport) static void staticDecl();1351 template<typename U> __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}1352#if defined(MS) || defined(WI) || defined(PS)1353// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}1354#endif1355 template<typename U> __declspec(dllimport) static void staticInlineDef();1356 1357#ifdef GNU1358 // expected-warning@+5{{'dllimport' attribute ignored on inline function}}1359 // expected-warning@+8{{'dllimport' attribute ignored on inline function}}1360 // expected-warning@+8{{'dllimport' attribute ignored on inline function}}1361 // expected-warning@+11{{'dllimport' attribute ignored on inline function}}1362#endif1363 template<typename U> __declspec(dllimport) void normalInclass() {}1364#if defined(MS) || defined(WI) || defined(PS)1365// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}1366#endif1367 template<typename U> __declspec(dllimport) inline void normalInlineDecl();1368 template<typename U> __declspec(dllimport) static void staticInclass() {}1369#if defined(MS) || defined(WI) || defined(PS)1370// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}1371#endif1372 template<typename U> __declspec(dllimport) static inline void staticInlineDecl();1373 1374#if __has_feature(cxx_variable_templates)1375 template<typename U> __declspec(dllimport) static int StaticField;1376 template<typename U> __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}}1377 template<typename U> __declspec(dllimport) static const int StaticConstField;1378 template<typename U> __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}}1379 template<typename U> __declspec(dllimport) static const int StaticConstFieldEqualInit = 1;1380 template<typename U> __declspec(dllimport) static const int StaticConstFieldBraceInit{1};1381 template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;1382#ifdef MS1383 template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;1384#endif1385#endif // __has_feature(cxx_variable_templates)1386};1387 1388template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1389template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1390#ifdef GNU1391template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}1392template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}1393#else1394template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1395template<typename T> template<typename U> void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1396#endif1397 1398#ifdef GNU1399template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}1400template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}1401#else1402template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1403template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}1404#endif1405 1406#if __has_feature(cxx_variable_templates)1407template<typename T> template<typename U> int ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}1408template<typename T> template<typename U> const int ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}1409#ifdef MS1410template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef;1411#endif1412#endif // __has_feature(cxx_variable_templates)1413 1414 1415// Redeclarations cannot add dllimport.1416template<typename T>1417struct CTMTR /*ClassTmplMemberTmplRedecl*/ {1418 template<typename U> void normalDef(); // expected-note{{previous declaration is here}}1419 template<typename U> inline void normalInlineDecl(); // expected-note{{previous declaration is here}}1420 template<typename U> static void staticDef(); // expected-note{{previous declaration is here}}1421 template<typename U> static inline void staticInlineDecl(); // expected-note{{previous declaration is here}}1422 1423#if defined(MS) || defined(WI) || defined(PS)1424 // expected-note@+3{{previous declaration is here}}1425 // expected-note@+3{{previous declaration is here}}1426#endif1427 template<typename U> void normalInlineDef();1428 template<typename U> static void staticInlineDef();1429 1430#if __has_feature(cxx_variable_templates)1431 template<typename U> static int StaticField; // expected-note{{previous declaration is here}}1432 template<typename U> static const int StaticConstField; // expected-note{{previous declaration is here}}1433#ifdef MS1434 template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous definition is here}}1435#endif1436#endif // __has_feature(cxx_variable_templates)1437};1438 1439template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}1440 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}1441template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}1442template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}1443 // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}1444template<typename T> template<typename U> __declspec(dllimport) void CTMTR<T>::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}1445 1446#if defined(MS) || defined(WI) || defined(PS)1447template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}1448template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}1449#else1450template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}1451template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}}1452#endif1453 1454#if __has_feature(cxx_variable_templates)1455template<typename T> template<typename U> __declspec(dllimport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}1456 // expected-warning@-1{{definition of dllimport static field}}1457 // expected-note@-2{{attribute is here}}1458template<typename T> template<typename U> __declspec(dllimport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}1459 // expected-warning@-1{{definition of dllimport static field}}1460 // expected-note@-2{{attribute is here}}1461#ifdef MS1462// expected-warning@+1{{attribute declaration must precede definition}}1463template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField;1464#endif1465#endif // __has_feature(cxx_variable_templates)1466 1467 1468 1469//===----------------------------------------------------------------------===//1470// Classes1471//===----------------------------------------------------------------------===//1472 1473namespace {1474 struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}}1475}1476 1477class __declspec(dllimport) ClassDecl;1478 1479class __declspec(dllimport) ClassDef { };1480 1481template <typename T> class ClassTemplate {};1482 1483#if defined(MS) || defined(WI) || defined(PS)1484// expected-note@+5{{previous attribute is here}}1485// expected-note@+4{{previous attribute is here}}1486// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}1487// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}1488#endif1489class __declspec(dllimport) ImportClassWithDllMember {1490 void __declspec(dllexport) foo();1491 void __declspec(dllimport) bar();1492};1493 1494#if defined(MS) || defined(WI) || defined(PS)1495// expected-note@+5{{previous attribute is here}}1496// expected-note@+4{{previous attribute is here}}1497// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}1498// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}1499#endif1500template <typename T> class __declspec(dllexport) ExportClassWithDllMember {1501 void __declspec(dllimport) foo();1502 void __declspec(dllexport) bar();1503};1504 1505namespace ImportedExplicitSpecialization {1506template <typename T> struct S { static int x; };1507template <typename T> int S<T>::x = sizeof(T);1508template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}1509int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}1510}1511 1512namespace PR19988 {1513// Don't error about applying delete to dllimport member function when instantiating.1514template <typename> struct __declspec(dllimport) S {1515 void foo() = delete;1516};1517S<int> s;1518}1519 1520#if defined(MS) || defined(WI) || defined(PS)1521// expected-warning@+3{{'dllimport' attribute ignored}}1522#endif1523template <typename T> struct PartiallySpecializedClassTemplate {};1524template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };1525 1526template <typename T> struct ExpliciallySpecializedClassTemplate {};1527template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };1528 1529 1530//===----------------------------------------------------------------------===//1531// Classes with template base classes1532//===----------------------------------------------------------------------===//1533 1534class __declspec(dllexport) ExportedClass {};1535class __declspec(dllimport) ImportedClass {};1536 1537template <typename T> class __declspec(dllexport) ExportedClassTemplate {};1538 1539#if !defined(MS) && !defined(PS)1540// expected-error@+2{{'ImportedClassTemplate<LocalCRTP>' must have external linkage when declared 'dllimport'}}1541#endif1542template <typename T> class __declspec(dllimport) ImportedClassTemplate {};1543 1544// ClassTemplate<int> gets imported.1545class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};1546 1547// ClassTemplate<int> is already imported.1548class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};1549 1550// ImportedClassTemplate is expliitly imported.1551class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};1552 1553// ExportedClassTemplate is explicitly exported.1554class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};1555 1556class DerivedFromTemplateD : public ClassTemplate<double> {};1557// Base class previously implicitly instantiated without attribute; it will get propagated.1558class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};1559 1560// Base class has explicit instantiation declaration; the attribute will get propagated.1561extern template class ClassTemplate<float>;1562class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {};1563 1564class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};1565// The second derived class doesn't change anything, the attribute that was propagated first wins.1566class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};1567 1568template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };1569#if defined(MS) || defined(PS)1570// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}1571#endif1572template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };1573template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };1574template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };1575template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };1576template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };1577 1578template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };1579#if defined(MS) || defined(PS)1580// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}1581#endif1582template struct ExplicitlyInstantiatedTemplate<int>;1583template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };1584template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;1585template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };1586template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;1587 1588#if defined(MS) || defined(PS)1589// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}1590// expected-note@+2{{attribute is here}}1591#endif1592struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};1593 1594// Base class already specialized with export attribute.1595struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};1596 1597// Base class already specialized with import attribute.1598struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};1599 1600#if defined(MS) || defined(PS)1601// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}1602// expected-note@+2{{attribute is here}}1603#endif1604struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};1605 1606// Base class already instantiated with export attribute.1607struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};1608 1609// Base class already instantiated with import attribute.1610struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};1611 1612template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };1613extern template struct ExplicitInstantiationDeclTemplateBase<int>;1614struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};1615 1616void func() {1617 // MSVC propagates dllimport to derived classes even if they don't have external linkage.1618 class LocalDerivedFromImportedClass : public ImportedClass {};1619 class LocalDerivedFromImportedTemplate : public ImportedClassTemplate<int> {};1620#if defined(GNU) || defined(WI)1621 // expected-note@+2{{in instantiation of template class 'ImportedClassTemplate<LocalCRTP>' requested here}}1622#endif1623 class LocalCRTP : public ImportedClassTemplate<LocalCRTP> {};1624}1625 1626//===----------------------------------------------------------------------===//1627// Lambdas1628//===----------------------------------------------------------------------===//1629// The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported.1630#if defined(MS) || defined(WI) || defined(PS)1631// expected-error@+4{{lambda cannot be declared 'dllimport'}}1632#else1633// expected-warning@+2{{'dllimport' attribute ignored on inline function}}1634#endif1635auto Lambda = []() __declspec(dllimport) -> bool { return true; };1636