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
20namespace 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
32namespace 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
57namespace 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