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