xref: /aosp_15_r20/external/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li 
4*67e74705SXin Li template <class T>
5*67e74705SXin Li class A {
6*67e74705SXin Li public:
f(T a)7*67e74705SXin Li    void f(T a) { }// expected-note 2{{must qualify identifier to find this declaration in dependent base class}}
8*67e74705SXin Li    void g();// expected-note 2{{must qualify identifier to find this declaration in dependent base class}}
9*67e74705SXin Li };
10*67e74705SXin Li 
11*67e74705SXin Li template <class T>
12*67e74705SXin Li class B : public A<T> {
13*67e74705SXin Li public:
z(T a)14*67e74705SXin Li 	void z(T a)
15*67e74705SXin Li     {
16*67e74705SXin Li        f(a); // expected-warning 2{{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
17*67e74705SXin Li        g(); // expected-warning 2{{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
18*67e74705SXin Li     }
19*67e74705SXin Li };
20*67e74705SXin Li 
21*67e74705SXin Li template class B<int>; // expected-note {{requested here}}
22*67e74705SXin Li template class B<char>; // expected-note {{requested here}}
23*67e74705SXin Li 
test()24*67e74705SXin Li void test()
25*67e74705SXin Li {
26*67e74705SXin Li     B<int> b;
27*67e74705SXin Li     b.z(3);
28*67e74705SXin Li }
29*67e74705SXin Li 
30*67e74705SXin Li struct A2 {
fA231*67e74705SXin Li   template<class T> void f(T) {
32*67e74705SXin Li     XX; //expected-error {{use of undeclared identifier 'XX'}}
33*67e74705SXin Li     A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
34*67e74705SXin Li   }
35*67e74705SXin Li };
36*67e74705SXin Li template void A2::f(int);
37*67e74705SXin Li 
38*67e74705SXin Li template<class T0>
39*67e74705SXin Li struct A3 {
fA340*67e74705SXin Li   template<class T1> void f(T1) {
41*67e74705SXin Li     XX; //expected-error {{use of undeclared identifier 'XX'}}
42*67e74705SXin Li   }
43*67e74705SXin Li };
44*67e74705SXin Li template void A3<int>::f(int);
45*67e74705SXin Li 
46*67e74705SXin Li template<class T0>
47*67e74705SXin Li struct A4 {
fA448*67e74705SXin Li   void f(char) {
49*67e74705SXin Li     XX; //expected-error {{use of undeclared identifier 'XX'}}
50*67e74705SXin Li   }
51*67e74705SXin Li };
52*67e74705SXin Li template class A4<int>;
53*67e74705SXin Li 
54*67e74705SXin Li 
55*67e74705SXin Li namespace lookup_dependent_bases_id_expr {
56*67e74705SXin Li 
57*67e74705SXin Li template<class T> class A {
58*67e74705SXin Li public:
59*67e74705SXin Li   int var;
60*67e74705SXin Li };
61*67e74705SXin Li 
62*67e74705SXin Li 
63*67e74705SXin Li template<class T>
64*67e74705SXin Li class B : public A<T> {
65*67e74705SXin Li public:
f()66*67e74705SXin Li   void f() {
67*67e74705SXin Li     var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
68*67e74705SXin Li   }
69*67e74705SXin Li };
70*67e74705SXin Li 
71*67e74705SXin Li template class B<int>;
72*67e74705SXin Li 
73*67e74705SXin Li }
74*67e74705SXin Li 
75*67e74705SXin Li 
76*67e74705SXin Li 
77*67e74705SXin Li namespace lookup_dependent_base_class_static_function {
78*67e74705SXin Li 
79*67e74705SXin Li template <class T>
80*67e74705SXin Li class A {
81*67e74705SXin Li public:
82*67e74705SXin Li    static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
83*67e74705SXin Li    void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
84*67e74705SXin Li };
85*67e74705SXin Li 
86*67e74705SXin Li 
87*67e74705SXin Li template <class T>
88*67e74705SXin Li class B : public A<T> {
89*67e74705SXin Li public:
z2()90*67e74705SXin Li   static void z2(){
91*67e74705SXin Li     static_func();  // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
92*67e74705SXin Li     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*67e74705SXin Li   }
94*67e74705SXin Li };
95*67e74705SXin Li template class B<int>; // expected-note {{requested here}}
96*67e74705SXin Li 
97*67e74705SXin Li }
98*67e74705SXin Li 
99*67e74705SXin Li 
100*67e74705SXin Li 
101*67e74705SXin Li namespace lookup_dependent_base_class_default_argument {
102*67e74705SXin Li 
103*67e74705SXin Li template<class T>
104*67e74705SXin Li class A {
105*67e74705SXin Li public:
106*67e74705SXin Li   static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
107*67e74705SXin Li   int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
108*67e74705SXin Li };
109*67e74705SXin Li 
110*67e74705SXin Li template<class T>
111*67e74705SXin Li class B : public A<T> {
112*67e74705SXin Li public:
113*67e74705SXin Li   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*67e74705SXin Li   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*67e74705SXin Li };
116*67e74705SXin Li 
foo()117*67e74705SXin Li void foo()
118*67e74705SXin Li {
119*67e74705SXin Li 	B<int> b;
120*67e74705SXin Li 	b.g1(); // expected-note {{required here}}
121*67e74705SXin Li 	b.g2(); // expected-note {{required here}}
122*67e74705SXin Li }
123*67e74705SXin Li 
124*67e74705SXin Li }
125*67e74705SXin Li 
126*67e74705SXin Li 
127*67e74705SXin Li namespace lookup_dependent_base_class_friend {
128*67e74705SXin Li 
129*67e74705SXin Li template <class T>
130*67e74705SXin Li class B {
131*67e74705SXin Li public:
132*67e74705SXin Li   static void g();  // expected-note {{must qualify identifier to find this declaration in dependent base class}}
133*67e74705SXin Li };
134*67e74705SXin Li 
135*67e74705SXin Li template <class T>
136*67e74705SXin Li class A : public B<T> {
137*67e74705SXin Li public:
foo(A<T> p)138*67e74705SXin Li   friend void foo(A<T> p){
139*67e74705SXin Li     g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
140*67e74705SXin Li   }
141*67e74705SXin Li };
142*67e74705SXin Li 
main2()143*67e74705SXin Li int main2()
144*67e74705SXin Li {
145*67e74705SXin Li   A<int> a;
146*67e74705SXin Li   foo(a); // expected-note {{requested here}}
147*67e74705SXin Li }
148*67e74705SXin Li 
149*67e74705SXin Li }
150*67e74705SXin Li 
151*67e74705SXin Li 
152*67e74705SXin Li namespace lookup_dependent_base_no_typo_correction {
153*67e74705SXin Li 
154*67e74705SXin Li class C {
155*67e74705SXin Li public:
156*67e74705SXin Li   int m_hWnd;
157*67e74705SXin Li };
158*67e74705SXin Li 
159*67e74705SXin Li template <class T>
160*67e74705SXin Li class A : public T {
161*67e74705SXin Li public:
f(int hWnd)162*67e74705SXin Li   void f(int hWnd) {
163*67e74705SXin Li     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*67e74705SXin Li   }
165*67e74705SXin Li };
166*67e74705SXin Li 
167*67e74705SXin Li template class A<C>;
168*67e74705SXin Li 
169*67e74705SXin Li }
170*67e74705SXin Li 
171*67e74705SXin Li namespace PR12701 {
172*67e74705SXin Li 
173*67e74705SXin Li class A {};
174*67e74705SXin Li class B {};
175*67e74705SXin Li 
176*67e74705SXin Li template <class T>
177*67e74705SXin Li class Base {
178*67e74705SXin Li  public:
base_fun(void * p)179*67e74705SXin Li   bool base_fun(void* p) { return false; }  // expected-note {{must qualify identifier to find this declaration in dependent base class}}
operator T*() const180*67e74705SXin Li   operator T*() const { return 0; }
181*67e74705SXin Li };
182*67e74705SXin Li 
183*67e74705SXin Li template <class T>
184*67e74705SXin Li class Container : public Base<T> {
185*67e74705SXin Li  public:
186*67e74705SXin Li   template <typename S>
operator =(const Container<S> & rhs)187*67e74705SXin Li   bool operator=(const Container<S>& rhs) {
188*67e74705SXin Li     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*67e74705SXin Li   }
190*67e74705SXin Li };
191*67e74705SXin Li 
f()192*67e74705SXin Li void f() {
193*67e74705SXin Li   Container<A> text_provider;
194*67e74705SXin Li   Container<B> text_provider2;
195*67e74705SXin Li   text_provider2 = text_provider;  // expected-note {{in instantiation of function template specialization}}
196*67e74705SXin Li }
197*67e74705SXin Li 
198*67e74705SXin Li }  // namespace PR12701
199*67e74705SXin Li 
200*67e74705SXin Li namespace PR16014 {
201*67e74705SXin Li 
202*67e74705SXin Li struct A {
203*67e74705SXin Li   int a;
204*67e74705SXin Li   static int sa;
205*67e74705SXin Li };
206*67e74705SXin Li template <typename T> struct B : T {
fooPR16014::B207*67e74705SXin Li   int     foo() { return a; }           // expected-warning {{lookup into dependent bases}}
barPR16014::B208*67e74705SXin Li   int    *bar() { return &a; }          // expected-warning {{lookup into dependent bases}}
bazPR16014::B209*67e74705SXin Li   int     baz() { return T::a; }
quxPR16014::B210*67e74705SXin Li   int T::*qux() { return &T::a; }
stuffPR16014::B211*67e74705SXin Li   static int T::*stuff() { return &T::a; }
stuff1PR16014::B212*67e74705SXin Li   static int stuff1() { return T::sa; }
stuff2PR16014::B213*67e74705SXin Li   static int *stuff2() { return &T::sa; }
stuff3PR16014::B214*67e74705SXin Li   static int stuff3() { return sa; }    // expected-warning {{lookup into dependent bases}}
stuff4PR16014::B215*67e74705SXin Li   static int *stuff4() { return &sa; }  // expected-warning {{lookup into dependent bases}}
216*67e74705SXin Li };
217*67e74705SXin Li 
218*67e74705SXin Li template <typename T> struct C : T {
fooPR16014::C219*67e74705SXin Li   int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
barPR16014::C220*67e74705SXin Li   int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
bazPR16014::C221*67e74705SXin Li   int     baz() { return T::b; }   // expected-error {{no member named 'b' in 'PR16014::A'}}
quxPR16014::C222*67e74705SXin Li   int T::*qux() { return &T::b; }  // expected-error {{no member named 'b' in 'PR16014::A'}}
fuzPR16014::C223*67e74705SXin Li   int T::*fuz() { return &U::a; }  // expected-error {{use of undeclared identifier 'U'}} \
224*67e74705SXin Li   // expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
225*67e74705SXin Li };
226*67e74705SXin Li 
227*67e74705SXin Li template struct B<A>;
228*67e74705SXin Li template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
229*67e74705SXin Li 
230*67e74705SXin Li template <typename T> struct D : T {
231*67e74705SXin Li   struct Inner {
fooPR16014::D::Inner232*67e74705SXin Li     int foo() {
233*67e74705SXin Li       // FIXME: MSVC can find this in D's base T!  Even worse, if ::sa exists,
234*67e74705SXin Li       // clang will use it instead.
235*67e74705SXin Li       return sa; // expected-error {{use of undeclared identifier 'sa'}}
236*67e74705SXin Li     }
237*67e74705SXin Li   };
238*67e74705SXin Li };
239*67e74705SXin Li template struct D<A>;
240*67e74705SXin Li 
241*67e74705SXin Li }
242*67e74705SXin Li 
243*67e74705SXin Li namespace PR19233 {
244*67e74705SXin Li template <class T>
245*67e74705SXin Li struct A : T {
fooPR19233::A246*67e74705SXin Li   void foo() {
247*67e74705SXin Li     ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
248*67e74705SXin Li   }
barPR19233::A249*67e74705SXin Li   void bar() {
250*67e74705SXin Li     ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
251*67e74705SXin Li   }
bazPR19233::A252*67e74705SXin Li   void baz() {
253*67e74705SXin Li     B::qux(); // expected-error {{use of undeclared identifier 'B'}} \
254*67e74705SXin Li     // expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
255*67e74705SXin Li   }
256*67e74705SXin Li };
257*67e74705SXin Li 
258*67e74705SXin Li struct B { void qux(); };
259*67e74705SXin Li struct C : B { };
260*67e74705SXin Li template struct A<C>; // No error!  B is a base of A<C>, and qux is available.
261*67e74705SXin Li 
262*67e74705SXin Li struct D { };
263*67e74705SXin Li template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
264*67e74705SXin Li 
265*67e74705SXin Li }
266*67e74705SXin Li 
267*67e74705SXin Li namespace nonmethod_missing_this {
268*67e74705SXin Li template <typename T> struct Base { int y = 42; };
269*67e74705SXin Li template <typename T> struct Derived : Base<T> {
270*67e74705SXin Li   int x = y; // expected-warning {{lookup into dependent bases}}
foononmethod_missing_this::Derived271*67e74705SXin Li   auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
272*67e74705SXin Li     return y * j; // expected-warning {{lookup into dependent bases}}
273*67e74705SXin Li   }
barnonmethod_missing_this::Derived274*67e74705SXin Li   int bar() {
275*67e74705SXin Li     return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
276*67e74705SXin Li   }
277*67e74705SXin Li };
278*67e74705SXin Li template struct Derived<int>;
279*67e74705SXin Li }
280*67e74705SXin Li 
281*67e74705SXin Li namespace typedef_in_base {
282*67e74705SXin Li template <typename T> struct A { typedef T NameFromBase; };
283*67e74705SXin Li template <typename T> struct B : A<T> {
284*67e74705SXin Li   NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
285*67e74705SXin Li };
286*67e74705SXin Li static_assert(sizeof(B<int>) == 4, "");
287*67e74705SXin Li }
288*67e74705SXin Li 
289*67e74705SXin Li namespace struct_in_base {
290*67e74705SXin Li template <typename T> struct A { struct NameFromBase {}; };
291*67e74705SXin Li template <typename T> struct B : A<T> {
292*67e74705SXin Li   NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
293*67e74705SXin Li };
294*67e74705SXin Li static_assert(sizeof(B<int>) == 1, "");
295*67e74705SXin Li }
296*67e74705SXin Li 
297*67e74705SXin Li namespace enum_in_base {
298*67e74705SXin Li template <typename T> struct A { enum NameFromBase { X }; };
299*67e74705SXin Li template <typename T> struct B : A<T> {
300*67e74705SXin Li   NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
301*67e74705SXin Li };
302*67e74705SXin Li static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
303*67e74705SXin Li }
304*67e74705SXin Li 
305*67e74705SXin Li namespace two_types_in_base {
306*67e74705SXin Li template <typename T> struct A { typedef T NameFromBase; }; // expected-note {{member found by ambiguous name lookup}}
307*67e74705SXin Li template <typename T> struct B { struct NameFromBase { T m; }; }; // expected-note {{member found by ambiguous name lookup}}
308*67e74705SXin Li template <typename T> struct C : A<T>, B<T> {
309*67e74705SXin Li   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*67e74705SXin Li };
311*67e74705SXin Li static_assert(sizeof(C<int>) != 0, ""); // expected-note {{in instantiation of template class 'two_types_in_base::C<int>' requested here}}
312*67e74705SXin Li }
313*67e74705SXin Li 
314*67e74705SXin Li namespace type_and_decl_in_base {
315*67e74705SXin Li template <typename T> struct A { typedef T NameFromBase; };
316*67e74705SXin Li template <typename T> struct B { static const T NameFromBase = 42; };
317*67e74705SXin Li template <typename T> struct C : A<T>, B<T> {
318*67e74705SXin Li   NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
319*67e74705SXin Li };
320*67e74705SXin Li }
321*67e74705SXin Li 
322*67e74705SXin Li namespace classify_type_from_base {
323*67e74705SXin Li template <typename T> struct A { struct NameFromBase {}; };
324*67e74705SXin Li template <typename T> struct B : A<T> {
325*67e74705SXin Li   A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
326*67e74705SXin Li };
327*67e74705SXin Li }
328*67e74705SXin Li 
329*67e74705SXin Li namespace classify_nontype_from_base {
330*67e74705SXin Li // MSVC does not do lookup of non-type declarations from dependent template base
331*67e74705SXin Li // classes.  The extra lookup only applies to types.
NameFromBaseclassify_nontype_from_base::A332*67e74705SXin Li template <typename T> struct A { void NameFromBase() {} };
333*67e74705SXin Li template <void (*F)()> struct B { };
334*67e74705SXin Li template <typename T> struct C : A<T> {
335*67e74705SXin Li   B<C::NameFromBase> a; // correct
336*67e74705SXin Li   B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
337*67e74705SXin Li };
338*67e74705SXin Li }
339*67e74705SXin Li 
340*67e74705SXin Li namespace template_in_base {
341*67e74705SXin Li template <typename T> struct A {
342*67e74705SXin Li   template <typename U> struct NameFromBase { U x; };
343*67e74705SXin Li };
344*67e74705SXin Li template <typename T> struct B : A<T> {
345*67e74705SXin Li   // Correct form.
346*67e74705SXin Li   typename B::template NameFromBase<T> m;
347*67e74705SXin Li };
348*67e74705SXin Li template <typename T> struct C : A<T> {
349*67e74705SXin Li   // Incorrect form.
350*67e74705SXin Li   NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
351*67e74705SXin Li   //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
352*67e74705SXin Li };
353*67e74705SXin Li }
354*67e74705SXin Li 
355*67e74705SXin Li namespace type_in_inner_class_in_base {
356*67e74705SXin Li template <typename T>
357*67e74705SXin Li struct A {
358*67e74705SXin Li   struct B { typedef T NameFromBase; };
359*67e74705SXin Li };
360*67e74705SXin Li template <typename T>
361*67e74705SXin Li struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
362*67e74705SXin Li }
363*67e74705SXin Li 
364*67e74705SXin Li namespace type_in_inner_template_class_in_base {
365*67e74705SXin Li template <typename T>
366*67e74705SXin Li struct A {
367*67e74705SXin Li   template <typename U> struct B { typedef U InnerType; };
368*67e74705SXin Li };
369*67e74705SXin Li template <typename T>
370*67e74705SXin Li struct C : A<T>::template B<T> {
371*67e74705SXin Li   NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
372*67e74705SXin Li };
373*67e74705SXin Li }
374*67e74705SXin Li 
375*67e74705SXin Li namespace have_nondependent_base {
376*67e74705SXin Li template <typename T>
377*67e74705SXin Li struct A {
378*67e74705SXin Li   // Nothing, lookup should fail.
379*67e74705SXin Li };
380*67e74705SXin Li template <typename T>
381*67e74705SXin Li struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
382*67e74705SXin Li struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
383*67e74705SXin Li }
384*67e74705SXin Li 
385*67e74705SXin Li namespace type_in_base_of_dependent_base {
386*67e74705SXin Li struct A { typedef int NameFromBase; };
387*67e74705SXin Li template <typename T>
388*67e74705SXin Li struct B : A {};
389*67e74705SXin Li template <typename T>
390*67e74705SXin Li struct 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*67e74705SXin Li }
392*67e74705SXin Li 
393*67e74705SXin Li namespace type_in_second_dependent_base {
394*67e74705SXin Li template <typename T>
395*67e74705SXin Li struct A {};
396*67e74705SXin Li template<typename T>
397*67e74705SXin Li struct B { typedef T NameFromBase; };
398*67e74705SXin Li template <typename T>
399*67e74705SXin Li struct 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*67e74705SXin Li }
401*67e74705SXin Li 
402*67e74705SXin Li namespace type_in_second_non_dependent_base {
403*67e74705SXin Li struct A {};
404*67e74705SXin Li struct B { typedef int NameFromBase; };
405*67e74705SXin Li template<typename T>
406*67e74705SXin Li struct C : A, B {};
407*67e74705SXin Li template <typename T>
408*67e74705SXin Li struct 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*67e74705SXin Li }
410*67e74705SXin Li 
411*67e74705SXin Li namespace type_in_virtual_base_of_dependent_base {
412*67e74705SXin Li template <typename T>
413*67e74705SXin Li struct A { typedef T NameFromBase; };
414*67e74705SXin Li template <typename T>
415*67e74705SXin Li struct B : virtual A<T> {};
416*67e74705SXin Li template <typename T>
417*67e74705SXin Li struct 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}}
418*67e74705SXin Li C<int> c;
419*67e74705SXin Li }
420*67e74705SXin Li 
421*67e74705SXin Li namespace type_in_base_of_multiple_dependent_bases {
422*67e74705SXin Li template <typename T>
423*67e74705SXin Li struct A { typedef T NameFromBase; };
424*67e74705SXin Li template <typename T>
425*67e74705SXin Li struct B : public A<T> {};
426*67e74705SXin Li template <typename T>
427*67e74705SXin Li struct 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:}}
428*67e74705SXin Li C<int> c; // expected-note {{in instantiation of template class 'type_in_base_of_multiple_dependent_bases::C<int>' requested here}}
429*67e74705SXin Li }
430*67e74705SXin Li 
431*67e74705SXin Li namespace type_in_dependent_base_of_non_dependent_type {
432*67e74705SXin Li template<typename T> struct A { typedef int NameFromBase; };
433*67e74705SXin Li template<typename T> struct B : A<T> {
434*67e74705SXin Li   struct C;
435*67e74705SXin Li   template<typename TT>
436*67e74705SXin Li   struct D : C {
437*67e74705SXin Li     NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
438*67e74705SXin Li   };
439*67e74705SXin Li   struct E : C {
440*67e74705SXin Li     NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
441*67e74705SXin Li   };
442*67e74705SXin Li };
443*67e74705SXin Li template<typename T> struct B<T>::C : B {
444*67e74705SXin Li   NameFromBase m; // expected-warning {{use of identifier 'NameFromBase' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
445*67e74705SXin Li };
446*67e74705SXin Li template<typename T> struct F : B<T>::C {
447*67e74705SXin Li   NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
448*67e74705SXin Li };
449*67e74705SXin Li }
450*67e74705SXin Li 
451*67e74705SXin Li namespace lookup_in_function_contexts {
452*67e74705SXin Li template <typename T> struct A { typedef T NameFromBase; };
453*67e74705SXin Li template <typename T>
454*67e74705SXin Li struct B : A<T> {
455*67e74705SXin Li   // expected-warning@+1 {{lookup into dependent bases}}
lateSpecifiedFunclookup_in_function_contexts::B456*67e74705SXin Li   static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
457*67e74705SXin Li     return {};
458*67e74705SXin Li   }
459*67e74705SXin Li 
memberFunclookup_in_function_contexts::B460*67e74705SXin Li   static void memberFunc() {
461*67e74705SXin Li     NameFromBase x; // expected-warning {{lookup into dependent bases}}
462*67e74705SXin Li   }
463*67e74705SXin Li 
funcLocalClasslookup_in_function_contexts::B464*67e74705SXin Li   static void funcLocalClass() {
465*67e74705SXin Li     struct X {
466*67e74705SXin Li       NameFromBase x; // expected-warning {{lookup into dependent bases}}
467*67e74705SXin Li     } y;
468*67e74705SXin Li   }
469*67e74705SXin Li 
localClassMethodlookup_in_function_contexts::B470*67e74705SXin Li   void localClassMethod() {
471*67e74705SXin Li     struct X {
472*67e74705SXin Li       void bar() {
473*67e74705SXin Li         NameFromBase m; // expected-warning {{lookup into dependent bases}}
474*67e74705SXin Li       }
475*67e74705SXin Li     } x;
476*67e74705SXin Li     x.bar();
477*67e74705SXin Li   }
478*67e74705SXin Li 
funcLambdalookup_in_function_contexts::B479*67e74705SXin Li   static void funcLambda() {
480*67e74705SXin Li     auto l = []() {
481*67e74705SXin Li       NameFromBase x; // expected-warning {{lookup into dependent bases}}
482*67e74705SXin Li     };
483*67e74705SXin Li     l();
484*67e74705SXin Li   }
485*67e74705SXin Li 
constexprFunclookup_in_function_contexts::B486*67e74705SXin Li   static constexpr int constexprFunc() {
487*67e74705SXin Li     NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
488*67e74705SXin Li     return sizeof(x);
489*67e74705SXin Li   }
490*67e74705SXin Li 
autoFunclookup_in_function_contexts::B491*67e74705SXin Li   static auto autoFunc() {
492*67e74705SXin Li     NameFromBase x; // expected-warning {{lookup into dependent bases}}
493*67e74705SXin Li     return x;
494*67e74705SXin Li   }
495*67e74705SXin Li };
496*67e74705SXin Li 
497*67e74705SXin Li // Force us to parse the methods.
498*67e74705SXin Li template struct B<int>;
499*67e74705SXin Li }
500*67e74705SXin Li 
501*67e74705SXin Li namespace function_template_deduction {
502*67e74705SXin Li // Overloaded function templates.
f()503*67e74705SXin Li template <int N> int f() { return N; }
f()504*67e74705SXin Li template <typename T> int f() { return sizeof(T); }
505*67e74705SXin Li 
506*67e74705SXin Li // Dependent base class with type.
507*67e74705SXin Li template <typename T>
508*67e74705SXin Li struct A { typedef T NameFromBase; };
509*67e74705SXin Li template <typename T>
510*67e74705SXin Li struct B : A<T> {
511*67e74705SXin Li   // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
512*67e74705SXin Li   int x = f<NameFromBase>();
513*67e74705SXin Li };
514*67e74705SXin Li 
515*67e74705SXin Li // Dependent base class with enum.
516*67e74705SXin Li template <typename T> struct C { enum { NameFromBase = 4 }; };
517*67e74705SXin Li template <typename T> struct D : C<T> {
518*67e74705SXin Li   // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
519*67e74705SXin Li   int x = f<NameFromBase>();
520*67e74705SXin Li };
521*67e74705SXin Li }
522*67e74705SXin Li 
523*67e74705SXin Li namespace function_template_undef_impl {
524*67e74705SXin Li template<class T>
f()525*67e74705SXin Li void f() {
526*67e74705SXin Li   Undef::staticMethod(); // expected-error {{use of undeclared identifier 'Undef'}}
527*67e74705SXin Li   UndefVar.method(); // expected-error {{use of undeclared identifier 'UndefVar'}}
528*67e74705SXin Li }
529*67e74705SXin Li }
530*67e74705SXin Li 
531*67e74705SXin Li namespace PR20716 {
532*67e74705SXin Li template <template <typename T> class A>
533*67e74705SXin Li struct B : A<int>
534*67e74705SXin Li {
535*67e74705SXin Li   XXX x; // expected-error {{unknown type name}}
536*67e74705SXin Li };
537*67e74705SXin Li 
538*67e74705SXin Li template <typename T>
539*67e74705SXin Li struct C {};
540*67e74705SXin Li 
541*67e74705SXin Li template <typename T>
542*67e74705SXin Li using D = C<T>;
543*67e74705SXin Li 
544*67e74705SXin Li template <typename T>
545*67e74705SXin Li struct E : D<T>
546*67e74705SXin Li {
547*67e74705SXin Li   XXX x; // expected-error {{unknown type name}}
548*67e74705SXin Li };
549*67e74705SXin Li }
550*67e74705SXin Li 
551*67e74705SXin Li namespace PR23810 {
552*67e74705SXin Li void f(int);
553*67e74705SXin Li struct Base {
554*67e74705SXin Li   void f(); // expected-note{{must qualify identifier to find this declaration in dependent base class}}
555*67e74705SXin Li };
556*67e74705SXin Li template <typename T> struct Template : T {
memberPR23810::Template557*67e74705SXin Li   void member() {
558*67e74705SXin Li     f(); // expected-warning {{found via unqualified lookup into dependent bases}}
559*67e74705SXin Li   }
560*67e74705SXin Li };
test()561*67e74705SXin Li void test() {
562*67e74705SXin Li   Template<Base> x;
563*67e74705SXin Li   x.member(); // expected-note{{requested here}}
564*67e74705SXin Li };
565*67e74705SXin Li }
566*67e74705SXin Li 
567*67e74705SXin Li namespace PR23823 {
568*67e74705SXin Li // Don't delay lookup in SFINAE context.
569*67e74705SXin Li template <typename T> decltype(g(T())) check(); // expected-note{{candidate template ignored: substitution failure [with T = int]: use of undeclared identifier 'g'}}
570*67e74705SXin Li decltype(check<int>()) x; // expected-error{{no matching function for call to 'check'}}
571*67e74705SXin Li 
572*67e74705SXin Li void h();
573*67e74705SXin Li template <typename T> decltype(h(T())) check2(); // expected-note{{candidate template ignored: substitution failure [with T = int]: no matching function for call to 'h'}}
574*67e74705SXin Li decltype(check2<int>()) y; // expected-error{{no matching function for call to 'check2'}}
575*67e74705SXin Li }
576*67e74705SXin Li 
577*67e74705SXin Li // We also allow unqualified lookup into bases in contexts where the we know the
578*67e74705SXin Li // undeclared identifier *must* be a type, such as a new expression or catch
579*67e74705SXin Li // parameter type.
580*67e74705SXin Li template <typename T>
581*67e74705SXin Li struct UseUnqualifiedTypeNames : T {
fooUseUnqualifiedTypeNames582*67e74705SXin Li   void foo() {
583*67e74705SXin Li     void *P = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
584*67e74705SXin Li     size_t x = __builtin_offsetof(TheType, f2); // expected-warning {{unqualified lookup}} expected-error {{no type}}
585*67e74705SXin Li     try {
586*67e74705SXin Li     } catch (TheType) { // expected-warning {{unqualified lookup}} expected-error {{no type}}
587*67e74705SXin Li     }
588*67e74705SXin Li     enum E : IntegerType { E0 = 42 }; // expected-warning {{unqualified lookup}} expected-error {{no type}}
589*67e74705SXin Li     _Atomic(TheType) a; // expected-warning {{unqualified lookup}} expected-error {{no type}}
590*67e74705SXin Li   }
591*67e74705SXin Li   void out_of_line();
592*67e74705SXin Li };
593*67e74705SXin Li template <typename T>
out_of_line()594*67e74705SXin Li void UseUnqualifiedTypeNames<T>::out_of_line() {
595*67e74705SXin Li   void *p = new TheType; // expected-warning {{unqualified lookup}} expected-error {{no type}}
596*67e74705SXin Li }
597*67e74705SXin Li struct Base {
598*67e74705SXin Li   typedef int IntegerType;
599*67e74705SXin Li   struct TheType {
600*67e74705SXin Li     int f1, f2;
601*67e74705SXin Li   };
602*67e74705SXin Li };
603*67e74705SXin Li template struct UseUnqualifiedTypeNames<Base>;
604*67e74705SXin Li struct BadBase { };
605*67e74705SXin Li template struct UseUnqualifiedTypeNames<BadBase>; // expected-note-re 2 {{in instantiation {{.*}} requested here}}
606*67e74705SXin Li 
607*67e74705SXin Li namespace partial_template_lookup {
608*67e74705SXin Li 
609*67e74705SXin Li class Bar;
610*67e74705SXin Li class Spare;
611*67e74705SXin Li 
612*67e74705SXin Li template <class T, class X = Bar>
613*67e74705SXin Li class FooTemplated;
614*67e74705SXin Li 
615*67e74705SXin Li class FooBase {
616*67e74705SXin Li public:
617*67e74705SXin Li   typedef int BaseTypedef;
618*67e74705SXin Li };
619*67e74705SXin Li 
620*67e74705SXin Li // Partial template spec (unused)
621*67e74705SXin Li template <class T>
622*67e74705SXin Li class FooTemplated<T, Spare> {};
623*67e74705SXin Li 
624*67e74705SXin Li // Partial template spec (used)
625*67e74705SXin Li template <class T>
626*67e74705SXin Li class FooTemplated<T, Bar> : public FooBase {};
627*67e74705SXin Li 
628*67e74705SXin Li // Full template spec
629*67e74705SXin Li template <class T, class X>
630*67e74705SXin Li class FooTemplated : public FooTemplated<T, Bar> {
631*67e74705SXin Li public:
632*67e74705SXin Li   BaseTypedef Member; // expected-warning {{unqualified lookup}}
633*67e74705SXin Li };
634*67e74705SXin Li }
635