xref: /llvm-project/clang/test/SemaCXX/cxx20-using-enum.cpp (revision bc4d50f02ded9eea287daccf2b4a39ae5d30abd0)
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