| // { dg-do assemble } |
| // 980604 bkoz |
| // 3.4.5 Class member access p 4 |
| // nested and non-nested calls, no dtors |
| |
| struct L { |
| int ii; |
| void foo(int a) {++a;} |
| struct Linner { |
| int ii_inner; |
| void foo_inner(int b) {++b;} |
| }; |
| }; |
| class A : public L {}; |
| class B : public L {}; |
| class C : public A, public B {}; |
| |
| |
| void foo() { |
| // straight call |
| C x; |
| x.A::ii = 5; |
| x.A::foo(x.A::ii); |
| |
| // 5.1 Primary expressions |
| // p 8 |
| // a nested name specifier that names a class, |
| // optionally followed by the keyword template and then followd by |
| // the name of a member of either that class or one of its base |
| // classes is a qualified-id. (3.4.3.1 describes their lookup.) |
| |
| // 5.2.5 Class memember access |
| |
| // p 3 if E1 has the type 'pointer to class X' then |
| // E1->E2 == (*(E1)).E32 |
| // E1 == object-expression |
| // E2 == id-expression |
| // thus everything gets converted to the "." notation |
| |
| // p 2 |
| // the id-expression shall name a member of the class |
| // (object-expression) or of one of its base classes. |
| |
| // p4 if E2 is a nested type (of the object-expression), tye |
| // expression E1.E2 is ill formed. |
| |
| // try 1 nested call - ERROR |
| #if 0 |
| C x2; |
| x2.A::L::Linner::ii_inner = 6; //ERROR violates p2, does not name member of C |
| x2.A::L::Linner::foo_inner(x2.A::L::Linner::ii_inner); |
| #endif |
| |
| //try2: scoped method call -edg +acc +g++ |
| #if 1 |
| C::A::Linner x2; |
| x2.A::Linner::ii_inner = 6; |
| x2.A::Linner::foo_inner(x2.A::Linner::ii_inner); |
| #endif |
| |
| //try 3: non-scoped method call -edg +acc +g++ |
| #if 0 |
| C::A::L::Linner x3; |
| x3.ii_inner = 6; |
| x3.foo_inner(x3.ii_inner); |
| #endif |
| } |
| |
| |
| |
| |