1 // RUN: %clang_cc1 -std=c++11 -verify %s 2 3 template<typename T> struct A { 4 enum E : T; // expected-note {{here}} 5 E v; 6 E f() { return A::e1; } // expected-error {{no member named 'e1' in 'A<T>'}} 7 E g() { return E::e1; } 8 E h(); 9 }; 10 11 A<int> a; 12 A<int>::E a0 = A<int>().v; 13 int n = A<int>::E::e1; // expected-error {{implicit instantiation of undefined member}} 14 15 template<typename T> enum A<T>::E : T { e1, e2 }; // expected-note 2 {{declared here}} 16 17 // FIXME: Now that A<T>::E is defined, we are supposed to inject its enumerators 18 // into the already-instantiated class A<T>. This seems like a really bad idea, 19 // though, so we don't implement that, but what we do implement is inconsistent. 20 // 21 // Either do as the standard says, or only include enumerators lexically defined 22 // within the class in its scope. 23 A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'; did you mean simply 'e1'?}} 24 25 A<char>::E a2 = A<char>::e2; 26 27 template<typename T> typename A<T>::E A<T>::h() { return e2; } 28 A<short>::E a3 = A<short>().h(); 29 30 31 template<typename T> struct B { 32 enum class E; 33 E v; 34 E f() { return E::e1; } 35 E g(); 36 }; 37 38 B<int> b; 39 B<int>::E b0 = B<int>().v; 40 41 template<typename T> enum class B<T>::E { e1, e2 }; 42 B<int>::E b1 = B<int>::E::e1; 43 44 B<char>::E b2 = B<char>::E::e2; 45 46 template<typename T> typename B<T>::E B<T>::g() { return e2; } 47 B<short>::E b3 = B<short>().g(); 48 49 50 // Enumeration members of class templates can be explicitly specialized. For 51 // unscoped enumerations, specializations must be defined before the primary 52 // template is, since otherwise the primary template will be implicitly 53 // instantiated when we parse the nested name specifier. 54 template<> enum A<long long>::E : long long { e3, e4 }; // expected-error {{explicit specialization of 'E' after instantiation}} expected-note {{first required here}} 55 56 template<> enum class B<long long>::E { e3, e4 }; 57 B<long long>::E b4 = B<long long>::E::e4; 58 59 B<long>::E b5; 60 template<> enum class B<long>::E { e5 }; 61 void fb5() { b5 = decltype(b5)::e5; } 62 B<long>::E b6 = B<long>::E::e5; 63 64 65 template<typename T> struct C { 66 enum class E : T; 67 }; 68 69 template<> enum class C<long long>::E : long long { e3, e4 }; 70 C<long long>::E c0 = C<long long>::E::e3; 71 72 C<long>::E c1; 73 template<> enum class C<long>::E : long { e5 }; 74 void fc1() { c1 = decltype(c1)::e5; } 75 C<long>::E c2 = C<long>::E::e5; 76 77 template<> enum class C<int>::E : int { e6 }; 78 template<typename T> enum class C<T>::E : T { e0 }; 79 C<int>::E c3 = C<int>::E::e6; 80 C<int>::E c4 = C<int>::E::e0; // expected-error {{no member named 'e0' in 'C<int>::E'}} 81 82 83 // Enumeration members can't be partially-specialized. 84 template<typename T> enum class B<T*>::E { e5, e6 }; // expected-error {{nested name specifier for a declaration cannot depend on a template parameter}} 85 86 87 // Explicit specializations can be forward-declared. 88 template<typename T> 89 struct D { 90 enum class E { e1 }; 91 }; 92 template<> enum class D<int>::E; 93 D<int>::E d1 = D<int>::E::e1; // expected-error {{incomplete type 'D<int>::E'}} 94 template<> enum class D<int>::E { e2 }; 95 D<int>::E d2 = D<int>::E::e2; 96 D<char>::E d3 = D<char>::E::e1; // expected-note {{first required here}} 97 D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2' in 'D<char>::E'; did you mean simply 'e2'?}} 98 template<> enum class D<char>::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}} 99 100 template<> enum class D<short>::E; 101 struct F { 102 // Per C++11 [class.friend]p3, these friend declarations have no effect. 103 // Only classes and functions can be friends. 104 template<typename T> friend enum D<T>::E; 105 template<> friend enum D<short>::E; 106 107 template<> friend enum D<double>::E { e3 }; // expected-error {{cannot define a type in a friend declaration}} 108 109 private: 110 static const int n = 1; // expected-note {{private here}} 111 }; 112 template<> enum class D<short>::E { 113 e = F::n // expected-error {{private member}} 114 }; 115 116 class Access { 117 friend class X; 118 119 template<typename T> 120 class Priv { 121 friend class X; 122 123 enum class E : T; 124 }; 125 126 class S { 127 typedef int N; // expected-note {{here}} 128 static const int k = 3; // expected-note {{here}} 129 130 friend class Priv<char>; 131 }; 132 133 static const int k = 5; 134 }; 135 136 template<> enum class Access::Priv<Access::S::N>::E 137 : Access::S::N { // expected-error {{private member}} 138 a = Access::k, // ok 139 b = Access::S::k // expected-error {{private member}} 140 }; 141 142 template<typename T> enum class Access::Priv<T>::E : T { 143 c = Access::k, 144 d = Access::S::k 145 }; 146 147 class X { 148 Access::Priv<int>::E a = Access::Priv<int>::E::a; 149 Access::Priv<char>::E c = Access::Priv<char>::E::d; 150 // FIXME: We should see an access error for this enumerator. 151 Access::Priv<short>::E b = Access::Priv<short>::E::d; 152 }; 153