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}}
+ constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
};
__declspec(dllexport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
__declspec(dllexport) int MemberRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
__declspec(dllexport) const int MemberRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
-__declspec(dllexport) constexpr int MemberRedecl::ConstexprField; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+#ifdef MS
+// expected-warning@+4{{attribute declaration must precede definition}}
+#else
+// expected-error@+2{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+#endif
+__declspec(dllexport) constexpr int MemberRedecl::ConstexprField;
#ifdef MS
struct __declspec(dllexport) ClassWithMultipleDefaultCtors {
#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}}
+ template<typename T> constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
#endif // __has_feature(cxx_variable_templates)
};
#if __has_feature(cxx_variable_templates)
template<typename T> __declspec(dllexport) int MemTmplRedecl::StaticField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
template<typename T> __declspec(dllexport) const int MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
-template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+
+#ifdef MS
+// expected-warning@+4{{attribute declaration must precede definition}}
+#else
+// expected-error@+2{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+#endif
+template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField;
#endif // __has_feature(cxx_variable_templates)
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}}
+ constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(definition|declaration)}} is here}}
};
template<typename T> __declspec(dllexport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
template<typename T> __declspec(dllexport) int CTMR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
template<typename T> __declspec(dllexport) const int CTMR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
-template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
+#ifdef MS
+// expected-warning@+4{{attribute declaration must precede definition}}
+#else
+// expected-error@+2{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
+#endif
+template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField;
#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}}
+ template<typename U> constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
#endif // __has_feature(cxx_variable_templates)
};
#if __has_feature(cxx_variable_templates)
template<typename T> template<typename U> __declspec(dllexport) int CTMTR<T>::StaticField = 1; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
template<typename T> template<typename U> __declspec(dllexport) const int CTMTR<T>::StaticConstField = 1; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
-template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
+#ifdef MS
+// expected-warning@+4{{attribute declaration must precede definition}}
+#else
+// expected-error@+2{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
+#endif
+template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField;
#endif // __has_feature(cxx_variable_templates)
// FIXME: Precedence rules seem to be different for classes.
// RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DMS %s
// RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c++1y -Wunsupported-dll-base-class-template -DGNU %s
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++11 -Wunsupported-dll-base-class-template -DGNU %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c++17 -Wunsupported-dll-base-class-template -DGNU %s
// Helper structs to make templates more expressive.
struct ImplicitInst_Imported {};
__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}}
+#if __cplusplus < 201703L && !defined(MS)
+ // expected-note@+2{{attribute is here}}
+#endif
+ __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;
};
#ifdef MS
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}}
+#if __cplusplus < 201703L && !defined(MS)
+// expected-error@+2{{definition of dllimport static field not allowed}}
+#endif
+constexpr int ImportMembers::ConstexprFieldDef;
// Import on member definitions.
__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}}
+#if __cplusplus < 201703L && !defined(MS)
+// expected-error@+3{{definition of dllimport static field not allowed}}
+// expected-note@+2{{attribute is here}}
+#endif
+__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField;
// Import special member functions.
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}}
+ constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
};
__declspec(dllimport) void MemberRedecl::normalDef() {} // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
__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}}
+
+#if __cplusplus < 201703L && !defined(MS)
+// expected-error@+6{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+// expected-error@+5{{definition of dllimport static field not allowed}}
+// expected-note@+4{{attribute is here}}
+#else
+// expected-warning@+2{{attribute declaration must precede definition}}
+#endif
+__declspec(dllimport) constexpr int MemberRedecl::ConstexprField;
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}}
+ template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;
#endif // __has_feature(cxx_variable_templates)
};
#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}}
+#ifdef MS
+template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef;
+#endif
#endif // __has_feature(cxx_variable_templates)
#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}}
+#ifdef MS
+ template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous definition is here}}
+#endif
#endif // __has_feature(cxx_variable_templates)
};
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}}
+#ifdef MS
+// expected-warning@+1{{attribute declaration must precede definition}}
+template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField;
+#endif
#endif // __has_feature(cxx_variable_templates)
__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}}
+#if __cplusplus < 201703L && !defined(MS)
+ // expected-note@+2{{attribute is here}}
+#endif
+ __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;
};
// NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
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}}
+#if __cplusplus < 201703L && !defined(MS)
+// expected-warning@+2{{definition of dllimport static field}}
+#endif
+template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef;
// Redeclarations cannot add dllimport.
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}}
+ constexpr static int ConstexprField = 1; // expected-note-re{{previous {{(declaration|definition)}} is here}}
};
template<typename T> __declspec(dllimport) void CTMR<T>::normalDef() {} // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
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}}
+
+#if __cplusplus < 201703L && !defined(MS)
+// expected-error@+6{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
+// expected-warning@+5{{definition of dllimport static field}}
+// expected-note@+4{{attribute is here}}
+#else
+// expected-warning@+2{{attribute declaration must precede definition}}
+#endif
+template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField;
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}}
+#ifdef MS
+ template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1;
+#endif
#endif // __has_feature(cxx_variable_templates)
};
#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}}
+#ifdef MS
+template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef;
+#endif
#endif // __has_feature(cxx_variable_templates)
#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}}
+#ifdef MS
+ template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous definition is here}}
+#endif
#endif // __has_feature(cxx_variable_templates)
};
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}}
+#ifdef MS
+// expected-warning@+1{{attribute declaration must precede definition}}
+template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField;
+#endif
#endif // __has_feature(cxx_variable_templates)