v.g.vassilev updated this revision to Diff 94293.
v.g.vassilev marked 2 inline comments as done.
v.g.vassilev added a comment.

Iterate over the specs. Diagnose unused variable templates.


https://reviews.llvm.org/D29877

Files:
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/dllimport.cpp
  test/SemaCXX/warn-unused-filescoped.cpp

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 <typename PT1, typename PT2>
+struct S {};
+template <typename PT1, typename PT2>
+static bool operator==(S<PT1, PT2> lhs, S<PT1, PT2> rhs) { }
+}
+
 namespace pr19713 {
 #if __cplusplus >= 201103L
   static constexpr int constexpr1() { return 1; }
@@ -65,7 +73,7 @@
   template <> void TS<int>::m() { }  // expected-warning{{unused}}
 
   template <typename T>
-  void tf() { }
+  void tf() { }  // expected-warning{{unused}}
   template <> void tf<int>() { }  // expected-warning{{unused}}
   
   struct VS {
@@ -200,6 +208,28 @@
 static void func() {}
 }
 
+namespace test9 {
+template<typename T>
+static void completeRedeclChainForTemplateSpecialization() { } // expected-warning {{unused}}
+}
+
+namespace test10 {
+#if __cplusplus >= 201103L
+template<class T>
+constexpr T pi = T(3.14);
+#endif
+
+#if __cplusplus >=  201402L
+struct limits {
+template<typename T>
+static const T min;
+};
+
+template<typename T>
+const T limits::min = { };
+#endif
+}
+
 namespace pr19713 {
 #if __cplusplus >= 201103L
   // FIXME: We should warn on both of these.
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<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
-
-// dllimport implies a declaration.
-template<typename T> __declspec(dllimport) int VarTmplDecl;
-
-// Not allowed on definitions.
-template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
-template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
-template<typename T> 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 <typename T>
-__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 <typename T>
-int ExternVarTmplDeclInit = 1;
-
-#ifdef GNU
-// expected-note@+3{{previous attribute is here}}
-#endif
-template <typename T>
-__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 <typename T>
-int VarTmplDeclInit = 1;
-
-// Redeclarations
-template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
-template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
-
-template<typename T> __declspec(dllimport) int VarTmplRedecl2;
-template<typename T> __declspec(dllimport) int VarTmplRedecl2;
-
-template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-template<typename T>                       extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-
-template<typename T>                       extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
-template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
-
-// External linkage is required.
-template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
-template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
-namespace    { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
-namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
-
 template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
 
-
-template<typename T> int VarTmpl;
-template<typename T> __declspec(dllimport) int ImportedVarTmpl;
-
-// Import implicit instantiation of an imported variable template.
-int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
-
-// Import explicit instantiation declaration of an imported variable template.
-extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
-
-// 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<ExplicitSpec_Imported>;
-template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
-
-// Not importing specialization of an imported variable template without
-// explicit dllimport.
-template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
-
-
-// Import explicit instantiation declaration of a non-imported variable template.
-extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
-
-// Import explicit instantiation definition of a non-imported variable template.
-template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
-
-// Import specialization of a non-imported variable template.
-template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
-template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 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<typename T> __declspec(dllimport) void funcTmplDecl1();
-template<typename T> void __declspec(dllimport) funcTmplDecl2();
-
-// Import function template definition.
-template<typename T> __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<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
-template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
-
-template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}
-template<typename T>                              void inlineFuncTmplDecl() {}
-
-template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
-template<typename T>                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<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
-template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
-
-template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-template<typename T>                              void inlineFuncTmplDecl() {} // expected-warning{{'inlineFuncTmplDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-
-template<typename T> __declspec(dllimport) void inlineFuncTmplDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-template<typename T>                inline void inlineFuncTmplDef() {} // expected-warning{{'inlineFuncTmplDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#endif
-
-// Redeclarations
-template<typename T> __declspec(dllimport) void funcTmplRedecl1();
-template<typename T> __declspec(dllimport) void funcTmplRedecl1();
-
-template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-template<typename T>                       void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-
-template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-
-template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
-template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
-
-#ifdef MS
-template<typename T>                       void funcTmplRedecl5(); // expected-note{{previous declaration is here}}
-template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
-#endif
-
-// Function template friends
-struct FuncTmplFriend {
-  template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
-  template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-  template<typename T> friend __declspec(dllimport) void funcTmplFriend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-  template<typename T> 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<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();
-};
-template<typename T> __declspec(dllimport) void funcTmplFriend1();
-template<typename T>                       void funcTmplFriend2(); // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T>                       void funcTmplFriend3() {} // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T> __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<typename T>                       inline void funcTmplFriend5() {}
-
-// External linkage is required.
-template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
-template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
-namespace    { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
-namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
-
-
-template<typename T> void funcTmpl() {}
-template<typename T> inline void inlineFuncTmpl() {}
-template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
-#ifdef GNU
-// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
-
-// Import implicit instantiation of an imported function template.
-void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }
-void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }
-
-// Import explicit instantiation declaration of an imported function template.
-extern template void importedFuncTmpl<ExplicitDecl_Imported>();
-
-// 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<ExplicitInst_Imported>();
-
-// Import specialization of an imported function template. A definition must be
-// declared inline.
-template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
-#ifdef MS
-template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
-#endif
-
-// Not importing specialization of an imported function template without
-// explicit dllimport.
-template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
-
-
-// Import explicit instantiation declaration of a non-imported function template.
-extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
-#ifdef GNU
-// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
-
-// Import explicit instantiation definition of a non-imported function template.
-template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
-#ifdef GNU
-// expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
-
-// Import specialization of a non-imported function template. A definition must
-// be declared inline.
-template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // 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<ExplicitSpec_InlineDef_Imported>() {}
-
-
-//===----------------------------------------------------------------------===//
-// 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<typename T> __declspec(dllimport)               void normalDecl();
-  template<typename T> __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<typename T> __declspec(dllimport)               void normalInlineDef();
-  template<typename T> __declspec(dllimport) static        void staticDecl();
-  template<typename T> __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<typename T> __declspec(dllimport) static        void staticInlineDef();
-
-#ifdef GNU
-  template<typename T> __declspec(dllimport)               void normalInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
-  template<typename T> __declspec(dllimport)        inline void normalInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}
-  template<typename T> __declspec(dllimport) static        void staticInclass() {} // expected-warning{{'dllimport' attribute ignored on inline function}}
-  template<typename T> __declspec(dllimport) static inline void staticInlineDecl(); // expected-warning{{'dllimport' attribute ignored on inline function}}
-#else
-  template<typename T> __declspec(dllimport)               void normalInclass() {}
-  template<typename T> __declspec(dllimport)        inline void normalInlineDecl(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
-  template<typename T> __declspec(dllimport) static        void staticInclass() {}
-  template<typename T> __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<typename T> __declspec(dllimport) static        int  StaticField;
-  template<typename T> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
-  template<typename T> __declspec(dllimport) static const  int  StaticConstField;
-  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
-  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
-  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
-  template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
-  template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
-#endif // __has_feature(cxx_variable_templates)
-};
-
-template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T>        void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#ifdef GNU // dllimport was ignored above
-template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
-template<typename T>        void ImportMemberTmpl::staticInlineDecl() {}
-#else // dllimport dropped here
-template<typename T>        void ImportMemberTmpl::normalInlineDecl() {} // expected-warning{{'ImportMemberTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T>        void ImportMemberTmpl::staticInlineDecl() {} // expected-warning{{'ImportMemberTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#endif
-
-#ifdef GNU
-template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-#else
-template<typename T> inline void ImportMemberTmpl::normalInlineDef() {} // expected-warning{{ImportMemberTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T> inline void ImportMemberTmpl::staticInlineDef() {} // expected-warning{{ImportMemberTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#endif
-
-#if __has_feature(cxx_variable_templates)
-template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
-template<typename T> const  int  ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
-template<typename T> 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<typename T>               void normalDef();         // expected-note{{previous declaration is here}}
-  template<typename T>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
-  template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
-  template<typename T> 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<typename T>               void normalInlineDef();
-  template<typename T> static        void staticInlineDef();
-
-#if __has_feature(cxx_variable_templates)
-  template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
-  template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
-  template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
-#endif // __has_feature(cxx_variable_templates)
-};
-
-template<typename T> __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<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
-#else
-template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
-#endif
-template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
-template<typename T> __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<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
-#else
-template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
-#endif
-template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
-
-#if __has_feature(cxx_variable_templates)
-template<typename T> __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<typename T> __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<typename T> __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<typename T>                              void normalDef() {}
-#ifdef GNU
-  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-  template<typename T> __declspec(dllimport)        void importedNormal() {}
-  template<typename T>                       static void staticDef() {}
-#ifdef GNU
-  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-  template<typename T> __declspec(dllimport) static void importedStatic() {}
-};
-
-// Import implicit instantiation of an imported member function template.
-void useMemFunTmpl() {
-  MemFunTmpl().importedNormal<ImplicitInst_Imported>();
-  MemFunTmpl().importedStatic<ImplicitInst_Imported>();
-}
-
-// Import explicit instantiation declaration of an imported member function
-// template.
-extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
-extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
-
-// Import explicit instantiation definition of an imported member function
-// template.
-// NB: MSVC fails this instantiation without explicit dllimport.
-template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
-template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
-
-// Import specialization of an imported member function template.
-template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw
-#ifdef GNU
-  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
-#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<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw
-#ifdef GNU
-  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
-#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<ExplicitSpec_NotImported>() {}
-template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
-
-
-// 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<ExplicitDecl_Imported>();
-extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
-
-// 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<ExplicitInst_Imported>();
-template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
-
-// Import specialization of a non-imported member function template.
-template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw
-#ifdef GNU
-  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
-#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<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw
-#ifdef GNU
-  // expected-warning@+2{{'dllimport' attribute ignored on inline function}}
-#endif
-template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
-#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<typename T>                       static const int StaticVar = 1;
-  template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
-};
-
-// Import implicit instantiation of an imported member variable template.
-int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
-
-// Import explicit instantiation declaration of an imported member variable
-// template.
-extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
-
-// 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<ExplicitSpec_Imported>;
-template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 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<ExplicitSpec_NotImported>;
-
-
-// Import explicit instantiation declaration of a non-imported member variable
-// template.
-extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
-
-// 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<ExplicitSpec_Imported>;
-template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 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<typename T>
-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 <typename T>
-void ImportClassTmplMembers<T>::normalDef() {}
-#ifdef GNU
-// expected-warning@+2{{'ImportClassTmplMembers::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-#endif
-template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}
-template<typename T>        void ImportClassTmplMembers<T>::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 <typename T>
-void ImportClassTmplMembers<T>::virtualDef() {}
-#ifdef GNU
-// expected-warning@+2{{'ImportClassTmplMembers::virtualInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-#endif
-template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}
-template<typename T>        void ImportClassTmplMembers<T>::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 <typename T>
-void ImportClassTmplMembers<T>::staticDef() {}
-#ifdef GNU
-// expected-warning@+2{{'ImportClassTmplMembers::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-#endif
-template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
-template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() {}
-
-template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
-template<typename T> const  int  ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
-template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
-
-
-// Redeclarations cannot add dllimport.
-template<typename T>
-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<typename T> __declspec(dllimport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
-                                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
-template<typename T> __declspec(dllimport)        void CTMR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
-template<typename T> __declspec(dllimport)        void CTMR<T>::virtualDef() {}        // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}
-                                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
-template<typename T> __declspec(dllimport)        void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
-template<typename T> __declspec(dllimport)        void CTMR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}
-                                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
-template<typename T> __declspec(dllimport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
-
-#ifdef MS
-template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
-template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
-template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
-#else
-template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
-template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-warning{{'dllimport' attribute ignored on inline function}}
-template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
-#endif
-
-template<typename T> __declspec(dllimport)        int  CTMR<T>::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<typename T> __declspec(dllimport) const  int  CTMR<T>::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<typename T> __declspec(dllimport) constexpr int CTMR<T>::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<typename T>
-struct ImportClsTmplMemTmpl {
-  template<typename U> __declspec(dllimport)               void normalDecl();
-  template<typename U> __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<typename U> __declspec(dllimport)               void normalInlineDef();
-  template<typename U> __declspec(dllimport) static        void staticDecl();
-  template<typename U> __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<typename U> __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<typename U> __declspec(dllimport)               void normalInclass() {}
-#ifdef MS
-// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
-#endif
-  template<typename U> __declspec(dllimport)        inline void normalInlineDecl();
-  template<typename U> __declspec(dllimport) static        void staticInclass() {}
-#ifdef MS
-// expected-note@+2{{previous declaration is here}} expected-note@+2{{previous attribute is here}}
-#endif
-  template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
-
-#if __has_feature(cxx_variable_templates)
-  template<typename U> __declspec(dllimport) static        int  StaticField;
-  template<typename U> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
-  template<typename U> __declspec(dllimport) static const  int  StaticConstField;
-  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
-  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
-  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
-  template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
-  template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
-#endif // __has_feature(cxx_variable_templates)
-};
-
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#ifdef GNU
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {}
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
-#else
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDecl' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#endif
-
-#ifdef GNU
-template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared inline; 'dllimport' attribute ignored}}
-#else
-template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {} // expected-warning{{'ImportClsTmplMemTmpl::staticInlineDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
-#endif
-
-#if __has_feature(cxx_variable_templates)
-template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
-template<typename T> template<typename U> const  int  ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
-template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
-#endif // __has_feature(cxx_variable_templates)
-
-
-// Redeclarations cannot add dllimport.
-template<typename T>
-struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
-  template<typename U>               void normalDef();         // expected-note{{previous declaration is here}}
-  template<typename U>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
-  template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
-  template<typename U> 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<typename U>               void normalInlineDef();
-  template<typename U> static        void staticInlineDef();
-
-#if __has_feature(cxx_variable_templates)
-  template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
-  template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
-  template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
-#endif // __has_feature(cxx_variable_templates)
-};
-
-template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
-                                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
-template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
-template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}
-                                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
-template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
-
-#ifdef MS
-template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
-template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
-#else
-template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
-template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-warning{{'dllimport' attribute ignored on inline function}}
-#endif
-
-#if __has_feature(cxx_variable_templates)
-template<typename T> template<typename U> __declspec(dllimport)        int  CTMTR<T>::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<typename T> template<typename U> __declspec(dllimport) const  int  CTMTR<T>::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<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::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 <typename T> 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 <typename T> class __declspec(dllexport) ExportClassWithDllMember {
-  void __declspec(dllimport) foo();
-  void __declspec(dllexport) bar();
-};
-
-namespace ImportedExplicitSpecialization {
-template <typename T> struct S { static int x; };
-template <typename T> int S<T>::x = sizeof(T);
-template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
-int S<int>::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 <typename> struct __declspec(dllimport) S {
-  void foo() = delete;
-};
-S<int> s;
-}
-
-#ifdef MS
-// expected-warning@+3{{'dllimport' attribute ignored}}
-#endif
-template <typename T> struct PartiallySpecializedClassTemplate {};
-template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
-
-template <typename T> struct ExpliciallySpecializedClassTemplate {};
-template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
-
-
-//===----------------------------------------------------------------------===//
-// Classes with template base classes
-//===----------------------------------------------------------------------===//
-
-template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
-
-template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
-
-// ClassTemplate<int> gets imported.
-class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
-
-// ClassTemplate<int> is already imported.
-class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
-
-// ImportedClassTemplate is expliitly imported.
-class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
-
-// ExportedClassTemplate is explicitly exported.
-class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
-
-class DerivedFromTemplateD : public ClassTemplate<double> {};
-// Base class previously implicitly instantiated without attribute; it will get propagated.
-class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
-
-// Base class has explicit instantiation declaration; the attribute will get propagated.
-extern template class ClassTemplate<float>;
-class __declspec(dllimport) DerivedFromTemplateF : public ClassTemplate<float> {};
-
-class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
-// The second derived class doesn't change anything, the attribute that was propagated first wins.
-class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
-
-template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
-#ifdef MS
-// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
-#endif
-template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
-template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
-template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
-template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
-template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
-
-template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
-#ifdef MS
-// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
-#endif
-template struct ExplicitlyInstantiatedTemplate<int>;
-template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
-template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
-template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
-template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
-
-#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<int> {};
-
-// Base class already specialized with export attribute.
-struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
-
-// Base class already specialized with import attribute.
-struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
-
-#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<int> {};
-
-// Base class already instantiated with export attribute.
-struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
-
-// Base class already instantiated with import attribute.
-struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
-
-template <typename T> struct ExplicitInstantiationDeclTemplateBase { void func() {} };
-extern template struct ExplicitInstantiationDeclTemplateBase<int>;
-struct __declspec(dllimport) DerivedFromExplicitInstantiationDeclTemplateBase : public ExplicitInstantiationDeclTemplateBase<int> {};
-
-//===----------------------------------------------------------------------===//
-// 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: 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<RecordDecl>(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<UnusedAttr>())
@@ -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: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -470,6 +470,13 @@
     return true;
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(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: 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.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to