Clang Project

clang_source_code/test/SemaTemplate/cxx1z-using-declaration.cpp
1// RUN: %clang_cc1 -std=c++1z -verify %s
2
3// Test that we cope with failure to expand a pack.
4template<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};
12void 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.
19template<typename ...T> struct A : T... { // expected-note 2{{candidate}}
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
31namespace 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); // expected-note {{not viable}}
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.
92template<typename X, typename Y, typename ...T> struct B : X, Y {
93  using X::operator T* ...;
94};
95
96namespace 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.
106template<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
111namespace 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.
129template<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
135namespace 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.
151template<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.
159template<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
171namespace 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}} expected-note {{not viable}}
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); // expected-note {{not viable}}
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
209namespace 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}
231