// RUN: %clang_cc1 -std=c++11 -verify %s template struct A { enum E : T; // expected-note {{here}} E v; E f() { return A::e1; } // expected-error {{no member named 'e1' in 'A'}} E g() { return E::e1; } E h(); }; A a; A::E a0 = A().v; int n = A::E::e1; // expected-error {{implicit instantiation of undefined member}} template enum A::E : T { e1, e2 }; // expected-note 2 {{declared here}} // FIXME: Now that A::E is defined, we are supposed to inject its enumerators // into the already-instantiated class A. This seems like a really bad idea, // though, so we don't implement that, but what we do implement is inconsistent. // // Either do as the standard says, or only include enumerators lexically defined // within the class in its scope. A::E a1 = A::e1; // expected-error {{no member named 'e1' in 'A'; did you mean simply 'e1'?}} A::E a2 = A::e2; template typename A::E A::h() { return e2; } A::E a3 = A().h(); template struct B { enum class E; E v; E f() { return E::e1; } E g(); }; B b; B::E b0 = B().v; template enum class B::E { e1, e2 }; B::E b1 = B::E::e1; B::E b2 = B::E::e2; template typename B::E B::g() { return e2; } B::E b3 = B().g(); // Enumeration members of class templates can be explicitly specialized. For // unscoped enumerations, specializations must be defined before the primary // template is, since otherwise the primary template will be implicitly // instantiated when we parse the nested name specifier. template<> enum A::E : long long { e3, e4 }; // expected-error {{explicit specialization of 'E' after instantiation}} expected-note {{first required here}} template<> enum class B::E { e3, e4 }; B::E b4 = B::E::e4; B::E b5; template<> enum class B::E { e5 }; void fb5() { b5 = decltype(b5)::e5; } B::E b6 = B::E::e5; template struct C { enum class E : T; }; template<> enum class C::E : long long { e3, e4 }; C::E c0 = C::E::e3; C::E c1; template<> enum class C::E : long { e5 }; void fc1() { c1 = decltype(c1)::e5; } C::E c2 = C::E::e5; template<> enum class C::E : int { e6 }; template enum class C::E : T { e0 }; C::E c3 = C::E::e6; C::E c4 = C::E::e0; // expected-error {{no member named 'e0' in 'C::E'}} // Enumeration members can't be partially-specialized. template enum class B::E { e5, e6 }; // expected-error {{nested name specifier for a declaration cannot depend on a template parameter}} // Explicit specializations can be forward-declared. template struct D { enum class E { e1 }; }; template<> enum class D::E; D::E d1 = D::E::e1; // expected-error {{incomplete type 'D::E'}} template<> enum class D::E { e2 }; D::E d2 = D::E::e2; D::E d3 = D::E::e1; // expected-note {{first required here}} D::E d4 = D::E::e2; // expected-error {{no member named 'e2' in 'D::E'; did you mean simply 'e2'?}} template<> enum class D::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}} template<> enum class D::E; struct F { // Per C++11 [class.friend]p3, these friend declarations have no effect. // Only classes and functions can be friends. template friend enum D::E; template<> friend enum D::E; template<> friend enum D::E { e3 }; // expected-error {{cannot define a type in a friend declaration}} private: static const int n = 1; // expected-note {{private here}} }; template<> enum class D::E { e = F::n // expected-error {{private member}} }; class Access { friend class X; template class Priv { friend class X; enum class E : T; }; class S { typedef int N; // expected-note {{here}} static const int k = 3; // expected-note {{here}} friend class Priv; }; static const int k = 5; }; template<> enum class Access::Priv::E : Access::S::N { // expected-error {{private member}} a = Access::k, // ok b = Access::S::k // expected-error {{private member}} }; template enum class Access::Priv::E : T { c = Access::k, d = Access::S::k }; class X { Access::Priv::E a = Access::Priv::E::a; Access::Priv::E c = Access::Priv::E::d; // FIXME: We should see an access error for this enumerator. Access::Priv::E b = Access::Priv::E::d; };