summaryrefslogtreecommitdiffstats
path: root/test/CXX/class/class.mfct
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-12-02 03:53:29 +0000
committerJohn McCall <rjmccall@apple.com>2009-12-02 03:53:29 +0000
commit2f841ba3b3fd6babe751667470735651907b4001 (patch)
tree73cf71e52817f3c503f1a4f97ee9ec4bb86da40f /test/CXX/class/class.mfct
parent7b55668db7618334cc40011d3c1e128524d89462 (diff)
Stop trying to analyze class-hierarchies for dependently-scoped id-expressions;
there's nothing interesting we can say now that we're correctly not requiring the qualifier to name a known base class in dependent contexts. Require scope specifiers on member access expressions to name complete types if they're not dependent; delay lookup when they are dependent. Use more appropriate diagnostics when qualified implicit member access expressions find declarations from unrelated classes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90289 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CXX/class/class.mfct')
-rw-r--r--test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
new file mode 100644
index 0000000000..b90661deef
--- /dev/null
+++ b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
@@ -0,0 +1,93 @@
+// RUN: clang-cc -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}}
+ void test();
+ };
+
+ struct B : A {
+
+ };
+
+ void A::test() {
+ B::foo(Opaque1());
+ B::foo(Opaque2());
+ B::foo(Opaque3()); // expected-error {{no matching member function}}
+ }
+}
+
+namespace test2 {
+ class 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}}
+ }
+}