1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -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 2{{must qualify identifier to find this declaration in dependent base class}}
8   void g();// expected-note 2{{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 2{{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
17       g(); // expected-warning 2{{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>; // expected-note {{requested here}}
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  // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
225};
226
227template struct B<A>;
228template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
229
230template <typename T> struct D : T {
231  struct Inner {
232    int foo() {
233      // FIXME: MSVC can find this in D's base T!  Even worse, if ::sa exists,
234      // clang will use it instead.
235      return sa; // expected-error {{use of undeclared identifier 'sa'}}
236    }
237  };
238};
239template struct D<A>;
240
241}
242
243namespace PR19233 {
244template <class T>
245struct A : T {
246  void foo() {
247    ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
248  }
249  void bar() {
250    ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
251  }
252  void baz() {
253    B::qux(); // expected-error {{use of undeclared identifier 'B'}} \
254    // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
255  }
256};
257
258struct B { void qux(); };
259struct C : B { };
260template struct A<C>; // No error!  B is a base of A<C>, and qux is available.
261
262struct D { };
263template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
264
265}
266
267namespace nonmethod_missing_this {
268template <typename T> struct Base { int y = 42; };
269template <typename T> struct Derived : Base<T> {
270  int x = y; // expected-warning {{lookup into dependent bases}}
271  auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
272    return y * j; // expected-warning {{lookup into dependent bases}}
273  }
274  int bar() {
275    return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
276  }
277};
278template struct Derived<int>;
279}
280
281namespace typedef_in_base {
282template <typename T> struct A { typedef T NameFromBase; };
283template <typename T> struct B : A<T> {
284  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
285};
286static_assert(sizeof(B<int>) == 4, "");
287}
288
289namespace struct_in_base {
290template <typename T> struct A { struct NameFromBase {}; };
291template <typename T> struct B : A<T> {
292  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
293};
294static_assert(sizeof(B<int>) == 1, "");
295}
296
297namespace enum_in_base {
298template <typename T> struct A { enum NameFromBase { X }; };
299template <typename T> struct B : A<T> {
300  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
301};
302static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
303}
304
305namespace two_types_in_base {
306template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}}
307template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
308template <typename T> struct C : A<T>, B<T> {
309  NameFromBase m; // expected-error {{member 'NameFromBase' found in multiple base classes of different types}} expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
310};
311static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
312}
313
314namespace type_and_decl_in_base {
315template <typename T> struct A { typedef T NameFromBase; };
316template <typename T> struct B { static const T NameFromBase = 42; };
317template <typename T> struct C : A<T>, B<T> {
318  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
319};
320}
321
322namespace classify_type_from_base {
323template <typename T> struct A { struct NameFromBase {}; };
324template <typename T> struct B : A<T> {
325  A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
326};
327}
328
329namespace classify_nontype_from_base {
330// MSVC does not do lookup of non-type declarations from dependent template base
331// classes.  The extra lookup only applies to types.
332template <typename T> struct A { void NameFromBase() {} };
333template <void (*F)()> struct B { };
334template <typename T> struct C : A<T> {
335  B<C::NameFromBase> a; // correct
336  B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
337};
338}
339
340namespace template_in_base {
341template <typename T> struct A {
342  template <typename U> struct NameFromBase { U x; };
343};
344template <typename T> struct B : A<T> {
345  // Correct form.
346  typename B::template NameFromBase<T> m;
347};
348template <typename T> struct C : A<T> {
349  // Incorrect form.
350  NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
351  //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
352};
353}
354
355namespace type_in_inner_class_in_base {
356template <typename T>
357struct A {
358  struct B { typedef T NameFromBase; };
359};
360template <typename T>
361struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
362}
363
364namespace type_in_inner_template_class_in_base {
365template <typename T>
366struct A {
367  template <typename U> struct B { typedef U InnerType; };
368};
369template <typename T>
370struct C : A<T>::template B<T> {
371  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
372};
373}
374
375namespace have_nondependent_base {
376template <typename T>
377struct A {
378  // Nothing, lookup should fail.
379};
380template <typename T>
381struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
382struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
383}
384
385namespace type_in_base_of_dependent_base {
386struct A { typedef int NameFromBase; };
387template <typename T>
388struct B : A {};
389template <typename T>
390struct C : B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
391}
392
393namespace type_in_second_dependent_base {
394template <typename T>
395struct A {};
396template<typename T>
397struct B { typedef T NameFromBase; };
398template <typename T>
399struct D : A<T>, B<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
400}
401
402namespace type_in_second_non_dependent_base {
403struct A {};
404struct B { typedef int NameFromBase; };
405template<typename T>
406struct C : A, B {};
407template <typename T>
408struct D : C<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
409}
410
411namespace type_in_virtual_base_of_dependent_base {
412template <typename T>
413struct A { typedef T NameFromBase; };
414template <typename T>
415struct B : virtual A<T> {};
416template <typename T>
417struct C : B<T>, virtual A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
418C<int> c;
419}
420
421namespace type_in_base_of_multiple_dependent_bases {
422template <typename T>
423struct A { typedef T NameFromBase; };
424template <typename T>
425struct B : public A<T> {};
426template <typename T>
427struct C : B<T>, public A<T> { NameFromBase m; }; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-warning {{direct base 'A<int>' is inaccessible due to ambiguity:}}
428C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}
429}
430
431namespace type_in_dependent_base_of_non_dependent_type {
432template<typename T> struct A { typedef int NameFromBase; };
433template<typename T> struct B : A<T> {
434  struct C;
435  template<typename TT>
436  struct D : C {
437    NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
438  };
439  struct E : C {
440    NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
441  };
442};
443template<typename T> struct B<T>::C : B {
444  NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
445};
446template<typename T> struct F : B<T>::C {
447  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
448};
449}
450
451namespace lookup_in_function_contexts {
452template <typename T> struct A { typedef T NameFromBase; };
453template <typename T>
454struct B : A<T> {
455  // expected-warning@+1 {{lookup into dependent bases}}
456  static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
457    return {};
458  }
459
460  static void memberFunc() {
461    NameFromBase x; // expected-warning {{lookup into dependent bases}}
462  }
463
464  static void funcLocalClass() {
465    struct X {
466      NameFromBase x; // expected-warning {{lookup into dependent bases}}
467    } y;
468  }
469
470  void localClassMethod() {
471    struct X {
472      void bar() {
473        NameFromBase m; // expected-warning {{lookup into dependent bases}}
474      }
475    } x;
476    x.bar();
477  }
478
479  static void funcLambda() {
480    auto l = []() {
481      NameFromBase x; // expected-warning {{lookup into dependent bases}}
482    };
483    l();
484  }
485
486  static constexpr int constexprFunc() {
487    NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
488    return sizeof(x);
489  }
490
491  static auto autoFunc() {
492    NameFromBase x; // expected-warning {{lookup into dependent bases}}
493    return x;
494  }
495};
496
497// Force us to parse the methods.
498template struct B<int>;
499}
500
501namespace function_template_deduction {
502// Overloaded function templates.
503template <int N> int f() { return N; }
504template <typename T> int f() { return sizeof(T); }
505
506// Dependent base class with type.
507template <typename T>
508struct A { typedef T NameFromBase; };
509template <typename T>
510struct B : A<T> {
511  // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
512  int x = f<NameFromBase>();
513};
514
515// Dependent base class with enum.
516template <typename T> struct C { enum { NameFromBase = 4 }; };
517template <typename T> struct D : C<T> {
518  // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
519  int x = f<NameFromBase>();
520};
521}
522
523namespace function_template_undef_impl {
524template<class T>
525void f() {
526  Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}
527  UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}
528}
529}
530
531namespace PR20716 {
532template <template <typename T> class A>
533struct B : A<int>
534{
535  XXX x; // expected-error {{unknown type name}}
536};
537
538template <typename T>
539struct C {};
540
541template <typename T>
542using D = C<T>;
543
544template <typename T>
545struct E : D<T>
546{
547  XXX x; // expected-error {{unknown type name}}
548};
549}
550
551namespace PR23810 {
552void f(int);
553struct Base {
554  void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}
555};
556template <typename T> struct Template : T {
557  void member() {
558    f(); // expected-warning {{found via unqualified lookup into dependent bases}}
559  }
560};
561void test() {
562  Template<Base> x;
563  x.member(); // expected-note{{requested here}}
564};
565}
566
567namespace PR23823 {
568// Don't delay lookup in SFINAE context.
569template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}}
570decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}}
571
572void h();
573template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}
574decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}
575}
576
577// We also allow unqualified lookup into bases in contexts where the we know the
578// undeclared identifier *must* be a type, such as a new expression or catch
579// parameter type.
580template <typename T>
581struct UseUnqualifiedTypeNames : T {
582  void foo() {
583    void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
584    size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}}
585    try {
586    } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}}
587    }
588    enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}}
589    _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}}
590  }
591  void out_of_line();
592};
593template <typename T>
594void UseUnqualifiedTypeNames<T>::out_of_line() {
595  void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
596}
597struct Base {
598  typedef int IntegerType;
599  struct TheType {
600    int f1, f2;
601  };
602};
603template struct UseUnqualifiedTypeNames<Base>;
604struct BadBase { };
605template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}}
606
607namespace partial_template_lookup {
608
609class Bar;
610class Spare;
611
612template <class T, class X = Bar>
613class FooTemplated;
614
615class FooBase {
616public:
617  typedef int BaseTypedef;
618};
619
620// Partial template spec (unused)
621template <class T>
622class FooTemplated<T, Spare> {};
623
624// Partial template spec (used)
625template <class T>
626class FooTemplated<T, Bar> : public FooBase {};
627
628// Full template spec
629template <class T, class X>
630class FooTemplated : public FooTemplated<T, Bar> {
631public:
632  BaseTypedef Member; // expected-warning {{unqualified lookup}}
633};
634}
635