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));
Bar()120 constexpr int Bar() {
121 using enum Stuart::A;
122 return int(b);
123 }
124 static_assert(Bar() == 1);
125
Foo()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
Foo()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