1// RUN: %clang_cc1 -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
2
3
4template <class T>
5class A {
6public:
7   void f(T a) { }// expected-note {{must qualify identifier to find this declaration in dependent base class}}
8   void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
9};
10
11template <class T>
12class B : public A<T> {
13public:
14	void z(T a)
15    {
16       f(a); // expected-warning {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
17       g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
18    }
19};
20
21template class B<int>; // expected-note {{requested here}}
22template class B<char>;
23
24void test()
25{
26    B<int> b;
27    b.z(3);
28}
29
30struct A2 {
31  template<class T> void f(T) {
32    XX; //expected-error {{use of undeclared identifier 'XX'}}
33    A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
34  }
35};
36template void A2::f(int);
37
38template<class T0>
39struct A3 {
40  template<class T1> void f(T1) {
41    XX; //expected-error {{use of undeclared identifier 'XX'}}
42  }
43};
44template void A3<int>::f(int);
45
46template<class T0>
47struct A4 {
48  void f(char) {
49    XX; //expected-error {{use of undeclared identifier 'XX'}}
50  }
51};
52template class A4<int>;
53
54
55namespace lookup_dependent_bases_id_expr {
56
57template<class T> class A {
58public:
59  int var;
60};
61
62
63template<class T>
64class B : public A<T> {
65public:
66  void f() {
67    var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
68  }
69};
70
71template class B<int>;
72
73}
74
75
76
77namespace lookup_dependent_base_class_static_function {
78
79template <class T>
80class A {
81public:
82   static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
83   void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
84};
85
86
87template <class T>
88class B : public A<T> {
89public:
90  static void z2(){
91    static_func();  // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
92    func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
93  }
94};
95template class B<int>; // expected-note {{requested here}}
96
97}
98
99
100
101namespace lookup_dependent_base_class_default_argument {
102
103template<class T>
104class A {
105public:
106  static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
107  int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
108};
109
110template<class T>
111class B : public A<T> {
112public:
113  void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
114  void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
115};
116
117void foo()
118{
119	B<int> b;
120	b.g1(); // expected-note {{required here}}
121	b.g2(); // expected-note {{required here}}
122}
123
124}
125
126
127namespace lookup_dependent_base_class_friend {
128
129template <class T>
130class B {
131public:
132  static void g();  // expected-note {{must qualify identifier to find this declaration in dependent base class}}
133};
134
135template <class T>
136class A : public B<T> {
137public:
138  friend void foo(A<T> p){
139    g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
140  }
141};
142
143int main2()
144{
145  A<int> a;
146  foo(a); // expected-note {{requested here}}
147}
148
149}
150
151
152namespace lookup_dependent_base_no_typo_correction {
153
154class C {
155public:
156  int m_hWnd;
157};
158
159template <class T>
160class A : public T {
161public:
162  void f(int hWnd) {
163    m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
164  }
165};
166
167template class A<C>;
168
169}
170
171namespace PR12701 {
172
173class A {};
174class B {};
175
176template <class T>
177class Base {
178 public:
179  bool base_fun(void* p) { return false; }  // expected-note {{must qualify identifier to find this declaration in dependent base class}}
180  operator T*() const { return 0; }
181};
182
183template <class T>
184class Container : public Base<T> {
185 public:
186  template <typename S>
187  bool operator=(const Container<S>& rhs) {
188    return base_fun(rhs);  // expected-warning {{use of identifier 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
189  }
190};
191
192void f() {
193  Container<A> text_provider;
194  Container<B> text_provider2;
195  text_provider2 = text_provider;  // expected-note {{in instantiation of function template specialization}}
196}
197
198}  // namespace PR12701
199
200namespace PR16014 {
201
202struct A {
203  int a;
204  static int sa;
205};
206template <typename T> struct B : T {
207  int     foo() { return a; }           // expected-warning {{lookup into dependent bases}}
208  int    *bar() { return &a; }          // expected-warning {{lookup into dependent bases}}
209  int     baz() { return T::a; }
210  int T::*qux() { return &T::a; }
211  static int T::*stuff() { return &T::a; }
212  static int stuff1() { return T::sa; }
213  static int *stuff2() { return &T::sa; }
214  static int stuff3() { return sa; }    // expected-warning {{lookup into dependent bases}}
215  static int *stuff4() { return &sa; }  // expected-warning {{lookup into dependent bases}}
216};
217
218template <typename T> struct C : T {
219  int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
220  int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
221  int     baz() { return T::b; }   // expected-error {{no member named 'b' in 'PR16014::A'}}
222  int T::*qux() { return &T::b; }  // expected-error {{no member named 'b' in 'PR16014::A'}}
223  int T::*fuz() { return &U::a; }  // expected-error {{use of undeclared identifier 'U'}}
224};
225
226template struct B<A>;
227template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
228
229template <typename T> struct D : T {
230  struct Inner {
231    int foo() {
232      // FIXME: MSVC can find this in D's base T!  Even worse, if ::sa exists,
233      // clang will use it instead.
234      return sa; // expected-error {{use of undeclared identifier 'sa'}}
235    }
236  };
237};
238template struct D<A>;
239
240}
241
242namespace PR19233 {
243template <class T>
244struct A : T {
245  void foo() {
246    ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
247  }
248  void bar() {
249    ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
250  }
251  void baz() {
252    B::qux(); // expected-error {{use of undeclared identifier 'B'}}
253  }
254};
255
256struct B { void qux(); };
257struct C : B { };
258template struct A<C>; // No error!  B is a base of A<C>, and qux is available.
259
260struct D { };
261template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
262
263}
264
265namespace nonmethod_missing_this {
266template <typename T> struct Base { int y = 42; };
267template <typename T> struct Derived : Base<T> {
268  int x = y; // expected-warning {{lookup into dependent bases}}
269  auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
270    return y * j; // expected-warning {{lookup into dependent bases}}
271  }
272  int bar() {
273    return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
274  }
275};
276template struct Derived<int>;
277}
278
279namespace typedef_in_base {
280template <typename T> struct A { typedef T NameFromBase; };
281template <typename T> struct B : A<T> {
282  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
283};
284static_assert(sizeof(B<int>) == 4, "");
285}
286
287namespace struct_in_base {
288template <typename T> struct A { struct NameFromBase {}; };
289template <typename T> struct B : A<T> {
290  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
291};
292static_assert(sizeof(B<int>) == 1, "");
293}
294
295namespace enum_in_base {
296template <typename T> struct A { enum NameFromBase { X }; };
297template <typename T> struct B : A<T> {
298  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
299};
300static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
301}
302
303namespace two_types_in_base {
304template <typename T> struct A { typedef T NameFromBase; };
305template <typename T> struct B { struct NameFromBase { T m; }; };
306template <typename T> struct C : A<T>, B<T> {
307  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
308};
309static_assert(sizeof(C<int>) == 4, "");
310}
311
312namespace type_and_decl_in_base {
313template <typename T> struct A { typedef T NameFromBase; };
314template <typename T> struct B { static const T NameFromBase = 42; };
315template <typename T> struct C : A<T>, B<T> {
316  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
317};
318}
319
320namespace classify_type_from_base {
321template <typename T> struct A { struct NameFromBase {}; };
322template <typename T> struct B : A<T> {
323  A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
324};
325}
326
327namespace classify_nontype_from_base {
328// MSVC does not do lookup of non-type declarations from dependent template base
329// classes.  The extra lookup only applies to types.
330template <typename T> struct A { void NameFromBase() {} };
331template <void (*F)()> struct B { };
332template <typename T> struct C : A<T> {
333  B<C::NameFromBase> a; // correct
334  B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
335};
336}
337
338namespace template_in_base {
339template <typename T> struct A {
340  template <typename U> struct NameFromBase { U x; };
341};
342template <typename T> struct B : A<T> {
343  // Correct form.
344  typename B::template NameFromBase<T> m;
345};
346template <typename T> struct C : A<T> {
347  // Incorrect form.
348  NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
349  //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
350};
351}
352
353namespace type_in_inner_class_in_base {
354template <typename T>
355struct A {
356  struct B { typedef T NameFromBase; };
357};
358template <typename T>
359struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
360}
361
362namespace type_in_inner_template_class_in_base {
363template <typename T>
364struct A {
365  template <typename U> struct B { typedef U InnerType; };
366};
367template <typename T>
368struct C : A<T>::template B<T> {
369  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
370};
371}
372
373namespace have_nondependent_base {
374template <typename T>
375struct A {
376  // Nothing, lookup should fail.
377};
378template <typename T>
379struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
380struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
381}
382
383namespace type_in_base_of_dependent_base {
384struct A { typedef int NameFromBase; };
385template <typename T>
386struct B : A {};
387// FIXME: MSVC accepts this.
388template <typename T>
389struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
390}
391
392namespace lookup_in_function_contexts {
393template <typename T> struct A { typedef T NameFromBase; };
394template <typename T>
395struct B : A<T> {
396  // expected-warning@+1 {{lookup into dependent bases}}
397  static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
398    return {};
399  }
400
401  static void memberFunc() {
402    NameFromBase x; // expected-warning {{lookup into dependent bases}}
403  }
404
405  static void funcLocalClass() {
406    struct X {
407      NameFromBase x; // expected-warning {{lookup into dependent bases}}
408    } y;
409  }
410
411  void localClassMethod() {
412    struct X {
413      void bar() {
414        NameFromBase m; // expected-warning {{lookup into dependent bases}}
415      }
416    } x;
417    x.bar();
418  }
419
420  static void funcLambda() {
421    auto l = []() {
422      NameFromBase x; // expected-warning {{lookup into dependent bases}}
423    };
424    l();
425  }
426
427  static constexpr int constexprFunc() {
428    NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
429    return sizeof(x);
430  }
431
432  static auto autoFunc() {
433    NameFromBase x; // expected-warning {{lookup into dependent bases}}
434    return x;
435  }
436};
437
438// Force us to parse the methods.
439template struct B<int>;
440}
441
442namespace function_template_deduction {
443// Overloaded function templates.
444template <int N> int f() { return N; }
445template <typename T> int f() { return sizeof(T); }
446
447// Dependent base class with type.
448template <typename T>
449struct A { typedef T NameFromBase; };
450template <typename T>
451struct B : A<T> {
452  // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
453  int x = f<NameFromBase>();
454};
455
456// Dependent base class with enum.
457template <typename T> struct C { enum { NameFromBase = 4 }; };
458template <typename T> struct D : C<T> {
459  // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
460  int x = f<NameFromBase>();
461};
462}
463