// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s // p1099 'using SCOPEDENUM::MEMBER;' namespace Zero { namespace Bob { enum class Kevin { Stuart, AlsoStuart #if __cplusplus >= 202002L // expected-note@-3{{target of using declaration}} // expected-note@-3{{target of using declaration}} #endif }; } // namespace Bob using Bob::Kevin::Stuart; #if __cplusplus < 202002L // expected-warning@-2{{using declaration naming a scoped enumerator is a C++20 extension}} #else using Bob::Kevin::Stuart; auto b = Stuart; namespace Foo { int Stuart; // expected-note{{conflicting declaration}} using Bob::Kevin::Stuart; // expected-error{{target of using declaration conflicts}} using Bob::Kevin::AlsoStuart; // expected-note{{using declaration}} int AlsoStuart; // expected-error{{declaration conflicts with target}} } // namespace Foo #endif } // namespace Zero namespace One { // derived from [namespace.udecl]/3 enum class button { up, down }; struct S { using button::up; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{using declaration in class}} #else button b = up; #endif }; #if __cplusplus >= 202002L // some more struct T : S { button c = up; }; #endif enum E2 { e2 }; } // namespace One namespace Two { enum class E1 { e1 }; struct S { using One::e2; #if __cplusplus < 202002L // expected-error@-2{{using declaration in class}} #else One::E2 c = e2; #endif }; } // namespace Two namespace Three { enum E3 { e3 }; struct e3; struct S { using Three::e3; // expected-error{{using declaration in class}} enum class E4 { e4 }; enum E5 { e5 }; }; using S::e5; using S::E4::e4; #if __cplusplus < 202002L // expected-error@-3{{using declaration cannot refer to class member}} // expected-note@-4{{use a constexpr variable instead}} // expected-warning@-4{{a C++20 extension}} // expected-error@-5{{using declaration cannot refer to class member}} // expected-note@-6{{use a constexpr variable instead}} #else auto a = e4; auto b = e5; #endif } // namespace Three namespace Four { template struct TPL { enum class E1 { e1 }; struct IN { enum class E2 { e2 }; }; protected: enum class E3 { e3 }; // expected-note{{declared protected here}} }; using TPL::E1::e1; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{using declaration cannot refer to class member}} // expected-note@-4{{use a constexpr variable instead}} #else using TPL::IN::E2::e2; auto a = e1; auto b = e2; #endif enum class E4 { e4 }; template struct DER : TPL { using TPL::E1::e1; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-warning@-3{{using declaration naming a scoped}} // expected-error@-4{{which is not a base}} #endif using TPL::E3::e3; // expected-error{{is a protected member}} #if __cplusplus < 202002L // expected-warning@-2 2{{using declaration naming a scoped}} // expected-error@-3{{which is not a base}} #endif using E4::e4; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{which is not a class}} #else auto Foo() { return e1; } auto Bar() { return e2; } #endif }; DER x; // expected-note{{requested here}} DER y; #if __cplusplus < 202002L // expected-note@-2{{requested here}} #else auto y1 = y.Foo(); auto y2 = y.Bar(); #endif } // namespace Four namespace Five { template struct Quux { enum class Q : unsigned; // expected-note{{member is declared here}} enum class R : unsigned { i = I, k = K }; }; using Quux<1, 2>::Q::nothing; // expected-error{{implicit instantiation of undefined}} using Quux<1, 2>::R::i; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{using declaration cannot refer to class member}} // expected-note@-4{{use a constexpr variable instead}} #endif } // namespace Five namespace Six { template struct Quux { enum class Q : unsigned; // expected-note{{member is declared here}} enum class R : unsigned { i = I, k = K }; }; template struct Fido { using Quux::Q::nothing; // expected-error{{implicit instantiation of undefined}} }; Fido<2> a; // expected-note{{in instantiation}} } // namespace Six namespace Seven { template struct Quux { enum class R : unsigned { i = I, k = K }; }; template struct Toto { using Quux::R::i; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{refers into}} #else static_assert(unsigned(i) == I); #endif }; Toto<2> b; #if __cplusplus < 202002L // expected-note@-2{{in instantiation}} #endif } // namespace Seven namespace Eight { struct Kevin { enum class B { a }; enum a {}; }; using Kevin::B::a; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{using declaration cannot refer to class member}} // expected-note@-4{{use a constexpr variable instead}} #endif using Kevin::B::a; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} // expected-error@-3{{using declaration cannot refer to class member}} // expected-note@-4{{use a constexpr variable instead}} #endif class X : Kevin { using Kevin::B::a; // expected-note{{previous using declaration}} #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} #endif using Kevin::a; using Kevin::B::a; // expected-error{{redeclaration of using declaration}} }; } // namespace Eight namespace Nine { namespace Q { enum class Bob { a }; using Bob::a; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} #endif } // namespace Q using Q::a; using Q::Bob::a; #if __cplusplus < 202002L // expected-warning@-2{{a C++20 extension}} #endif #if __cplusplus >= 202002L struct Foo { using Q::a; // expected-note{{previous using declaration}} using Q::Bob::a; using Q::a; // expected-error{{redeclaration of using declaration}} }; #endif } // namespace Nine