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