annotate clang/test/SemaTemplate/cxx1z-using-declaration.cpp @ 150:1d019706d866

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