1 // Copyright (C) 2000 Free Software Foundation, Inc.
2 // Contributed by Nathan Sidwell 4 February 2001 <nathan@codesourcery.com>
3
4 // Check constructor vtables work. This is included from numerous test
5 // files, which set the #defines necessary to specify the heirarchy.
6
7 #include <typeinfo>
8 #include <stdio.h>
9
10 int fail;
11 struct A;
12
13 template <typename BASE, typename DERIVED>
Test(DERIVED * d,int expect)14 int Test (DERIVED *d, int expect)
15 {
16 BASE *b = static_cast <BASE *> (d);
17 void *full_b = dynamic_cast <void *> (b);
18 void *full_d = dynamic_cast <void *> (d);
19 A *ap = static_cast <A *> (b);
20
21 if (full_b != full_d)
22 {
23 fail++;
24 fprintf (stderr, "base %s and derived %s have different full objects\n",
25 typeid (BASE).name (), typeid (DERIVED).name ());
26 return 1;
27 }
28
29 DERIVED *dynamic_d = dynamic_cast <DERIVED *> (b);
30
31 if (dynamic_d != d)
32 {
33 fail++;
34 fprintf (stderr, "dynamic_cast from %s to %s failed\n",
35 typeid (BASE).name (), typeid (DERIVED).name ());
36 return 1;
37 }
38
39 b->Baz (static_cast <void *> (ap));
40
41 int res = b->Foo (static_cast <void *> (d));
42
43 if (res != expect)
44 {
45 fail++;
46 fprintf (stderr, "%s::Foo returned %d, expected %d\n",
47 typeid (BASE).name (), res, expect);
48 return 1;
49 }
50
51 return 0;
52 }
53
54 template <typename T>
Test(T * self,void * expected,int result)55 int Test (T *self, void *expected, int result)
56 {
57 if (self != expected)
58 {
59 fail++;
60 fprintf (stderr, "%s::Foo wrong this pointer\n", typeid (T).name ());
61 }
62 return result;
63 }
64
65 struct A {
66 #ifndef A_EMPTY
67 int a_m;
68 #endif
FooA69 virtual int Foo (void *p) {return Test (this, p, 1);}
BazA70 virtual int Baz (void *p) {return Test (this, p, 1);}
71 A ();
72 ~A ();
73 };
74
75 struct B1: virtual A {
76 #ifndef B1_EMPTY
77 int b1_m;
78 #endif
FooB179 virtual int Foo (void *p) {return Test (this, p, 2);}
80 B1();
81 ~B1();
82 };
83
84 struct B2: virtual A {
85 #ifndef B2_EMPTY
86 int b2_m;
87 #endif
FooB288 virtual int Foo (void *p) {return Test (this, p, 3);}
89 B2();
90 ~B2();
91 };
92
93 struct Empty {};
94
95 struct C : C_PARENTS {
96 #ifndef C_EMPTY
97 int c_m;
98 #endif
FooC99 virtual int Foo (void *p) {return Test (this, p, 4);}
100 C();
101 ~C();
102 };
103
A()104 A::A ()
105 {
106 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
107 Test <A> (this, 1);
108 }
~A()109 A::~A ()
110 {
111 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
112 Test <A> (this, 1);
113 }
114
B1()115 B1::B1()
116 {
117 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
118 Test <A> (this, 2);
119 Test <B1> (this, 2);
120 }
~B1()121 B1::~B1()
122 {
123 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
124 Test <A> (this, 2);
125 Test <B1> (this, 2);
126 }
B2()127 B2::B2()
128 {
129 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
130 Test <A> (this, 3);
131 Test <B2> (this, 3);
132 }
~B2()133 B2::~B2()
134 {
135 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
136 Test <A> (this, 3);
137 Test <B2> (this, 3);
138 }
C()139 C::C()
140 {
141 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
142 Test <A> (this, 4);
143 Test <C> (this, 4);
144 }
~C()145 C::~C()
146 {
147 fprintf (stderr, "%s\n", __PRETTY_FUNCTION__);
148 Test <A> (this, 4);
149 Test <C> (this, 4);
150 }
151
152 struct D : C {};
153 struct D1 : virtual C {};
154 struct D2 : virtual A, virtual C {};
155
main()156 int main()
157 {
158 {
159 fprintf (stderr, "C\n");
160 C c;
161 }
162 {
163 fprintf (stderr, "D\n");
164 D d;
165 }
166 {
167 fprintf (stderr, "D1\n");
168 D1 d1;
169 }
170 {
171 fprintf (stderr, "D2\n");
172 D2 d2;
173 }
174 if (fail)
175 fprintf (stderr, "There are %d failings\n", fail);
176 else
177 fprintf (stderr, "Passed\n");
178 return fail ? 1 : 0;
179 }
180