| // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s |
| // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s -fexperimental-new-constant-interpreter |
| // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s -fexperimental-new-constant-interpreter |
| |
| // p1099 'using enum ELABORATED-ENUM-SPECIFIER ;' |
| |
| namespace One { |
| namespace Bob { |
| enum A { a, // expected-note{{declared here}} |
| b, |
| c }; |
| class C; |
| enum class D : int; |
| enum class D { d, |
| e, |
| f }; |
| enum class D : int; |
| } // namespace Bob |
| |
| using enum Bob::A; |
| #if __cplusplus < 202002 |
| // expected-warning@-2{{is a C++20 extension}} |
| #endif |
| using enum Bob::B; // expected-error{{unknown type name B}} |
| #if __cplusplus < 202002 |
| // expected-warning@-2{{is a C++20 extension}} |
| #endif |
| using enum Bob::C; // expected-error{{'Bob::C' is not an enumerated type}} |
| #if __cplusplus < 202002 |
| // expected-warning@-2{{is a C++20 extension}} |
| #endif |
| auto v = a; |
| |
| A g; // expected-error{{unknown type name 'A'}} |
| |
| int A; |
| |
| using enum Bob::D; |
| #if __cplusplus < 202002 |
| // expected-warning@-2{{is a C++20 extension}} |
| #endif |
| |
| void DR2621() { |
| using A_t = Bob::A; |
| using enum A_t; |
| #if __cplusplus < 202002 |
| // expected-warning@-2{{is a C++20 extension}} |
| #endif |
| A_t x = a; |
| } |
| |
| } // namespace One |
| |
| namespace Two { |
| namespace Kevin { |
| enum class B { d, |
| e, |
| f }; |
| } |
| |
| using enum Kevin::B; |
| #if __cplusplus < 202002 |
| // expected-warning@-2{{is a C++20 extension}} |
| #endif |
| auto w = e; |
| |
| } // namespace Two |
| |
| #if __cplusplus >= 202002 |
| // Now only check c++20 onwards |
| |
| namespace Three { |
| namespace Stuart { |
| enum class C : int; // expected-note{{declared here}} |
| } |
| |
| using enum Stuart::C; // expected-error{{is incomplete}} |
| } // namespace Three |
| |
| namespace Four { |
| class Dave { |
| public: |
| enum D { a, |
| b, |
| c }; |
| |
| private: |
| enum class E { d, // expected-note{{declared private here}} |
| e, |
| f }; |
| }; |
| |
| using enum Dave::D; |
| using enum Dave::E; // expected-error{{is a private member}} |
| |
| } // namespace Four |
| |
| namespace Five { |
| enum class A { b, |
| c }; |
| class Dave { |
| public: |
| using enum A; |
| A f = b; |
| }; |
| |
| } // namespace Five |
| |
| namespace Six { |
| template <typename T> class TPL; |
| template <> class TPL<int> { |
| public: |
| enum A { a }; |
| }; |
| |
| template <typename T> class USR { |
| using enum TPL<T>::B; // expected-error{{cannot name a dependent type}} |
| using enum TPL<int>::A; |
| }; |
| } // namespace Six |
| |
| // Now instantiate things |
| namespace Seven { |
| namespace Stuart { |
| enum class A { a, |
| b, |
| c }; |
| } |
| |
| static_assert(!int(Stuart::A::a)); |
| constexpr int Bar() { |
| using enum Stuart::A; |
| return int(b); |
| } |
| static_assert(Bar() == 1); |
| |
| template <int I> constexpr int Foo() { |
| using enum Stuart::A; |
| return int(b) + I; |
| } |
| |
| static_assert(Foo<10>() == 11); |
| |
| template <int I> struct C { |
| using enum Stuart::A; |
| static constexpr int V = int(c) + I; |
| |
| enum class D { d, |
| e, |
| f }; |
| using enum D; // expected-error {{using-enum cannot name a dependent type}} |
| }; |
| |
| static_assert(C<2>::V == 4); |
| |
| } // namespace Seven |
| |
| namespace Eight { |
| enum class Bob : int {}; |
| using enum Bob; |
| } // namespace Eight |
| |
| namespace Nine { |
| template <int I> struct C { |
| enum class D { i = I }; |
| enum class E : int; // expected-note{{declared here}} |
| }; |
| |
| using enum C<2>::D; |
| |
| constexpr auto d = i; |
| static_assert(unsigned(d) == 2); |
| |
| using enum C<2>::E; // expected-error{{instantiation of undefined member}} |
| } // namespace Nine |
| |
| namespace Ten { |
| enum class Bob { a }; |
| |
| void Foo() { |
| extern void a(); |
| } |
| |
| // We don't see the hidden extern a fn! |
| using enum Bob; |
| |
| auto v = a; |
| } // namespace Ten |
| |
| namespace Eleven { |
| enum class Bob { a }; // expected-note{{conflicting declaration}} |
| |
| struct Base { |
| enum { a }; // expected-note{{target of using}} |
| }; |
| |
| template <typename B> |
| class TPLa : B { |
| using enum Bob; |
| using B::a; // expected-error{{target of using declaration}} |
| }; |
| |
| TPLa<Base> a; // expected-note{{in instantiation}} |
| |
| } // namespace Eleven |
| |
| namespace Twelve { |
| enum class Bob { a }; // expected-note{{target of using}} |
| |
| struct Base { |
| enum { a }; |
| }; |
| |
| template <typename B> |
| class TPLb : B { |
| using B::a; // expected-note{{conflicting declaration}} |
| using enum Bob; // expected-error{{target of using declaration}} |
| }; |
| |
| TPLb<Base> b; |
| |
| } // namespace Twelve |
| |
| namespace Thirteen { |
| enum class Bob { a }; |
| class Foo { |
| using enum Bob; // expected-note{{previous using-enum}} |
| using enum Bob; // expected-error{{redeclaration of using-enum}} |
| }; |
| |
| template <typename B> |
| class TPLa { |
| using enum Bob; // expected-note{{previous using-enum}} |
| using enum Bob; // expected-error{{redeclaration of using-enum}} |
| }; |
| |
| TPLa<int> a; |
| |
| } // namespace Thirteen |
| |
| namespace Fourteen { |
| template<typename T> |
| int A = T(); |
| |
| using enum A<int>; // expected-error {{A is not an enumerated type}} |
| } // namespace Fourteen |
| |
| namespace GH58057 { |
| struct Wrap { |
| enum Things { |
| Value1, |
| Value2 |
| }; |
| }; |
| |
| using enum Wrap::Things; |
| |
| int f() { |
| return (Value1 | Value2); |
| } |
| } |
| |
| namespace GH59014 { |
| struct X { |
| enum Masks {Mask = 1,Shift = 0}; |
| }; |
| |
| void f(int a) { |
| using enum X::Masks; |
| |
| auto u = (Mask); |
| auto v = (Mask << Shift); |
| void (~(Mask)); |
| } |
| } |
| |
| #endif |