186 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3// [class.mfct.non-static]p3:4// When an id-expression (5.1) that is not part of a class member5// access syntax (5.2.5) and not used to form a pointer to member6// (5.3.1) is used in the body of a non-static member function of7// class X, if name lookup (3.4.1) resolves the name in the8// id-expression to a non-static non-type member of some class C,9// the id-expression is transformed into a class member access10// expression (5.2.5) using (*this) (9.3.2) as the11// postfix-expression to the left of the . operator. [ Note: if C is12// not X or a base class of X, the class member access expression is13// ill-formed. --end note] Similarly during name lookup, when an14// unqualified-id (5.1) used in the definition of a member function15// for class X resolves to a static member, an enumerator or a16// nested type of class X or of a base class of X, the17// unqualified-id is transformed into a qualified-id (5.1) in which18// 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(); // expected-error {{call to non-static member function without an object argument}}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-formed94 a.test1(); // expected-note {{in instantiation}}95 a.test2(); // expected-note {{in instantiation}}96 a.test3(); // expected-note {{in instantiation}}97 }98}99 100namespace test3 {101 struct A {102 void f0();103 104 template<typename T>105 void f1();106 107 static void f2();108 109 template<typename T>110 static void f3();111 112 int x0;113 114 static constexpr int x1 = 0;115 116 template<typename T>117 static constexpr int x2 = 0;118 };119 120 template<typename T>121 struct B : T {122 auto g0() -> decltype(T::f0());123 124 auto g1() -> decltype(T::template f1<int>());125 126 auto g2() -> decltype(T::f2());127 128 auto g3() -> decltype(T::template f3<int>());129 130 auto g4() -> decltype(T::x0);131 132 auto g5() -> decltype(T::x1);133 134 auto g6() -> decltype(T::template x2<int>);135 136 decltype(T::f0()) g7(); // expected-error {{call to non-static member function without an object argument}}137 138 decltype(T::template f1<int>()) g8(); // expected-error {{call to non-static member function without an object argument}}139 140 decltype(T::f2()) g9();141 142 decltype(T::template f3<int>()) g10();143 144 decltype(T::x0) g11();145 146 decltype(T::x1) g12();147 148 decltype(T::template x2<int>) g13();149 };150 151 template struct B<A>; // expected-note {{in instantiation of}}152 153 template<typename T>154 struct C : T {155 static auto g0() -> decltype(T::f0()); // expected-error {{'this' cannot be implicitly used in a static member function declaration}}156 157 static auto g1() -> decltype(T::template f1<int>()); // expected-error {{'this' cannot be implicitly used in a static member function declaration}}158 159 static auto g2() -> decltype(T::f2());160 161 static auto g3() -> decltype(T::template f3<int>());162 163 static auto g4() -> decltype(T::x0); // expected-error {{'this' cannot be implicitly used in a static member function declaration}}164 165 static auto g5() -> decltype(T::x1);166 167 static auto g6() -> decltype(T::template x2<int>);168 169 static decltype(T::f0()) g7(); // expected-error {{call to non-static member function without an object argument}}170 171 static decltype(T::template f1<int>()) g8(); // expected-error {{call to non-static member function without an object argument}}172 173 static decltype(T::f2()) g9();174 175 static decltype(T::template f3<int>()) g10();176 177 static decltype(T::x0) g11();178 179 static decltype(T::x1) g12();180 181 static decltype(T::template x2<int>) g13();182 };183 184 template struct C<A>; // expected-note {{in instantiation of}}185}186