Home | History | Annotate | Download | only in class.mfct.non-static
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 // [class.mfct.non-static]p3:
      4 //   When an id-expression (5.1) that is not part of a class member
      5 //   access syntax (5.2.5) and not used to form a pointer to member
      6 //   (5.3.1) is used in the body of a non-static member function of
      7 //   class X, if name lookup (3.4.1) resolves the name in the
      8 //   id-expression to a non-static non-type member of some class C,
      9 //   the id-expression is transformed into a class member access
     10 //   expression (5.2.5) using (*this) (9.3.2) as the
     11 //   postfix-expression to the left of the . operator. [ Note: if C is
     12 //   not X or a base class of X, the class member access expression is
     13 //   ill-formed. --end note] Similarly during name lookup, when an
     14 //   unqualified-id (5.1) used in the definition of a member function
     15 //   for class X resolves to a static member, an enumerator or a
     16 //   nested type of class X or of a base class of X, the
     17 //   unqualified-id is transformed into a qualified-id (5.1) in which
     18 //   the nested-name-specifier names the class of the member function.
     19 
     20 namespace test0 {
     21   class A {
     22     int data_member;
     23     int instance_method();
     24     static int static_method();
     25 
     26     bool test() {
     27       return data_member + instance_method() < static_method();
     28     }
     29   };
     30 }
     31 
     32 namespace test1 {
     33   struct Opaque1 {}; struct Opaque2 {}; struct Opaque3 {};
     34 
     35   struct A {
     36     void foo(Opaque1); // expected-note {{candidate}}
     37     void foo(Opaque2); // expected-note {{candidate}}
     38   };
     39 
     40   struct B : A {
     41     void test();
     42   };
     43 
     44   struct C1 : A { };
     45   struct C2 : B { };
     46 
     47   void B::test() {
     48     A::foo(Opaque1());
     49     A::foo(Opaque2());
     50     A::foo(Opaque3()); // expected-error {{no matching member function}}
     51 
     52     C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
     53     C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
     54   }
     55 }
     56 
     57 namespace test2 {
     58   struct Unrelated {
     59     void foo();
     60   };
     61 
     62   template <class T> struct B;
     63   template <class T> struct C;
     64 
     65   template <class T> struct A {
     66     void foo();
     67 
     68     void test0() {
     69       Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}}
     70     }
     71 
     72     void test1() {
     73       B<T>::foo();
     74     }
     75 
     76     static void test2() {
     77       B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
     78     }
     79 
     80     void test3() {
     81       C<T>::foo(); // expected-error {{no member named 'foo'}}
     82     }
     83   };
     84 
     85   template <class T> struct B : A<T> {
     86   };
     87 
     88   template <class T> struct C {
     89   };
     90 
     91   int test() {
     92     A<int> a;
     93     a.test0(); // no instantiation note here, decl is ill-formed
     94     a.test1();
     95     a.test2(); // expected-note {{in instantiation}}
     96     a.test3(); // expected-note {{in instantiation}}
     97   }
     98 }
     99