diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/class/class.mfct/class.mfct.non-static | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/class/class.mfct/class.mfct.non-static')
-rw-r--r-- | clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp new file mode 100644 index 0000000..9116e71 --- /dev/null +++ b/clang/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// [class.mfct.non-static]p3: +// When an id-expression (5.1) that is not part of a class member +// access syntax (5.2.5) and not used to form a pointer to member +// (5.3.1) is used in the body of a non-static member function of +// class X, if name lookup (3.4.1) resolves the name in the +// id-expression to a non-static non-type member of some class C, +// the id-expression is transformed into a class member access +// expression (5.2.5) using (*this) (9.3.2) as the +// postfix-expression to the left of the . operator. [ Note: if C is +// not X or a base class of X, the class member access expression is +// ill-formed. --end note] Similarly during name lookup, when an +// unqualified-id (5.1) used in the definition of a member function +// for class X resolves to a static member, an enumerator or a +// nested type of class X or of a base class of X, the +// unqualified-id is transformed into a qualified-id (5.1) in which +// the nested-name-specifier names the class of the member function. + +namespace test0 { + class A { + int data_member; + int instance_method(); + static int static_method(); + + bool test() { + return data_member + instance_method() < static_method(); + } + }; +} + +namespace test1 { + struct Opaque1 {}; struct Opaque2 {}; struct Opaque3 {}; + + struct A { + void foo(Opaque1); // expected-note {{candidate}} + void foo(Opaque2); // expected-note {{candidate}} + }; + + struct B : A { + void test(); + }; + + struct C1 : A { }; + struct C2 : B { }; + + void B::test() { + A::foo(Opaque1()); + A::foo(Opaque2()); + A::foo(Opaque3()); // expected-error {{no matching member function}} + + C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}} + C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}} + } +} + +namespace test2 { + struct Unrelated { + void foo(); + }; + + template <class T> struct B; + template <class T> struct C; + + template <class T> struct A { + void foo(); + + void test0() { + Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}} + } + + void test1() { + B<T>::foo(); + } + + static void test2() { + B<T>::foo(); // expected-error {{call to non-static member function without an object argument}} + } + + void test3() { + C<T>::foo(); // expected-error {{no member named 'foo'}} + } + }; + + template <class T> struct B : A<T> { + }; + + template <class T> struct C { + }; + + int test() { + A<int> a; + a.test0(); // no instantiation note here, decl is ill-formed + a.test1(); + a.test2(); // expected-note {{in instantiation}} + a.test3(); // expected-note {{in instantiation}} + } +} |