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