| // 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 <typename T> |
| struct TPL { |
| enum class E1 { e1 }; |
| struct IN { |
| enum class E2 { e2 }; |
| }; |
| |
| protected: |
| enum class E3 { e3 }; // expected-note{{declared protected here}} |
| }; |
| |
| using TPL<int>::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<float>::IN::E2::e2; |
| |
| auto a = e1; |
| auto b = e2; |
| #endif |
| |
| enum class E4 { e4 }; |
| template <typename T> |
| struct DER : TPL<int> { |
| using TPL<T>::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<T>::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<float> x; // expected-note{{requested here}} |
| DER<int> y; |
| #if __cplusplus < 202002L |
| // expected-note@-2{{requested here}} |
| #else |
| auto y1 = y.Foo(); |
| auto y2 = y.Bar(); |
| #endif |
| } // namespace Four |
| |
| namespace Five { |
| template <unsigned I, unsigned K> |
| 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 <unsigned I, unsigned K> |
| struct Quux { |
| enum class Q : unsigned; // expected-note{{member is declared here}} |
| enum class R : unsigned { i = I, |
| k = K }; |
| }; |
| |
| template <unsigned I> struct Fido { |
| using Quux<I, I>::Q::nothing; // expected-error{{implicit instantiation of undefined}} |
| }; |
| |
| Fido<2> a; // expected-note{{in instantiation}} |
| |
| } // namespace Six |
| |
| namespace Seven { |
| template <unsigned I, unsigned K> |
| struct Quux { |
| enum class R : unsigned { i = I, |
| k = K }; |
| }; |
| |
| template <unsigned I> struct Toto { |
| using Quux<I, I>::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 |