239 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
 | |
| 
 | |
| 
 | |
| template <class T>
 | |
| class A {
 | |
| public:
 | |
|    void f(T a) { }// expected-note {{must qualify identifier to find this declaration in dependent base class}}
 | |
|    void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| class B : public A<T> {
 | |
| public:
 | |
| 	void z(T a)
 | |
|     {
 | |
|        f(a); // expected-warning {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
 | |
|        g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
 | |
|     }
 | |
| };
 | |
| 
 | |
| template class B<int>; // expected-note {{requested here}}
 | |
| template class B<char>;
 | |
| 
 | |
| void test()
 | |
| {
 | |
|     B<int> b;
 | |
|     b.z(3);
 | |
| }
 | |
| 
 | |
| struct A2 {
 | |
|   template<class T> void f(T) {
 | |
|     XX; //expected-error {{use of undeclared identifier 'XX'}}
 | |
|     A2::XX; //expected-error {{no member named 'XX' in 'A2'}}
 | |
|   }
 | |
| };
 | |
| template void A2::f(int);
 | |
| 
 | |
| template<class T0>
 | |
| struct A3 {
 | |
|   template<class T1> void f(T1) {
 | |
|     XX; //expected-error {{use of undeclared identifier 'XX'}}
 | |
|   }
 | |
| };
 | |
| template void A3<int>::f(int);
 | |
| 
 | |
| template<class T0>
 | |
| struct A4 {
 | |
|   void f(char) {
 | |
|     XX; //expected-error {{use of undeclared identifier 'XX'}}
 | |
|   }
 | |
| };
 | |
| template class A4<int>;
 | |
| 
 | |
| 
 | |
| namespace lookup_dependent_bases_id_expr {
 | |
| 
 | |
| template<class T> class A {
 | |
| public:
 | |
|   int var;
 | |
| };
 | |
| 
 | |
| 
 | |
| template<class T>
 | |
| class B : public A<T> {
 | |
| public:
 | |
|   void f() {
 | |
|     var = 3;
 | |
|   }
 | |
| };
 | |
| 
 | |
| template class B<int>;
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| namespace lookup_dependent_base_class_static_function {
 | |
| 
 | |
| template <class T>
 | |
| class A {
 | |
| public:
 | |
|    static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
 | |
|    void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
 | |
| };
 | |
| 
 | |
| 
 | |
| template <class T>
 | |
| class B : public A<T> {
 | |
| public:
 | |
|   static void z2(){
 | |
|     static_func();  // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
 | |
|     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}}
 | |
|   }
 | |
| };
 | |
| template class B<int>; // expected-note {{requested here}}
 | |
| 
 | |
| } 
 | |
| 
 | |
| 
 | |
| 
 | |
| namespace lookup_dependent_base_class_default_argument {
 | |
| 
 | |
| template<class T>
 | |
| class A {
 | |
| public:
 | |
|   static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} 
 | |
|   int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} 
 | |
| };
 | |
| 
 | |
| template<class T>
 | |
| class B : public A<T> {
 | |
| public:
 | |
|   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}}
 | |
|   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}}
 | |
| };
 | |
| 
 | |
| void foo()
 | |
| {
 | |
| 	B<int> b;
 | |
| 	b.g1(); // expected-note {{required here}}
 | |
| 	b.g2(); // expected-note {{required here}}
 | |
| }
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| namespace lookup_dependent_base_class_friend {
 | |
| 
 | |
| template <class T>
 | |
| class B {
 | |
| public:
 | |
|   static void g();  // expected-note {{must qualify identifier to find this declaration in dependent base class}} 
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| class A : public B<T> {
 | |
| public:
 | |
|   friend void foo(A<T> p){
 | |
|     g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
 | |
|   }
 | |
| };
 | |
| 
 | |
| int main2()
 | |
| {
 | |
|   A<int> a;
 | |
|   foo(a); // expected-note {{requested here}}
 | |
| }
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| namespace lookup_dependent_base_no_typo_correction {
 | |
| 
 | |
| class C {
 | |
| public:
 | |
|   int m_hWnd;
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| class A : public T {
 | |
| public:
 | |
|   void f(int hWnd) {
 | |
|     m_hWnd = 1;
 | |
|   }
 | |
| };
 | |
| 
 | |
| template class A<C>;
 | |
| 
 | |
| }
 | |
| 
 | |
| namespace PR12701 {
 | |
| 
 | |
| class A {};
 | |
| class B {};
 | |
| 
 | |
| template <class T>
 | |
| class Base {
 | |
|  public:
 | |
|   bool base_fun(void* p) { return false; }  // expected-note {{must qualify identifier to find this declaration in dependent base clas}}
 | |
|   operator T*() const { return 0; }
 | |
| };
 | |
| 
 | |
| template <class T>
 | |
| class Container : public Base<T> {
 | |
|  public:
 | |
|   template <typename S>
 | |
|   bool operator=(const Container<S>& rhs) {
 | |
|     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}}
 | |
|   }
 | |
| };
 | |
| 
 | |
| void f() {
 | |
|   Container<A> text_provider;
 | |
|   Container<B> text_provider2;
 | |
|   text_provider2 = text_provider;  // expected-note {{in instantiation of function template specialization}}
 | |
| }
 | |
| 
 | |
| }  // namespace PR12701
 | |
| 
 | |
| namespace PR16014 {
 | |
| 
 | |
| struct A {
 | |
|   int a;
 | |
|   static int sa;
 | |
| };
 | |
| template <typename T> struct B : T {
 | |
|   int     foo() { return a; }
 | |
|   int    *bar() { return &a; }
 | |
|   int     baz() { return T::a; }
 | |
|   int T::*qux() { return &T::a; }
 | |
|   static int T::*stuff() { return &T::a; }
 | |
|   static int stuff1() { return T::sa; }
 | |
|   static int *stuff2() { return &T::sa; }
 | |
| };
 | |
| 
 | |
| template <typename T> struct C : T {
 | |
|   int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}}
 | |
|   int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}}
 | |
|   int     baz() { return T::b; }   // expected-error {{no member named 'b' in 'PR16014::A'}}
 | |
|   int T::*qux() { return &T::b; }  // expected-error {{no member named 'b' in 'PR16014::A'}}
 | |
|   int T::*fuz() { return &U::a; }  // expected-error {{use of undeclared identifier 'U'}}
 | |
| };
 | |
| 
 | |
| template struct B<A>;
 | |
| template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::.*' requested here}}
 | |
| 
 | |
| template <typename T> struct D : T {
 | |
|   struct Inner {
 | |
|     int foo() {
 | |
|       // FIXME: MSVC can find this in D's base T!  Even worse, if ::sa exists,
 | |
|       // clang will use it instead.
 | |
|       return sa; // expected-error {{use of undeclared identifier 'sa'}}
 | |
|     }
 | |
|   };
 | |
| };
 | |
| template struct D<A>;
 | |
| 
 | |
| }
 | 
