// Copyright (C) 2000 Free Software Foundation, Inc. // Contributed by Nathan Sidwell 4 February 2001 // Check constructor vtables work. This is included from numerous test // files, which set the #defines necessary to specify the hierarchy. #include #include int fail; struct A; template int Test (DERIVED *d, int expect) { BASE *b = static_cast (d); void *full_b = dynamic_cast (b); void *full_d = dynamic_cast (d); A *ap = static_cast (b); if (full_b != full_d) { fail++; fprintf (stderr, "base %s and derived %s have different full objects\n", typeid (BASE).name (), typeid (DERIVED).name ()); return 1; } DERIVED *dynamic_d = dynamic_cast (b); if (dynamic_d != d) { fail++; fprintf (stderr, "dynamic_cast from %s to %s failed\n", typeid (BASE).name (), typeid (DERIVED).name ()); return 1; } b->Baz (static_cast (ap)); int res = b->Foo (static_cast (d)); if (res != expect) { fail++; fprintf (stderr, "%s::Foo returned %d, expected %d\n", typeid (BASE).name (), res, expect); return 1; } return 0; } template int Test (T *self, void *expected, int result) { if (self != expected) { fail++; fprintf (stderr, "%s::Foo wrong this pointer\n", typeid (T).name ()); } return result; } struct A { #ifndef A_EMPTY int a_m; #endif virtual int Foo (void *p) {return Test (this, p, 1);} virtual int Baz (void *p) {return Test (this, p, 1);} A (); ~A (); }; struct B1: virtual A { #ifndef B1_EMPTY int b1_m; #endif virtual int Foo (void *p) {return Test (this, p, 2);} B1(); ~B1(); }; struct B2: virtual A { #ifndef B2_EMPTY int b2_m; #endif virtual int Foo (void *p) {return Test (this, p, 3);} B2(); ~B2(); }; struct Empty {}; struct C : C_PARENTS { #ifndef C_EMPTY int c_m; #endif virtual int Foo (void *p) {return Test (this, p, 4);} C(); ~C(); }; A::A () { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 1); } A::~A () { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 1); } B1::B1() { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 2); Test (this, 2); } B1::~B1() { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 2); Test (this, 2); } B2::B2() { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 3); Test (this, 3); } B2::~B2() { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 3); Test (this, 3); } C::C() { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 4); Test (this, 4); } C::~C() { fprintf (stderr, "%s\n", __PRETTY_FUNCTION__); Test (this, 4); Test (this, 4); } struct D : C {}; struct D1 : virtual C {}; struct D2 : virtual A, virtual C {}; int main() { { fprintf (stderr, "C\n"); C c; } { fprintf (stderr, "D\n"); D d; } { fprintf (stderr, "D1\n"); D1 d1; } { fprintf (stderr, "D2\n"); D2 d2; } if (fail) fprintf (stderr, "There are %d failings\n", fail); else fprintf (stderr, "Passed\n"); return fail ? 1 : 0; }