1 // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s 2 // RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s 3 4 // p1099 'using enum ELABORATED-ENUM-SPECIFIER ;' 5 6 namespace One { 7 namespace Bob { 8 enum A { a, // expected-note{{declared here}} 9 b, 10 c }; 11 class C; // expected-note{{previous use}} 12 enum class D : int; 13 enum class D { d, 14 e, 15 f }; 16 enum class D : int; 17 } // namespace Bob 18 19 using enum Bob::A; 20 #if __cplusplus < 202002 21 // expected-warning@-2{{is a C++20 extension}} 22 #endif 23 using enum Bob::B; // expected-error{{no enum named 'B'}} 24 #if __cplusplus < 202002 25 // expected-warning@-2{{is a C++20 extension}} 26 #endif 27 using enum Bob::C; // expected-error{{tag type that does not match}} 28 #if __cplusplus < 202002 29 // expected-warning@-2{{is a C++20 extension}} 30 #endif 31 auto v = a; 32 33 A g; // expected-error{{unknown type name 'A'}} 34 35 int A; 36 37 using enum Bob::D; 38 #if __cplusplus < 202002 39 // expected-warning@-2{{is a C++20 extension}} 40 #endif 41 } // namespace One 42 43 namespace Two { 44 namespace Kevin { 45 enum class B { d, 46 e, 47 f }; 48 } 49 50 using enum Kevin::B; 51 #if __cplusplus < 202002 52 // expected-warning@-2{{is a C++20 extension}} 53 #endif 54 auto w = e; 55 56 } // namespace Two 57 58 #if __cplusplus >= 202002 59 // Now only check c++20 onwards 60 61 namespace Three { 62 namespace Stuart { 63 enum class C : int; // expected-note{{declared here}} 64 } 65 66 using enum Stuart::C; // expected-error{{is incomplete}} 67 } // namespace Three 68 69 namespace Four { 70 class Dave { 71 public: 72 enum D { a, 73 b, 74 c }; 75 76 private: 77 enum class E { d, // expected-note{{declared private here}} 78 e, 79 f }; 80 }; 81 82 using enum Dave::D; 83 using enum Dave::E; // expected-error{{is a private member}} 84 85 } // namespace Four 86 87 namespace Five { 88 enum class A { b, 89 c }; 90 class Dave { 91 public: 92 using enum A; 93 A f = b; 94 }; 95 96 } // namespace Five 97 98 namespace Six { 99 template <typename T> class TPL; 100 template <> class TPL<int> { 101 public: 102 enum A { a }; 103 }; 104 105 template <typename T> class USR { 106 using enum TPL<T>::B; // expected-error{{cannot name a dependent type}} 107 using enum TPL<int>::A; 108 }; 109 } // namespace Six 110 111 // Now instantiate things 112 namespace Seven { 113 namespace Stuart { 114 enum class A { a, 115 b, 116 c }; 117 } 118 119 static_assert(!int(Stuart::A::a)); 120 constexpr int Bar() { 121 using enum Stuart::A; 122 return int(b); 123 } 124 static_assert(Bar() == 1); 125 126 template <int I> constexpr int Foo() { 127 using enum Stuart::A; 128 return int(b) + I; 129 } 130 131 static_assert(Foo<10>() == 11); 132 133 template <int I> struct C { 134 using enum Stuart::A; 135 static constexpr int V = int(c) + I; 136 137 enum class D { d, 138 e, 139 f }; 140 using enum D; 141 142 static constexpr int W = int(f) + I; 143 }; 144 145 static_assert(C<2>::V == 4); 146 static_assert(C<20>::W == 22); 147 148 } // namespace Seven 149 150 namespace Eight { 151 enum class Bob : int {}; 152 using enum Bob; 153 } // namespace Eight 154 155 namespace Nine { 156 template <int I> struct C { 157 enum class D { i = I }; 158 enum class E : int; // expected-note{{declared here}} 159 }; 160 161 using enum C<2>::D; 162 163 constexpr auto d = i; 164 static_assert(unsigned(d) == 2); 165 166 using enum C<2>::E; // expected-error{{instantiation of undefined member}} 167 } // namespace Nine 168 169 namespace Ten { 170 enum class Bob { a }; 171 172 void Foo() { 173 extern void a(); 174 } 175 176 // We don't see the hidden extern a fn! 177 using enum Bob; 178 179 auto v = a; 180 } // namespace Ten 181 182 namespace Eleven { 183 enum class Bob { a }; // expected-note{{conflicting declaration}} 184 185 struct Base { 186 enum { a }; // expected-note{{target of using}} 187 }; 188 189 template <typename B> 190 class TPLa : B { 191 using enum Bob; 192 using B::a; // expected-error{{target of using declaration}} 193 }; 194 195 TPLa<Base> a; // expected-note{{in instantiation}} 196 197 } // namespace Eleven 198 199 namespace Twelve { 200 enum class Bob { a }; // expected-note{{target of using}} 201 202 struct Base { 203 enum { a }; 204 }; 205 206 template <typename B> 207 class TPLb : B { 208 using B::a; // expected-note{{conflicting declaration}} 209 using enum Bob; // expected-error{{target of using declaration}} 210 }; 211 212 TPLb<Base> b; 213 214 } // namespace Twelve 215 216 namespace Thirteen { 217 enum class Bob { a }; 218 class Foo { 219 using enum Bob; // expected-note{{previous using-enum}} 220 using enum Bob; // expected-error{{redeclaration of using-enum}} 221 }; 222 223 template <typename B> 224 class TPLa { 225 using enum Bob; // expected-note{{previous using-enum}} 226 using enum Bob; // expected-error{{redeclaration of using-enum}} 227 }; 228 229 TPLa<int> a; 230 231 } // namespace Thirteen 232 233 #endif 234