Mercurial > hg > CbC > CbC_llvm
comparison clang/test/SemaTemplate/cxx1z-using-declaration.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | 2e18cbf3894f |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 // RUN: %clang_cc1 -std=c++1z -verify %s | |
2 | |
3 // Test that we cope with failure to expand a pack. | |
4 template<typename ...T> struct Unexpanded : T... { | |
5 using T::f; // expected-error {{unexpanded}} | |
6 using typename T::type; // expected-error {{unexpanded}} | |
7 template<typename ...U> void g(U ...u) { f(u...); } // expected-error {{undeclared identifier 'f'}} | |
8 void h() { | |
9 Unexpanded<type...> *p; // expected-error {{undeclared identifier 'type'}} | |
10 } | |
11 }; | |
12 void test_Unexpanded() { | |
13 struct A { void f(); }; // expected-note {{must qualify}} | |
14 struct B { void f(int); }; // expected-note {{must qualify}} | |
15 Unexpanded<A, B>().g(0); // expected-note {{instantiation of}} | |
16 } | |
17 | |
18 // Test using non-type members from pack of base classes. | |
19 template<typename ...T> struct A : T... { | |
20 using T::T ...; // expected-note 2{{inherited here}} | |
21 using T::operator() ...; | |
22 using T::operator T* ...; | |
23 using T::h ...; | |
24 | |
25 void f(int n) { h(n); } // expected-error {{ambiguous}} | |
26 void f(int n, int m) { h(n, m); } // expected-error {{member using declaration 'h' instantiates to an empty pack}} | |
27 void g(int n) { (*this)(n); } // expected-error {{ambiguous}} | |
28 void g(int n, int m) { (*this)(n, m); } // expected-error {{does not provide a call operator}} | |
29 }; | |
30 | |
31 namespace test_A { | |
32 struct X { | |
33 X(); | |
34 X(int); // expected-note {{candidate}} | |
35 void operator()(int); // expected-note 2{{candidate}} | |
36 operator X *(); | |
37 void h(int); // expected-note {{candidate}} | |
38 }; | |
39 struct Y { | |
40 Y(); | |
41 Y(int, int); | |
42 void operator()(int, int); | |
43 operator Y *(); | |
44 void h(int, int); | |
45 }; | |
46 struct Z { | |
47 Z(); | |
48 Z(int); // expected-note {{candidate}} | |
49 void operator()(int); // expected-note 2{{candidate}} | |
50 operator Z *(); | |
51 void h(int); // expected-note {{candidate}} | |
52 }; | |
53 | |
54 void f() { | |
55 A<> a; | |
56 a.f(0, 0); // expected-note {{instantiation of}} | |
57 a.g(0, 0); // expected-note {{instantiation of}} | |
58 | |
59 A<X, Y> axy(0); | |
60 A<X, Y>(0, 0); | |
61 axy.f(0); | |
62 axy.f(0, 0); | |
63 axy.g(0); | |
64 axy.g(0, 0); | |
65 axy(0); | |
66 axy(0, 0); | |
67 | |
68 A<X, Y, Z>(0); // expected-error {{ambiguous}} | |
69 A<X, Y, Z> axyz(0, 0); | |
70 axyz.f(0); // expected-note {{instantiation of}} | |
71 axyz.f(0, 0); | |
72 axyz.g(0); // expected-note {{instantiation of}} | |
73 axyz.g(0, 0); | |
74 axyz(0); // expected-error {{ambiguous}} | |
75 axyz(0, 0); | |
76 | |
77 X *x; | |
78 x = a; // expected-error {{incompatible}} | |
79 x = axy; | |
80 x = axyz; | |
81 x = a.operator X*(); // expected-error {{no member}} | |
82 x = axy.operator X*(); | |
83 x = axyz.operator X*(); | |
84 | |
85 Z *z; | |
86 z = axyz; | |
87 z = axyz.operator Z*(); | |
88 } | |
89 } | |
90 | |
91 // Test using pack of non-type members from single base class. | |
92 template<typename X, typename Y, typename ...T> struct B : X, Y { | |
93 using X::operator T* ...; | |
94 }; | |
95 | |
96 namespace test_B { | |
97 struct X { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}} | |
98 struct Y { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}} | |
99 B<X, Y, int, float> bif; | |
100 int *pi = bif; | |
101 float *pf = bif; | |
102 char *pc = bif; // expected-error {{ambiguous}} | |
103 } | |
104 | |
105 // Test using type member from pack of base classes. | |
106 template<typename ...T> struct C : T... { | |
107 using typename T::type ...; // expected-error {{target of using declaration conflicts}} | |
108 void f() { type value; } // expected-error {{member using declaration 'type' instantiates to an empty pack}} | |
109 }; | |
110 | |
111 namespace test_C { | |
112 struct X { typedef int type; }; | |
113 struct Y { typedef int type; }; // expected-note {{conflicting}} | |
114 struct Z { typedef float type; }; // expected-note {{target}} | |
115 | |
116 void f() { | |
117 C<> c; | |
118 c.f(); // expected-note {{instantiation of}} | |
119 | |
120 C<X, Y> cxy; | |
121 cxy.f(); | |
122 | |
123 C<X, Y, Z> cxyz; // expected-note {{instantiation of}} | |
124 cxyz.f(); | |
125 } | |
126 } | |
127 | |
128 // Test using pack of non-types at block scope. | |
129 template<typename ...T> int fn1() { | |
130 using T::e ...; // expected-error 2{{class member}} expected-note 2{{instead}} | |
131 // expected-error@-1 2{{produces multiple values}} | |
132 return e; // expected-error {{using declaration 'e' instantiates to an empty pack}} | |
133 } | |
134 | |
135 namespace test_fn1 { | |
136 struct X { static int e; }; | |
137 struct Y { typedef int e; }; | |
138 inline namespace P { enum E { e }; } | |
139 inline namespace Q { enum F { e }; } | |
140 void f() { | |
141 fn1<>(); // expected-note {{instantiation of}} | |
142 fn1<X>(); // expected-note {{instantiation of}} | |
143 fn1<Y>(); // expected-note {{instantiation of}} | |
144 fn1<E>(); | |
145 fn1<E, F>(); // expected-note {{instantiation of}} | |
146 fn1<E, X>(); // expected-note {{instantiation of}} | |
147 } | |
148 } | |
149 | |
150 // Test using pack of types at block scope. | |
151 template<typename ...T> void fn2() { | |
152 // This cannot ever be valid: in order for T::type to be a type, T must be a | |
153 // class, and a class member cannot be named by a block-scope using declaration. | |
154 using typename T::type ...; // expected-error {{class member}} | |
155 type x; // expected-error {{unknown type name 'type'}} | |
156 } | |
157 | |
158 // Test partial substitution into class-scope pack. | |
159 template<typename ...T> auto lambda1() { | |
160 return [](auto x) { | |
161 struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}} | |
162 using T::template X<decltype(x)>::f ...; | |
163 using typename T::template X<decltype(x)>::type ...; | |
164 void g(int n) { f(n); } // expected-error {{empty pack}} expected-error {{expected 2, have 1}} expected-error {{ambiguous}} | |
165 void h() { type value; } // expected-error {{empty pack}} | |
166 }; | |
167 return A(); | |
168 }; | |
169 } | |
170 | |
171 namespace test_lambda1 { | |
172 struct A { | |
173 template<typename> struct X { | |
174 void f(int); // expected-note {{candidate}} | |
175 using type = int; | |
176 }; | |
177 }; | |
178 struct B { | |
179 template<typename> struct X { | |
180 void f(int, int); // expected-note {{declared here}} | |
181 using type = int; | |
182 }; | |
183 }; | |
184 struct C { | |
185 template<typename> struct X { | |
186 void f(int); // expected-note {{candidate}} | |
187 void f(int, int); | |
188 using type = int; | |
189 }; | |
190 }; | |
191 | |
192 void f() { | |
193 lambda1<>() // expected-note 2{{instantiation of}} | |
194 (0) | |
195 // FIXME: This is poor error recovery | |
196 .g(0); // expected-error {{no member named 'g'}} | |
197 lambda1<A>() | |
198 (0) | |
199 .g(0); | |
200 lambda1<B>() | |
201 (0) // expected-note {{instantiation of}} | |
202 .g(0); | |
203 lambda1<A, B, C>() | |
204 (0) // expected-note {{instantiation of}} | |
205 .g(0); | |
206 } | |
207 } | |
208 | |
209 namespace p0195r2_example { | |
210 template<typename ...Ts> | |
211 struct Overloader : Ts... { | |
212 using Ts::operator() ...; | |
213 }; | |
214 | |
215 template<typename ...Ts> | |
216 constexpr auto make_overloader(Ts &&...ts) { | |
217 return Overloader<Ts...>{static_cast<Ts&&>(ts)...}; | |
218 } | |
219 | |
220 void test() { | |
221 auto o = make_overloader( | |
222 [&](int &r) -> int & { return r; }, // expected-note {{candidate function}} | |
223 [&](float &r) -> float & { return r; } // expected-note {{candidate function}} | |
224 ); | |
225 int a; float f; double d; | |
226 int &ra = o(a); | |
227 float &rf = o(f); | |
228 double &rd = o(d); // expected-error {{no matching function}} | |
229 } | |
230 } |