// 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