xref: /llvm-project/clang/test/SemaCXX/using-hiding.cpp (revision 9e11a6d8fdd745f20bada10473b701d2e21492a5)
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 namespace A {
4   class X { }; // expected-note{{candidate found by name lookup is 'A::X'}}
5                // expected-note@-1{{candidate found by name lookup is 'A::X'}}
6 }
7 namespace B {
8   void X(int); // expected-note{{candidate found by name lookup is 'B::X'}}
9                // expected-note@-1{{candidate found by name lookup is 'B::X'}}
10 }
11 
12 // Using directive doesn't cause A::X to be hidden, so X is ambiguous.
13 namespace Test1a {
14   using namespace A;
15   using namespace B;
16 
f()17   void f() {
18     X(1); // expected-error{{reference to 'X' is ambiguous}}
19   }
20 }
21 
22 namespace Test1b {
23   using namespace B;
24   using namespace A;
25 
f()26   void f() {
27     X(1); // expected-error{{reference to 'X' is ambiguous}}
28   }
29 }
30 
31 // The behaviour here should be the same as using namespaces A and B directly
32 namespace Test2a {
33   namespace C {
34     using A::X; // expected-note{{candidate found by name lookup is 'Test2a::C::X'}}
35   }
36   namespace D {
37     using B::X; // expected-note{{candidate found by name lookup is 'Test2a::D::X'}}
38   }
39   using namespace C;
40   using namespace D;
41 
f()42   void f() {
43     X(1); // expected-error{{reference to 'X' is ambiguous}}
44   }
45 }
46 
47 namespace Test2b {
48   namespace C {
49     using A::X; // expected-note{{candidate found by name lookup is 'Test2b::C::X'}}
50   }
51   namespace D {
52     using B::X; // expected-note{{candidate found by name lookup is 'Test2b::D::X'}}
53   }
54   using namespace D;
55   using namespace C;
56 
f()57   void f() {
58     X(1); // expected-error{{reference to 'X' is ambiguous}}
59   }
60 }
61 
62 // Defining a function X inside C should hide using A::X in C but not D, so the result is ambiguous.
63 namespace Test3a {
64   namespace C {
65     using A::X;
66     void X(int); // expected-note{{candidate found by name lookup is 'Test3a::C::X'}}
67   }
68   namespace D {
69     using A::X; // expected-note{{candidate found by name lookup is 'Test3a::D::X'}}
70   }
71   using namespace C;
72   using namespace D;
f()73   void f() {
74     X(1); // expected-error{{reference to 'X' is ambiguous}}
75   }
76 }
77 
78 namespace Test3b {
79   namespace C {
80     using A::X;
81     void X(int); // expected-note{{candidate found by name lookup is 'Test3b::C::X'}}
82   }
83   namespace D {
84     using A::X; // expected-note{{candidate found by name lookup is 'Test3b::D::X'}}
85   }
86   using namespace D;
87   using namespace C;
f()88   void f() {
89     X(1); // expected-error{{reference to 'X' is ambiguous}}
90   }
91 }
92 
93 namespace Test3c {
94   namespace C {
95     void X(int); // expected-note{{candidate found by name lookup is 'Test3c::C::X'}}
96     using A::X;
97   }
98   namespace D {
99     using A::X; // expected-note{{candidate found by name lookup is 'Test3c::D::X'}}
100   }
101   using namespace C;
102   using namespace D;
f()103   void f() {
104     X(1); // expected-error{{reference to 'X' is ambiguous}}
105   }
106 }
107 
108 namespace Test3d {
109   namespace C {
110     void X(int); // expected-note{{candidate found by name lookup is 'Test3d::C::X'}}
111     using A::X;
112   }
113   namespace D {
114     using A::X; // expected-note{{candidate found by name lookup is 'Test3d::D::X'}}
115   }
116   using namespace D;
117   using namespace C;
f()118   void f() {
119     X(1); // expected-error{{reference to 'X' is ambiguous}}
120   }
121 }
122 
123 // A::X hidden in both C and D by overloaded function, so the result is not ambiguous.
124 namespace Test4a {
125   namespace C {
126     using A::X;
127     void X(int);
128   }
129   namespace D {
130     using A::X;
131     void X(int, int);
132   }
133   using namespace C;
134   using namespace D;
f()135   void f() {
136     X(1);
137   }
138 }
139 
140 namespace Test4b {
141   namespace C {
142     using A::X;
143     void X(int);
144   }
145   namespace D {
146     using A::X;
147     void X(int, int);
148   }
149   using namespace D;
150   using namespace C;
f()151   void f() {
152     X(1);
153   }
154 }
155 
156 namespace Test4c {
157   namespace C {
158     void X(int);
159     using A::X;
160   }
161   namespace D {
162     void X(int, int);
163     using A::X;
164   }
165   using namespace C;
166   using namespace D;
f()167   void f() {
168     X(1);
169   }
170 }
171 
172 namespace Test4d {
173   namespace C {
174     void X(int);
175     using A::X;
176   }
177   namespace D {
178     void X(int, int);
179     using A::X;
180   }
181   using namespace D;
182   using namespace C;
f()183   void f() {
184     X(1);
185   }
186 }
187 
188 // B::X hides class X in C, so the the result is not ambiguous
189 namespace Test5a {
190   namespace C {
191     using B::X;
192     class X { };
193   }
194   namespace D {
195     using B::X;
196   }
197   using namespace C;
198   using namespace D;
f()199   void f() {
200     X(1);
201   }
202 }
203 
204 namespace Test5b {
205   namespace C {
206     using B::X;
207     class X { };
208   }
209   namespace D {
210     using B::X;
211   }
212   using namespace D;
213   using namespace C;
f()214   void f() {
215     X(1);
216   }
217 }
218 
219 namespace Test5c {
220   namespace C {
221     class X { };
222     using B::X;
223   }
224   namespace D {
225     using B::X;
226   }
227   using namespace C;
228   using namespace D;
f()229   void f() {
230     X(1);
231   }
232 }
233 
234 namespace Test5d {
235   namespace C {
236     class X { };
237     using B::X;
238   }
239   namespace D {
240     using B::X;
241   }
242   using namespace D;
243   using namespace C;
f()244   void f() {
245     X(1);
246   }
247 }
248 
249 // B::X hides class X declared in both C and D, so the result is not ambiguous.
250 namespace Test6a {
251   namespace C {
252     class X { };
253     using B::X;
254   }
255   namespace D {
256     class X { };
257     using B::X;
258   }
259   using namespace C;
260   using namespace D;
f()261   void f() {
262     X(1);
263   }
264 }
265 
266 namespace Test6b {
267   namespace C {
268     class X { };
269     using B::X;
270   }
271   namespace D {
272     class X { };
273     using B::X;
274   }
275   using namespace D;
276   using namespace C;
f()277   void f() {
278     X(1);
279   }
280 }
281 
282 namespace Test6c {
283   namespace C {
284     using B::X;
285     class X { };
286   }
287   namespace D {
288     using B::X;
289     class X { };
290   }
291   using namespace C;
292   using namespace D;
f()293   void f() {
294     X(1);
295   }
296 }
297 
298 namespace Test6d {
299   namespace C {
300     using B::X;
301     class X { };
302   }
303   namespace D {
304     using B::X;
305     class X { };
306   }
307   using namespace D;
308   using namespace C;
f()309   void f() {
310     X(1);
311   }
312 }
313 
314 // function X inside C should hide class X in C but not D.
315 namespace Test7a {
316   namespace C {
317     class X;
318     void X(int); // expected-note{{candidate found by name lookup is 'Test7a::C::X'}}
319   }
320   namespace D {
321     class X; // expected-note{{candidate found by name lookup is 'Test7a::D::X'}}
322   }
323   using namespace C;
324   using namespace D;
f()325   void f() {
326     X(1); // expected-error{{reference to 'X' is ambiguous}}
327   }
328 }
329 
330 namespace Test7b {
331   namespace C {
332     class X;
333     void X(int); // expected-note{{candidate found by name lookup is 'Test7b::C::X'}}
334   }
335   namespace D {
336     class X; // expected-note{{candidate found by name lookup is 'Test7b::D::X'}}
337   }
338   using namespace D;
339   using namespace C;
f()340   void f() {
341     X(1); // expected-error{{reference to 'X' is ambiguous}}
342   }
343 }
344 
345 namespace Test7c {
346   namespace C {
347     void X(int); // expected-note{{candidate found by name lookup is 'Test7c::C::X'}}
348     class X;
349   }
350   namespace D {
351     class X; // expected-note{{candidate found by name lookup is 'Test7c::D::X'}}
352   }
353   using namespace C;
354   using namespace D;
f()355   void f() {
356     X(1); // expected-error{{reference to 'X' is ambiguous}}
357   }
358 }
359 
360 namespace Test7d {
361   namespace C {
362     void X(int); // expected-note{{candidate found by name lookup is 'Test7d::C::X'}}
363     class X;
364   }
365   namespace D {
366     class X; // expected-note{{candidate found by name lookup is 'Test7d::D::X'}}
367   }
368   using namespace D;
369   using namespace C;
f()370   void f() {
371     X(1); // expected-error{{reference to 'X' is ambiguous}}
372   }
373 }
374