Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -276,7 +276,7 @@ ///\brief Whether Sema has generated a multiplexer and has to delete it. bool isMultiplexExternalSource; - static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); + static bool mightHaveNonExternalLinkage(const NamedDecl *D); bool isVisibleSlow(const NamedDecl *D); @@ -3709,7 +3709,7 @@ void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); - bool ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const; + bool ShouldWarnIfUnusedFileScopedDecl(const NamedDecl *D) const; /// \brief If it's a file scoped decl that must warn if not used, keep track /// of it. Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -470,6 +470,13 @@ return true; if (const FunctionDecl *FD = dyn_cast(D)) { + // If this is a function template and neither of its specs is unused we + // should warn. + if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate()) + for (const auto *Spec : Template->specializations()) + if (ShouldRemoveFromUnused(SemaRef, Spec)) + return true; + // UnusedFileScopedDecls stores the first declaration. // The declaration may have become definition so check again. const FunctionDecl *DeclToCheck; @@ -493,6 +500,11 @@ VD->isUsableInConstantExpressions(SemaRef->Context)) return true; + if (VarTemplateDecl *Template = VD->getDescribedVarTemplate()) + for (const auto *Spec : Template->specializations()) + if (ShouldRemoveFromUnused(SemaRef, Spec)) + return true; + // UnusedFileScopedDecls stores the first declaration. // The declaration may have become definition so check again. const VarDecl *DeclToCheck = VD->getDefinition(); Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -1449,7 +1449,7 @@ // of the typedef, this function finds out if D might have non-external linkage. // Callers should verify at the end of the TU if it D has external linkage or // not. -bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) { +bool Sema::mightHaveNonExternalLinkage(const NamedDecl *D) { const DeclContext *DC = D->getDeclContext(); while (!DC->isTranslationUnit()) { if (const RecordDecl *RD = dyn_cast(DC)){ @@ -1470,7 +1470,7 @@ return S.SourceMgr.isInMainFile(Loc); } -bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { +bool Sema::ShouldWarnIfUnusedFileScopedDecl(const NamedDecl *D) const { assert(D); if (D->isInvalidDecl() || D->isUsed() || D->hasAttr()) @@ -1493,6 +1493,10 @@ // 'static inline' functions are defined in headers; don't warn. if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation())) return false; + // 'static operator' functions are defined in headers; don't warn. + if (FD->isOverloadedOperator() && + !isMainFileLoc(*this, FD->getLocation())) + return false; } if (FD->doesThisDeclarationHaveABody() && @@ -6672,6 +6676,7 @@ if (NewTemplate) { if (NewVD->isInvalidDecl()) NewTemplate->setInvalidDecl(); + MarkUnusedFileScopedDecl(NewVD); ActOnDocumentableDecl(NewTemplate); return NewTemplate; } @@ -8887,6 +8892,7 @@ if (FunctionTemplate) { if (NewFD->isInvalidDecl()) FunctionTemplate->setInvalidDecl(); + MarkUnusedFileScopedDecl(NewFD); return FunctionTemplate; } } Index: test/SemaCXX/dllimport.cpp =================================================================== --- test/SemaCXX/dllimport.cpp +++ test/SemaCXX/dllimport.cpp @@ -4,1532 +4,8 @@ // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s // Helper structs to make templates more expressive. -struct ImplicitInst_Imported {}; -struct ExplicitDecl_Imported {}; -struct ExplicitInst_Imported {}; -struct ExplicitSpec_Imported {}; -struct ExplicitSpec_Def_Imported {}; -struct ExplicitSpec_InlineDef_Imported {}; -struct ExplicitSpec_NotImported {}; namespace { struct Internal {}; } -// Invalid usage. -__declspec(dllimport) typedef int typedef1; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} -typedef __declspec(dllimport) int typedef2; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} -typedef int __declspec(dllimport) typedef3; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} -typedef __declspec(dllimport) void (*FunTy)(); -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} -enum __declspec(dllimport) Enum {}; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} -#if __has_feature(cxx_strong_enums) -enum class __declspec(dllimport) EnumClass {}; -// expected-warning@-1{{'dllimport' attribute only applies to variables, functions and classes}} -#endif - - - -//===----------------------------------------------------------------------===// -// Globals -//===----------------------------------------------------------------------===// - -// Import declaration. -__declspec(dllimport) extern int ExternGlobalDecl; - -// dllimport implies a declaration. -__declspec(dllimport) int GlobalDecl; -int **__attribute__((dllimport))* GlobalDeclChunkAttr; -int GlobalDeclAttr __attribute__((dllimport)); - -// Not allowed on definitions. -__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}} -__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}} -int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}} - -// Declare, then reject definition. -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif -__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} -#ifdef MS -// expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -int ExternGlobalDeclInit = 1; - -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif -__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} -#ifdef MS -// expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -int GlobalDeclInit = 1; - -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif -int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} -#ifdef MS -// expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -int *GlobalDeclChunkAttrInit = 0; - -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif -int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} -#ifdef MS -// expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -int GlobalDeclAttrInit = 1; - -// Redeclarations -__declspec(dllimport) extern int GlobalRedecl1; -__declspec(dllimport) extern int GlobalRedecl1; - -__declspec(dllimport) int GlobalRedecl2a; -__declspec(dllimport) int GlobalRedecl2a; - -int *__attribute__((dllimport)) GlobalRedecl2b; -int *__attribute__((dllimport)) GlobalRedecl2b; - -int GlobalRedecl2c __attribute__((dllimport)); -int GlobalRedecl2c __attribute__((dllimport)); - -__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - - extern int GlobalRedecl4; // expected-note{{previous declaration is here}} -__declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}} - -extern "C" { - extern int GlobalRedecl5; // expected-note{{previous declaration is here}} -__declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}} -} - -// External linkage is required. -__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}} -__declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}} -namespace { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}} -namespace ns { __declspec(dllimport) int ExternalGlobal; } - -__declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}} - // expected-error@-1{{definition of dllimport data}} - -// Thread local variables are invalid. -__declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}} -// This doesn't work on MinGW, because there, dllimport on the inline function is ignored. -#ifndef GNU -inline void __declspec(dllimport) ImportedInlineWithThreadLocal() { - static __thread int OK; // no-error -} -#endif - -// Import in local scope. -__declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}} -__declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}} -__declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}} -void functionScope() { - __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}} - int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}} - int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}} - - __declspec(dllimport) int LocalVarDecl; - __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}} - __declspec(dllimport) extern int ExternLocalVarDecl; - __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}} - __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}} -} - - - -//===----------------------------------------------------------------------===// -// Variable templates -//===----------------------------------------------------------------------===// -#if __has_feature(cxx_variable_templates) - -// Import declaration. -template __declspec(dllimport) extern int ExternVarTmplDecl; - -// dllimport implies a declaration. -template __declspec(dllimport) int VarTmplDecl; - -// Not allowed on definitions. -template __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}} -template __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}} -template int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}} - -// Declare, then reject definition. -#ifdef GNU -// expected-note@+3{{previous attribute is here}} -#endif -template -__declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} -#ifdef MS -// expected-warning@+5{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+3{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -template -int ExternVarTmplDeclInit = 1; - -#ifdef GNU -// expected-note@+3{{previous attribute is here}} -#endif -template -__declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} -#ifdef MS -// expected-warning@+5{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+3{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -template -int VarTmplDeclInit = 1; - -// Redeclarations -template __declspec(dllimport) extern int VarTmplRedecl1; -template __declspec(dllimport) extern int VarTmplRedecl1; - -template __declspec(dllimport) int VarTmplRedecl2; -template __declspec(dllimport) int VarTmplRedecl2; - -template __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - -template extern int VarTmplRedecl4; // expected-note{{previous declaration is here}} -template __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}} - -// External linkage is required. -template __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}} -template __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}} -namespace { template __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}} -namespace ns { template __declspec(dllimport) int ExternalVarTmpl; } - template __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}} - -template int VarTmpl; -template __declspec(dllimport) int ImportedVarTmpl; - -// Import implicit instantiation of an imported variable template. -int useVarTmpl() { return ImportedVarTmpl; } - -// Import explicit instantiation declaration of an imported variable template. -extern template int ImportedVarTmpl; - -// An explicit instantiation definition of an imported variable template cannot -// be imported because the template must be defined which is illegal. - -// Import specialization of an imported variable template. -template<> __declspec(dllimport) int ImportedVarTmpl; -template<> __declspec(dllimport) int ImportedVarTmpl = 1; // expected-error{{definition of dllimport data}} - -// Not importing specialization of an imported variable template without -// explicit dllimport. -template<> int ImportedVarTmpl; - - -// Import explicit instantiation declaration of a non-imported variable template. -extern template __declspec(dllimport) int VarTmpl; - -// Import explicit instantiation definition of a non-imported variable template. -template __declspec(dllimport) int VarTmpl; - -// Import specialization of a non-imported variable template. -template<> __declspec(dllimport) int VarTmpl; -template<> __declspec(dllimport) int VarTmpl = 1; // expected-error{{definition of dllimport data}} - -#endif // __has_feature(cxx_variable_templates) - - -//===----------------------------------------------------------------------===// -// Functions -//===----------------------------------------------------------------------===// - -// Import function declaration. Check different placements. -__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__ -__declspec(dllimport) void decl1B(); - -void __attribute__((dllimport)) decl2A(); -void __declspec(dllimport) decl2B(); - -// Not allowed on function definitions. -__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} - -// extern "C" -extern "C" __declspec(dllimport) void externC(); - -// Import inline function. -#ifdef GNU -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -#endif -__declspec(dllimport) inline void inlineFunc1() {} -inline void __attribute__((dllimport)) inlineFunc2() {} - -#ifdef GNU -// expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -__declspec(dllimport) inline void inlineDecl(); - void inlineDecl() {} - -__declspec(dllimport) void inlineDef(); -#ifdef GNU -// expected-warning@+2{{'inlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif - inline void inlineDef() {} - -// Redeclarations -__declspec(dllimport) void redecl1(); -__declspec(dllimport) void redecl1(); - -__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - -#ifdef GNU - // expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} - // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport. -#ifdef MS - // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else - // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - void redecl3() {} - - void redecl4(); // expected-note{{previous declaration is here}} -__declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}} - -extern "C" { - void redecl5(); // expected-note{{previous declaration is here}} -__declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}} -} - -#ifdef MS - void redecl6(); // expected-note{{previous declaration is here}} -__declspec(dllimport) inline void redecl6() {} // expected-warning{{redeclaration of 'redecl6' should not add 'dllimport' attribute}} -#else - void redecl6(); -__declspec(dllimport) inline void redecl6() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif - -// Friend functions -struct FuncFriend { - friend __declspec(dllimport) void friend1(); - friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} - friend void friend4(); // expected-note{{previous declaration is here}} -#ifdef MS -// expected-note@+2{{previous declaration is here}} -#endif - friend void friend5(); -}; -__declspec(dllimport) void friend1(); - void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#ifdef MS - // expected-warning@+4{{'friend3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else - // expected-warning@+2{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - void friend3() {} -__declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}} -#ifdef MS -__declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}} -#else -__declspec(dllimport) inline void friend5() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif - - -void __declspec(dllimport) friend6(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -void __declspec(dllimport) friend7(); -struct FuncFriend2 { - friend void friend6(); // expected-warning{{'friend6' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - friend void ::friend7(); -}; - -// Implicit declarations can be redeclared with dllimport. -__declspec(dllimport) void* operator new(__SIZE_TYPE__ n); - -// External linkage is required. -__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}} -__declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}} -namespace { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}} -namespace ns { __declspec(dllimport) void externalFunc(); } - -// Import deleted functions. -// FIXME: Deleted functions are definitions so a missing inline is diagnosed -// here which is irrelevant. But because the delete keyword is parsed later -// there is currently no straight-forward way to avoid this diagnostic. -__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}} -#ifdef MS -__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} -#else -__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif - - - -//===----------------------------------------------------------------------===// -// Function templates -//===----------------------------------------------------------------------===// - -// Import function template declaration. Check different placements. -template __declspec(dllimport) void funcTmplDecl1(); -template void __declspec(dllimport) funcTmplDecl2(); - -// Import function template definition. -template __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} - -// Import inline function template. -#ifdef GNU // MinGW always ignores dllimport on inline functions. - -template __declspec(dllimport) inline void inlineFuncTmpl1() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -template inline void __attribute__((dllimport)) inlineFuncTmpl2() {} // expected-warning{{'dllimport' attribute ignored on inline function}} - -template __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} -template void inlineFuncTmplDecl() {} - -template __declspec(dllimport) void inlineFuncTmplDef(); -template inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared inline; 'dllimport' attribute ignored}} - -#else // MSVC drops dllimport when the function template is redeclared without it. (It doesn't warn, but we do.) - -template __declspec(dllimport) inline void inlineFuncTmpl1() {} -template inline void __attribute__((dllimport)) inlineFuncTmpl2() {} - -template __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template void inlineFuncTmplDecl() {} // expected-warning{{'inlineFuncTmplDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - -template __declspec(dllimport) void inlineFuncTmplDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - -// Redeclarations -template __declspec(dllimport) void funcTmplRedecl1(); -template __declspec(dllimport) void funcTmplRedecl1(); - -template __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - -template __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -template void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} - -template void funcTmplRedecl4(); // expected-note{{previous declaration is here}} -template __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}} - -#ifdef MS -template void funcTmplRedecl5(); // expected-note{{previous declaration is here}} -template __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}} -#endif - -// Function template friends -struct FuncTmplFriend { - template friend __declspec(dllimport) void funcTmplFriend1(); - template friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - template friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - template friend void funcTmplFriend4(); // expected-note{{previous declaration is here}} -#ifdef GNU -// expected-warning@+4{{'dllimport' attribute ignored on inline function}} -#else -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template friend __declspec(dllimport) inline void funcTmplFriend5(); -}; -template __declspec(dllimport) void funcTmplFriend1(); -template void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template __declspec(dllimport) void funcTmplFriend4(); // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}} -#ifdef MS -// expected-warning@+2{{'funcTmplFriend5' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -template inline void funcTmplFriend5() {} - -// External linkage is required. -template __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}} -template __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}} -namespace { template __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}} -namespace ns { template __declspec(dllimport) void externalFuncTmpl(); } - - -template void funcTmpl() {} -template inline void inlineFuncTmpl() {} -template __declspec(dllimport) void importedFuncTmplDecl(); -#ifdef GNU -// expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template __declspec(dllimport) inline void importedFuncTmpl() {} - -// Import implicit instantiation of an imported function template. -void useFunTmplDecl() { importedFuncTmplDecl(); } -void useFunTmplDef() { importedFuncTmpl(); } - -// Import explicit instantiation declaration of an imported function template. -extern template void importedFuncTmpl(); - -// Import explicit instantiation definition of an imported function template. -// NB: MSVC fails this instantiation without explicit dllimport which is most -// likely a bug because an implicit instantiation is accepted. -template void importedFuncTmpl(); - -// Import specialization of an imported function template. A definition must be -// declared inline. -template<> __declspec(dllimport) void importedFuncTmpl(); -template<> __declspec(dllimport) void importedFuncTmpl() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} -#ifdef MS -template<> __declspec(dllimport) inline void importedFuncTmpl() {} -#endif - -// Not importing specialization of an imported function template without -// explicit dllimport. -template<> void importedFuncTmpl() {} - - -// Import explicit instantiation declaration of a non-imported function template. -extern template __declspec(dllimport) void funcTmpl(); -#ifdef GNU -// expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -extern template __declspec(dllimport) void inlineFuncTmpl(); - -// Import explicit instantiation definition of a non-imported function template. -template __declspec(dllimport) void funcTmpl(); -#ifdef GNU -// expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template __declspec(dllimport) void inlineFuncTmpl(); - -// Import specialization of a non-imported function template. A definition must -// be declared inline. -template<> __declspec(dllimport) void funcTmpl(); -template<> __declspec(dllimport) void funcTmpl() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} -#ifdef GNU -// expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template<> __declspec(dllimport) inline void funcTmpl() {} - - -//===----------------------------------------------------------------------===// -// Class members -//===----------------------------------------------------------------------===// - -// Import individual members of a class. -struct ImportMembers { - struct Nested { - __declspec(dllimport) void normalDecl(); -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} - }; - -#ifdef GNU -// expected-note@+5{{previous attribute is here}} -// expected-warning@+5{{'dllimport' attribute ignored on inline function}} -// expected-warning@+6{{'dllimport' attribute ignored on inline function}} -#endif - __declspec(dllimport) void normalDecl(); - __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} - __declspec(dllimport) void normalInclass() {} - __declspec(dllimport) void normalInlineDef(); - __declspec(dllimport) inline void normalInlineDecl(); -#ifdef GNU -// expected-note@+5{{previous attribute is here}} -// expected-warning@+5{{'dllimport' attribute ignored on inline function}} -// expected-warning@+6{{'dllimport' attribute ignored on inline function}} -#endif - __declspec(dllimport) virtual void virtualDecl(); - __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} - __declspec(dllimport) virtual void virtualInclass() {} - __declspec(dllimport) virtual void virtualInlineDef(); - __declspec(dllimport) virtual inline void virtualInlineDecl(); -#ifdef GNU -// expected-note@+5{{previous attribute is here}} -// expected-warning@+5{{'dllimport' attribute ignored on inline function}} -// expected-warning@+6{{'dllimport' attribute ignored on inline function}} -#endif - __declspec(dllimport) static void staticDecl(); - __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} - __declspec(dllimport) static void staticInclass() {} - __declspec(dllimport) static void staticInlineDef(); - __declspec(dllimport) static inline void staticInlineDecl(); - -protected: - __declspec(dllimport) void protectedDecl(); -private: - __declspec(dllimport) void privateDecl(); -public: - - __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} - __declspec(dllimport) static int StaticField; - __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} - __declspec(dllimport) static const int StaticConstField; - __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} - __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; - __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; - __declspec(dllimport) constexpr static int ConstexprField = 1; - __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} -}; - -#ifdef MS -// expected-warning@+4{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else - // expected-warning@+2{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -void ImportMembers::Nested::normalDef() {} -#ifdef MS -// expected-warning@+4{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else - // expected-warning@+2{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -void ImportMembers::normalDef() {} -#ifdef GNU -// expected-warning@+2{{'ImportMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif -inline void ImportMembers::normalInlineDef() {} - void ImportMembers::normalInlineDecl() {} -#ifdef MS - // expected-warning@+4{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else - // expected-warning@+2{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - void ImportMembers::virtualDef() {} -#ifdef GNU -// expected-warning@+2{{'ImportMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif -inline void ImportMembers::virtualInlineDef() {} - void ImportMembers::virtualInlineDecl() {} -#ifdef MS - // expected-warning@+4{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else - // expected-warning@+2{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - void ImportMembers::staticDef() {} -#ifdef GNU -// expected-warning@+2{{'ImportMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif -inline void ImportMembers::staticInlineDef() {} - void ImportMembers::staticInlineDecl() {} - - int ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} -const int ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} -constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}} - - -// Import on member definitions. -struct ImportMemberDefs { - __declspec(dllimport) void normalDef(); - __declspec(dllimport) void normalInlineDef(); - __declspec(dllimport) virtual void virtualDef(); - __declspec(dllimport) virtual void virtualInlineDef(); - __declspec(dllimport) static void staticDef(); - __declspec(dllimport) static void staticInlineDef(); -#ifdef MS - __declspec(dllimport) inline void normalInlineDecl(); - __declspec(dllimport) virtual inline void virtualInlineDecl(); - __declspec(dllimport) static inline void staticInlineDecl(); -#endif - - __declspec(dllimport) static int StaticField; - __declspec(dllimport) static const int StaticConstField; - __declspec(dllimport) constexpr static int ConstexprField = 1; -}; - -__declspec(dllimport) void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} -__declspec(dllimport) void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} -__declspec(dllimport) void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} -#ifdef MS -__declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {} -__declspec(dllimport) void ImportMemberDefs::normalInlineDecl() {} -__declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {} -__declspec(dllimport) void ImportMemberDefs::virtualInlineDecl() {} -__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {} -__declspec(dllimport) void ImportMemberDefs::staticInlineDecl() {} -#endif - -__declspec(dllimport) int ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} -__declspec(dllimport) const int ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} -__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}} - - -// Import special member functions. -struct ImportSpecials { - __declspec(dllimport) ImportSpecials(); - __declspec(dllimport) ~ImportSpecials(); - __declspec(dllimport) ImportSpecials(const ImportSpecials&); - __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&); - __declspec(dllimport) ImportSpecials(ImportSpecials&&); - __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&); -}; - - -// Import deleted member functions. -struct ImportDeleted { -#ifdef MS - __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} - __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} - __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} - __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} - __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} - __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} - __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} -#else - __declspec(dllimport) ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} - __declspec(dllimport) ~ImportDeleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} - __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} - __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} - __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} - __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} - __declspec(dllimport) void deleted() = delete; // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif -}; - - -// Import allocation functions. -struct ImportAlloc { - __declspec(dllimport) void* operator new(__SIZE_TYPE__); - __declspec(dllimport) void* operator new[](__SIZE_TYPE__); - __declspec(dllimport) void operator delete(void*); - __declspec(dllimport) void operator delete[](void*); -}; - - -// Import defaulted member functions. -struct ImportDefaulted { -#ifdef GNU - // expected-warning@+7{{'dllimport' attribute ignored on inline function}} - // expected-warning@+7{{'dllimport' attribute ignored on inline function}} - // expected-warning@+7{{'dllimport' attribute ignored on inline function}} - // expected-warning@+7{{'dllimport' attribute ignored on inline function}} - // expected-warning@+7{{'dllimport' attribute ignored on inline function}} - // expected-warning@+7{{'dllimport' attribute ignored on inline function}} -#endif - __declspec(dllimport) ImportDefaulted() = default; - __declspec(dllimport) ~ImportDefaulted() = default; - __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default; - __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default; - __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default; - __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default; -}; - - -// Import defaulted member function definitions. -struct ImportDefaultedDefs { - __declspec(dllimport) ImportDefaultedDefs(); -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} - -#ifdef GNU -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -// expected-note@+2{{previous declaration is here}} -#endif - __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&); - __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&); - - __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&); -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) ImportDefaultedDefs &operator=(ImportDefaultedDefs &&); // expected-note{{previous declaration is here}} -}; - -// Not allowed on definitions. -__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} - -#ifdef MS -// expected-warning@+5{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+3{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -// dllimport cannot be dropped. -ImportDefaultedDefs::~ImportDefaultedDefs() = default; - -// Import inline declaration and definition. -#ifdef GNU -// expected-error@+3{{redeclaration of 'ImportDefaultedDefs::ImportDefaultedDefs' cannot add 'dllimport' attribute}} -// expected-warning@+3{{'ImportDefaultedDefs::operator=' redeclared inline; 'dllimport' attribute ignored}} -#endif -__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default; -inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default; - -__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}} -#ifdef MS -// expected-warning@+4{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+2{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -ImportDefaultedDefs &ImportDefaultedDefs::operator=(ImportDefaultedDefs &&) = default; - -// Redeclarations cannot add dllimport. -struct MemberRedecl { - void normalDef(); // expected-note{{previous declaration is here}} - inline void normalInlineDecl(); // expected-note{{previous declaration is here}} - virtual void virtualDef(); // expected-note{{previous declaration is here}} - virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} - static void staticDef(); // expected-note{{previous declaration is here}} - static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} - -#ifdef MS - // expected-note@+4{{previous declaration is here}} - // expected-note@+4{{previous declaration is here}} - // expected-note@+4{{previous declaration is here}} -#endif - void normalInlineDef(); - virtual void virtualInlineDef(); - static void staticInlineDef(); - - static int StaticField; // expected-note{{previous declaration is here}} - static const int StaticConstField; // expected-note{{previous declaration is here}} - constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} -}; - -__declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -__declspec(dllimport) void MemberRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} -__declspec(dllimport) void MemberRedecl::virtualDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -__declspec(dllimport) void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}} -__declspec(dllimport) void MemberRedecl::staticDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -__declspec(dllimport) void MemberRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} - -#ifdef MS -__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}} -__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}} -__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}} -#else -__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif - - - -__declspec(dllimport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}} - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} -__declspec(dllimport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}} - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} -__declspec(dllimport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}} - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} - - - -//===----------------------------------------------------------------------===// -// Class member templates -//===----------------------------------------------------------------------===// - -struct ImportMemberTmpl { - template __declspec(dllimport) void normalDecl(); - template __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -#ifdef MS -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template __declspec(dllimport) void normalInlineDef(); - template __declspec(dllimport) static void staticDecl(); - template __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -#ifdef MS -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template __declspec(dllimport) static void staticInlineDef(); - -#ifdef GNU - template __declspec(dllimport) void normalInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}} - template __declspec(dllimport) inline void normalInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} - template __declspec(dllimport) static void staticInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}} - template __declspec(dllimport) static inline void staticInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}} -#else - template __declspec(dllimport) void normalInclass() {} - template __declspec(dllimport) inline void normalInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} - template __declspec(dllimport) static void staticInclass() {} - template __declspec(dllimport) static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -#endif - -#if __has_feature(cxx_variable_templates) - template __declspec(dllimport) static int StaticField; - template __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} - template __declspec(dllimport) static const int StaticConstField; - template __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} - template __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; - template __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; - template __declspec(dllimport) constexpr static int ConstexprField = 1; - template __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} -#endif // __has_feature(cxx_variable_templates) -}; - -template void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#ifdef GNU // dllimport was ignored above -template void ImportMemberTmpl::normalInlineDecl() {} -template void ImportMemberTmpl::staticInlineDecl() {} -#else // dllimport dropped here -template void ImportMemberTmpl::normalInlineDecl() {} // expected-warning{{'ImportMemberTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template void ImportMemberTmpl::staticInlineDecl() {} // expected-warning{{'ImportMemberTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - -#ifdef GNU -template inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} -template inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#else -template inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - -#if __has_feature(cxx_variable_templates) -template int ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}} -template const int ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}} -template constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}} -#endif // __has_feature(cxx_variable_templates) - - -// Redeclarations cannot add dllimport. -struct MemTmplRedecl { - template void normalDef(); // expected-note{{previous declaration is here}} - template inline void normalInlineDecl(); // expected-note{{previous declaration is here}} - template static void staticDef(); // expected-note{{previous declaration is here}} - template static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} - -#ifdef MS -// expected-note@+3{{previous declaration is here}} -// expected-note@+3{{previous declaration is here}} -#endif - template void normalInlineDef(); - template static void staticInlineDef(); - -#if __has_feature(cxx_variable_templates) - template static int StaticField; // expected-note{{previous declaration is here}} - template static const int StaticConstField; // expected-note{{previous declaration is here}} - template constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} -#endif // __has_feature(cxx_variable_templates) -}; - -template __declspec(dllimport) void MemTmplRedecl::normalDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -#ifdef MS -template __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}} -#else -template __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif -template __declspec(dllimport) void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}} -template __declspec(dllimport) void MemTmplRedecl::staticDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -#ifdef MS -template __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}} -#else -template __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif -template __declspec(dllimport) void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}} - -#if __has_feature(cxx_variable_templates) -template __declspec(dllimport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}} - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} -template __declspec(dllimport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}} - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} -template __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}} - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} -#endif // __has_feature(cxx_variable_templates) - - - -struct MemFunTmpl { - template void normalDef() {} -#ifdef GNU - // expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif - template __declspec(dllimport) void importedNormal() {} - template static void staticDef() {} -#ifdef GNU - // expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif - template __declspec(dllimport) static void importedStatic() {} -}; - -// Import implicit instantiation of an imported member function template. -void useMemFunTmpl() { - MemFunTmpl().importedNormal(); - MemFunTmpl().importedStatic(); -} - -// Import explicit instantiation declaration of an imported member function -// template. -extern template void MemFunTmpl::importedNormal(); -extern template void MemFunTmpl::importedStatic(); - -// Import explicit instantiation definition of an imported member function -// template. -// NB: MSVC fails this instantiation without explicit dllimport. -template void MemFunTmpl::importedNormal(); -template void MemFunTmpl::importedStatic(); - -// Import specialization of an imported member function template. -template<> __declspec(dllimport) void MemFunTmpl::importedNormal(); -template<> __declspec(dllimport) void MemFunTmpl::importedNormal() {} // error on mingw -#ifdef GNU - // expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal() {} -#if 1 -// FIXME: This should not be an error when targeting MSVC. (PR21406) -// expected-error@-7{{dllimport cannot be applied to non-inline function definition}} -#endif - -template<> __declspec(dllimport) void MemFunTmpl::importedStatic(); -template<> __declspec(dllimport) void MemFunTmpl::importedStatic() {} // error on mingw -#ifdef GNU - // expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic() {} -#if 1 -// FIXME: This should not be an error when targeting MSVC. (PR21406) -// expected-error@-7{{dllimport cannot be applied to non-inline function definition}} -#endif - -// Not importing specialization of an imported member function template without -// explicit dllimport. -template<> void MemFunTmpl::importedNormal() {} -template<> void MemFunTmpl::importedStatic() {} - - -// Import explicit instantiation declaration of a non-imported member function -// template. -#ifdef GNU -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -#endif -extern template __declspec(dllimport) void MemFunTmpl::normalDef(); -extern template __declspec(dllimport) void MemFunTmpl::staticDef(); - -// Import explicit instantiation definition of a non-imported member function -// template. -#ifdef GNU -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -// expected-warning@+3{{'dllimport' attribute ignored on inline function}} -#endif -template __declspec(dllimport) void MemFunTmpl::normalDef(); -template __declspec(dllimport) void MemFunTmpl::staticDef(); - -// Import specialization of a non-imported member function template. -template<> __declspec(dllimport) void MemFunTmpl::normalDef(); -template<> __declspec(dllimport) void MemFunTmpl::normalDef() {} // error on mingw -#ifdef GNU - // expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template<> __declspec(dllimport) inline void MemFunTmpl::normalDef() {} -#if 1 -// FIXME: This should not be an error when targeting MSVC. (PR21406) -// expected-error@-7{{dllimport cannot be applied to non-inline function definition}} -#endif - -template<> __declspec(dllimport) void MemFunTmpl::staticDef(); -template<> __declspec(dllimport) void MemFunTmpl::staticDef() {} // error on mingw -#ifdef GNU - // expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -template<> __declspec(dllimport) inline void MemFunTmpl::staticDef() {} -#if 1 -// FIXME: This should not be an error when targeting MSVC. (PR21406) -// expected-error@-7{{dllimport cannot be applied to non-inline function definition}} -#endif - - - -#if __has_feature(cxx_variable_templates) -struct MemVarTmpl { - template static const int StaticVar = 1; - template __declspec(dllimport) static const int ImportedStaticVar = 1; -}; - -// Import implicit instantiation of an imported member variable template. -int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar; } - -// Import explicit instantiation declaration of an imported member variable -// template. -extern template const int MemVarTmpl::ImportedStaticVar; - -// An explicit instantiation definition of an imported member variable template -// cannot be imported because the template must be defined which is illegal. The -// in-class initializer does not count. - -// Import specialization of an imported member variable template. -template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar; -template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar = 1; - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} - -// Not importing specialization of a member variable template without explicit -// dllimport. -template<> const int MemVarTmpl::ImportedStaticVar; - - -// Import explicit instantiation declaration of a non-imported member variable -// template. -extern template __declspec(dllimport) const int MemVarTmpl::StaticVar; - -// An explicit instantiation definition of a non-imported member variable template -// cannot be imported because the template must be defined which is illegal. The -// in-class initializer does not count. - -// Import specialization of a non-imported member variable template. -template<> __declspec(dllimport) const int MemVarTmpl::StaticVar; -template<> __declspec(dllimport) const int MemVarTmpl::StaticVar = 1; - // expected-error@-1{{definition of dllimport static field not allowed}} - // expected-note@-2{{attribute is here}} - -#endif // __has_feature(cxx_variable_templates) - - - -//===----------------------------------------------------------------------===// -// Class template members -//===----------------------------------------------------------------------===// - -// Import individual members of a class template. -template -struct ImportClassTmplMembers { - __declspec(dllimport) void normalDecl(); -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} - __declspec(dllimport) void normalInlineDef(); - __declspec(dllimport) virtual void virtualDecl(); -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) virtual void virtualDef(); // expected-note{{previous declaration is here}} - __declspec(dllimport) virtual void virtualInlineDef(); - __declspec(dllimport) static void staticDecl(); -#ifdef GNU -// expected-note@+2{{previous attribute is here}} -#endif - __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} - __declspec(dllimport) static void staticInlineDef(); - -#ifdef GNU -// expected-warning@+7{{'dllimport' attribute ignored on inline function}} -// expected-warning@+7{{'dllimport' attribute ignored on inline function}} -// expected-warning@+7{{'dllimport' attribute ignored on inline function}} -// expected-warning@+7{{'dllimport' attribute ignored on inline function}} -// expected-warning@+7{{'dllimport' attribute ignored on inline function}} -// expected-warning@+7{{'dllimport' attribute ignored on inline function}} -#endif - __declspec(dllimport) void normalInclass() {} - __declspec(dllimport) inline void normalInlineDecl(); - __declspec(dllimport) virtual void virtualInclass() {} - __declspec(dllimport) virtual inline void virtualInlineDecl(); - __declspec(dllimport) static void staticInclass() {} - __declspec(dllimport) static inline void staticInlineDecl(); - -protected: - __declspec(dllimport) void protectedDecl(); -private: - __declspec(dllimport) void privateDecl(); -public: - - __declspec(dllimport) int Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}} - __declspec(dllimport) static int StaticField; - __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} - __declspec(dllimport) static const int StaticConstField; - __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} - __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; - __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; - __declspec(dllimport) constexpr static int ConstexprField = 1; - __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} -}; - -// NB: MSVC is inconsistent here and disallows *InlineDef on class templates, -// but allows it on classes. We allow both. -#ifdef MS -// expected-warning@+5{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+3{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -template -void ImportClassTmplMembers::normalDef() {} -#ifdef GNU -// expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif -template inline void ImportClassTmplMembers::normalInlineDef() {} -template void ImportClassTmplMembers::normalInlineDecl() {} -#ifdef MS -// expected-warning@+5{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+3{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -template -void ImportClassTmplMembers::virtualDef() {} -#ifdef GNU -// expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif -template inline void ImportClassTmplMembers::virtualInlineDef() {} -template void ImportClassTmplMembers::virtualInlineDecl() {} -#ifdef MS -// expected-warning@+5{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} -#else -// expected-warning@+3{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif -template -void ImportClassTmplMembers::staticDef() {} -#ifdef GNU -// expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#endif -template inline void ImportClassTmplMembers::staticInlineDef() {} -template void ImportClassTmplMembers::staticInlineDecl() {} - -template int ImportClassTmplMembers::StaticFieldDef; // expected-warning{{definition of dllimport static field}} -template const int ImportClassTmplMembers::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} -template constexpr int ImportClassTmplMembers::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}} - - -// Redeclarations cannot add dllimport. -template -struct CTMR /*ClassTmplMemberRedecl*/ { - void normalDef(); // expected-note{{previous declaration is here}} - inline void normalInlineDecl(); // expected-note{{previous declaration is here}} - virtual void virtualDef(); // expected-note{{previous declaration is here}} - virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}} - static void staticDef(); // expected-note{{previous declaration is here}} - static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} - -#ifdef MS -// expected-note@+4{{previous declaration is here}} -// expected-note@+4{{previous declaration is here}} -// expected-note@+4{{previous declaration is here}} -#endif - void normalInlineDef(); - virtual void virtualInlineDef(); - static void staticInlineDef(); - - static int StaticField; // expected-note{{previous declaration is here}} - static const int StaticConstField; // expected-note{{previous declaration is here}} - constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} -}; - -template __declspec(dllimport) void CTMR::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -template __declspec(dllimport) void CTMR::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}} -template __declspec(dllimport) void CTMR::virtualDef() {} // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -template __declspec(dllimport) void CTMR::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}} -template __declspec(dllimport) void CTMR::staticDef() {} // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -template __declspec(dllimport) void CTMR::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}} - -#ifdef MS -template __declspec(dllimport) inline void CTMR::normalInlineDef() {} // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}} -template __declspec(dllimport) inline void CTMR::virtualInlineDef() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}} -template __declspec(dllimport) inline void CTMR::staticInlineDef() {} // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}} -#else -template __declspec(dllimport) inline void CTMR::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -template __declspec(dllimport) inline void CTMR::virtualInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -template __declspec(dllimport) inline void CTMR::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif - -template __declspec(dllimport) int CTMR::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}} - // expected-warning@-1{{definition of dllimport static field}} - // expected-note@-2{{attribute is here}} -template __declspec(dllimport) const int CTMR::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}} - // expected-warning@-1{{definition of dllimport static field}} - // expected-note@-2{{attribute is here}} -template __declspec(dllimport) constexpr int CTMR::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}} - // expected-warning@-1{{definition of dllimport static field}} - // expected-note@-2{{attribute is here}} - - - -//===----------------------------------------------------------------------===// -// Class template member templates -//===----------------------------------------------------------------------===// - -template -struct ImportClsTmplMemTmpl { - template __declspec(dllimport) void normalDecl(); - template __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -#ifdef MS -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template __declspec(dllimport) void normalInlineDef(); - template __declspec(dllimport) static void staticDecl(); - template __declspec(dllimport) static void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} -#ifdef MS -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template __declspec(dllimport) static void staticInlineDef(); - -#ifdef GNU - // expected-warning@+5{{'dllimport' attribute ignored on inline function}} - // expected-warning@+8{{'dllimport' attribute ignored on inline function}} - // expected-warning@+8{{'dllimport' attribute ignored on inline function}} - // expected-warning@+11{{'dllimport' attribute ignored on inline function}} -#endif - template __declspec(dllimport) void normalInclass() {} -#ifdef MS -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template __declspec(dllimport) inline void normalInlineDecl(); - template __declspec(dllimport) static void staticInclass() {} -#ifdef MS -// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}} -#endif - template __declspec(dllimport) static inline void staticInlineDecl(); - -#if __has_feature(cxx_variable_templates) - template __declspec(dllimport) static int StaticField; - template __declspec(dllimport) static int StaticFieldDef; // expected-note{{attribute is here}} - template __declspec(dllimport) static const int StaticConstField; - template __declspec(dllimport) static const int StaticConstFieldDef; // expected-note{{attribute is here}} - template __declspec(dllimport) static const int StaticConstFieldEqualInit = 1; - template __declspec(dllimport) static const int StaticConstFieldBraceInit{1}; - template __declspec(dllimport) constexpr static int ConstexprField = 1; - template __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}} -#endif // __has_feature(cxx_variable_templates) -}; - -template template void ImportClsTmplMemTmpl::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template template void ImportClsTmplMemTmpl::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#ifdef GNU -template template void ImportClsTmplMemTmpl::normalInlineDecl() {} -template template void ImportClsTmplMemTmpl::staticInlineDecl() {} -#else -template template void ImportClsTmplMemTmpl::normalInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template template void ImportClsTmplMemTmpl::staticInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - -#ifdef GNU -template template inline void ImportClsTmplMemTmpl::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}} -template template inline void ImportClsTmplMemTmpl::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}} -#else -template template inline void ImportClsTmplMemTmpl::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -template template inline void ImportClsTmplMemTmpl::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} -#endif - -#if __has_feature(cxx_variable_templates) -template template int ImportClsTmplMemTmpl::StaticFieldDef; // expected-warning{{definition of dllimport static field}} -template template const int ImportClsTmplMemTmpl::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}} -template template constexpr int ImportClsTmplMemTmpl::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}} -#endif // __has_feature(cxx_variable_templates) - - -// Redeclarations cannot add dllimport. -template -struct CTMTR /*ClassTmplMemberTmplRedecl*/ { - template void normalDef(); // expected-note{{previous declaration is here}} - template inline void normalInlineDecl(); // expected-note{{previous declaration is here}} - template static void staticDef(); // expected-note{{previous declaration is here}} - template static inline void staticInlineDecl(); // expected-note{{previous declaration is here}} - -#ifdef MS - // expected-note@+3{{previous declaration is here}} - // expected-note@+3{{previous declaration is here}} -#endif - template void normalInlineDef(); - template static void staticInlineDef(); - -#if __has_feature(cxx_variable_templates) - template static int StaticField; // expected-note{{previous declaration is here}} - template static const int StaticConstField; // expected-note{{previous declaration is here}} - template constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}} -#endif // __has_feature(cxx_variable_templates) -}; - -template template __declspec(dllimport) void CTMTR::normalDef() {} // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -template template __declspec(dllimport) void CTMTR::normalInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}} -template template __declspec(dllimport) void CTMTR::staticDef() {} // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}} - // expected-error@-1{{dllimport cannot be applied to non-inline function definition}} -template template __declspec(dllimport) void CTMTR::staticInlineDecl() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}} - -#ifdef MS -template template __declspec(dllimport) inline void CTMTR::normalInlineDef() {} // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}} -template template __declspec(dllimport) inline void CTMTR::staticInlineDef() {} // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}} -#else -template template __declspec(dllimport) inline void CTMTR::normalInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -template template __declspec(dllimport) inline void CTMTR::staticInlineDef() {} // expected-warning{{'dllimport' attribute ignored on inline function}} -#endif - -#if __has_feature(cxx_variable_templates) -template template __declspec(dllimport) int CTMTR::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}} - // expected-warning@-1{{definition of dllimport static field}} - // expected-note@-2{{attribute is here}} -template template __declspec(dllimport) const int CTMTR::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}} - // expected-warning@-1{{definition of dllimport static field}} - // expected-note@-2{{attribute is here}} -template template __declspec(dllimport) constexpr int CTMTR::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}} - // expected-warning@-1{{definition of dllimport static field}} - // expected-note@-2{{attribute is here}} -#endif // __has_feature(cxx_variable_templates) - - - -//===----------------------------------------------------------------------===// -// Classes -//===----------------------------------------------------------------------===// - -namespace { - struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}} -} - -class __declspec(dllimport) ClassDecl; - -class __declspec(dllimport) ClassDef { }; - -template class ClassTemplate {}; - -#ifdef MS -// expected-note@+5{{previous attribute is here}} -// expected-note@+4{{previous attribute is here}} -// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}} -// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}} -#endif -class __declspec(dllimport) ImportClassWithDllMember { - void __declspec(dllexport) foo(); - void __declspec(dllimport) bar(); -}; - -#ifdef MS -// expected-note@+5{{previous attribute is here}} -// expected-note@+4{{previous attribute is here}} -// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}} -// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}} -#endif -template class __declspec(dllexport) ExportClassWithDllMember { - void __declspec(dllimport) foo(); - void __declspec(dllexport) bar(); -}; - -namespace ImportedExplicitSpecialization { -template struct S { static int x; }; -template int S::x = sizeof(T); -template <> struct __declspec(dllimport) S { static int x; }; // expected-note{{attribute is here}} -int S::x = -1; // expected-error{{definition of dllimport static field not allowed}} -} - -namespace PR19988 { -// Don't error about applying delete to dllimport member function when instantiating. -template struct __declspec(dllimport) S { - void foo() = delete; -}; -S s; -} - -#ifdef MS -// expected-warning@+3{{'dllimport' attribute ignored}} -#endif -template struct PartiallySpecializedClassTemplate {}; -template struct __declspec(dllimport) PartiallySpecializedClassTemplate { void f() {} }; - -template struct ExpliciallySpecializedClassTemplate {}; -template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate { void f() {} }; - - -//===----------------------------------------------------------------------===// -// Classes with template base classes -//===----------------------------------------------------------------------===// - -template class __declspec(dllexport) ExportedClassTemplate {}; - -template class __declspec(dllimport) ImportedClassTemplate {}; - -// ClassTemplate gets imported. -class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate {}; - -// ClassTemplate is already imported. -class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate {}; - -// ImportedClassTemplate is expliitly imported. -class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate {}; - -// ExportedClassTemplate is explicitly exported. -class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate {}; - -class DerivedFromTemplateD : public ClassTemplate {}; -// Base class previously implicitly instantiated without attribute; it will get propagated. -class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate {}; - -// Base class has explicit instantiation declaration; the attribute will get propagated. -extern template class ClassTemplate; -class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate {}; - -class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate {}; -// The second derived class doesn't change anything, the attribute that was propagated first wins. -class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate {}; - -template struct ExplicitlySpecializedTemplate { void func() {} }; -#ifdef MS -// expected-note@+2{{class template 'ExplicitlySpecializedTemplate' was explicitly specialized here}} -#endif -template <> struct ExplicitlySpecializedTemplate { void func() {} }; -template struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate { void func() {} }; -template struct ExplicitlyImportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate { void func() {} }; - -template struct ExplicitlyInstantiatedTemplate { void func() {} }; -#ifdef MS -// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate' was instantiated here}} -#endif -template struct ExplicitlyInstantiatedTemplate; -template struct ExplicitlyExportInstantiatedTemplate { void func() {} }; -template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate; -template struct ExplicitlyImportInstantiatedTemplate { void func() {} }; -template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate; - -#ifdef MS -// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}} -// expected-note@+2{{attribute is here}} -#endif -struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate {}; - -// Base class already specialized with export attribute. -struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate {}; - -// Base class already specialized with import attribute. -struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate {}; - -#ifdef MS -// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}} -// expected-note@+2{{attribute is here}} -#endif -struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate {}; - -// Base class already instantiated with export attribute. -struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate {}; - -// Base class already instantiated with import attribute. -struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate {}; - -template struct ExplicitInstantiationDeclTemplateBase { void func() {} }; -extern template struct ExplicitInstantiationDeclTemplateBase; -struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase {}; - -//===----------------------------------------------------------------------===// -// Lambdas -//===----------------------------------------------------------------------===// -// The MS ABI doesn't provide a stable mangling for lambdas, so they can't be imported or exported. -#ifdef MS -// expected-error@+4{{lambda cannot be declared 'dllimport'}} -#else -// expected-warning@+2{{'dllimport' attribute ignored on inline function}} -#endif -auto Lambda = []() __declspec(dllimport) -> bool { return true; }; Index: test/SemaCXX/warn-unused-filescoped.cpp =================================================================== --- test/SemaCXX/warn-unused-filescoped.cpp +++ test/SemaCXX/warn-unused-filescoped.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-unused-local-typedefs -Wno-c++11-extensions -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-unused-local-typedefs -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-unused-local-typedefs -std=c++14 %s #ifdef HEADER @@ -32,6 +32,14 @@ inline void bar(int, int) { } }; +namespace test8 { +// Should ignore overloaded operators. +template +struct S {}; +template +static bool operator==(S lhs, S rhs) { } +} + namespace pr19713 { #if __cplusplus >= 201103L static constexpr int constexpr1() { return 1; } @@ -65,7 +73,7 @@ template <> void TS::m() { } // expected-warning{{unused}} template - void tf() { } + void tf() { } // expected-warning{{unused}} template <> void tf() { } // expected-warning{{unused}} struct VS { @@ -200,6 +208,28 @@ static void func() {} } +namespace test9 { +template +static void completeRedeclChainForTemplateSpecialization() { } // expected-warning {{unused}} +} + +namespace test10 { +#if __cplusplus >= 201103L +template +constexpr T pi = T(3.14); +#endif + +#if __cplusplus >= 201402L +struct limits { +template +static const T min; +}; + +template +const T limits::min = { }; +#endif +} + namespace pr19713 { #if __cplusplus >= 201103L // FIXME: We should warn on both of these.