vtable-layout-abi-examples.cpp revision 014a358058fab46a84718b1424e40ad5a8068827
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
2
3/// Examples from the Itanium C++ ABI specification.
4/// http://www.codesourcery.com/public/cxx-abi/
5
6namespace Test1 {
7
8// This is from http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html
9
10// CHECK:      Vtable for 'Test1::A' (5 entries).
11// CHECK-NEXT:    0 | offset_to_top (0)
12// CHECK-NEXT:    1 | Test1::A RTTI
13// CHECK-NEXT:        -- (Test1::A, 0) vtable address --
14// CHECK-NEXT:    2 | void Test1::A::f()
15// CHECK-NEXT:    3 | void Test1::A::g()
16// CHECK-NEXT:    4 | void Test1::A::h()
17struct A {
18  virtual void f ();
19  virtual void g ();
20  virtual void h ();
21  int ia;
22};
23void A::f() {}
24
25// CHECK:      Vtable for 'Test1::B' (13 entries).
26// CHECK-NEXT:    0 | vbase_offset (16)
27// CHECK-NEXT:    1 | offset_to_top (0)
28// CHECK-NEXT:    2 | Test1::B RTTI
29// CHECK-NEXT:        -- (Test1::B, 0) vtable address --
30// CHECK-NEXT:    3 | void Test1::B::f()
31// CHECK-NEXT:    4 | void Test1::B::h()
32// CHECK-NEXT:    5 | vcall_offset (-16)
33// CHECK-NEXT:    6 | vcall_offset (0)
34// CHECK-NEXT:    7 | vcall_offset (-16)
35// CHECK-NEXT:    8 | offset_to_top (-16)
36// CHECK-NEXT:    9 | Test1::B RTTI
37// CHECK-NEXT:        -- (Test1::A, 16) vtable address --
38// CHECK-NEXT:   10 | void Test1::B::f()
39// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
40// CHECK-NEXT:   11 | void Test1::A::g()
41// CHECK-NEXT:   12 | void Test1::B::h()
42// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
43struct B: public virtual A {
44  void f ();
45  void h ();
46  int ib;
47};
48void B::f() {}
49
50// CHECK:      Vtable for 'Test1::C' (13 entries).
51// CHECK-NEXT:    0 | vbase_offset (16)
52// CHECK-NEXT:    1 | offset_to_top (0)
53// CHECK-NEXT:    2 | Test1::C RTTI
54// CHECK-NEXT:        -- (Test1::C, 0) vtable address --
55// CHECK-NEXT:    3 | void Test1::C::g()
56// CHECK-NEXT:    4 | void Test1::C::h()
57// CHECK-NEXT:    5 | vcall_offset (-16)
58// CHECK-NEXT:    6 | vcall_offset (-16)
59// CHECK-NEXT:    7 | vcall_offset (0)
60// CHECK-NEXT:    8 | offset_to_top (-16)
61// CHECK-NEXT:    9 | Test1::C RTTI
62// CHECK-NEXT:        -- (Test1::A, 16) vtable address --
63// CHECK-NEXT:   10 | void Test1::A::f()
64// CHECK-NEXT:   11 | void Test1::C::g()
65// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
66// CHECK-NEXT:   12 | void Test1::C::h()
67// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
68struct C: public virtual A {
69  void g ();
70  void h ();
71  int ic;
72};
73void C::g() {}
74
75// CHECK:      Vtable for 'Test1::D' (18 entries).
76// CHECK-NEXT:    0 | vbase_offset (32)
77// CHECK-NEXT:    1 | offset_to_top (0)
78// CHECK-NEXT:    2 | Test1::D RTTI
79// CHECK-NEXT:        -- (Test1::B, 0) vtable address --
80// CHECK-NEXT:        -- (Test1::D, 0) vtable address --
81// CHECK-NEXT:    3 | void Test1::B::f()
82// CHECK-NEXT:    4 | void Test1::D::h()
83// CHECK-NEXT:    5 | vbase_offset (16)
84// CHECK-NEXT:    6 | offset_to_top (-16)
85// CHECK-NEXT:    7 | Test1::D RTTI
86// CHECK-NEXT:        -- (Test1::C, 16) vtable address --
87// CHECK-NEXT:    8 | void Test1::C::g()
88// CHECK-NEXT:    9 | void Test1::D::h()
89// CHECK-NEXT:        [this adjustment: -16 non-virtual]
90// CHECK-NEXT:   10 | vcall_offset (-32)
91// CHECK-NEXT:   11 | vcall_offset (-16)
92// CHECK-NEXT:   12 | vcall_offset (-32)
93// CHECK-NEXT:   13 | offset_to_top (-32)
94// CHECK-NEXT:   14 | Test1::D RTTI
95// CHECK-NEXT:        -- (Test1::A, 32) vtable address --
96// CHECK-NEXT:   15 | void Test1::B::f()
97// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
98// CHECK-NEXT:   16 | void Test1::C::g()
99// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
100// CHECK-NEXT:   17 | void Test1::D::h()
101// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
102struct D: public B, public C {
103  void h ();
104  int id;
105};
106void D::h() { }
107
108struct X {
109  int ix;
110  virtual void x();
111};
112
113// CHECK:      Vtable for 'Test1::E' (24 entries).
114// CHECK-NEXT:    0 | vbase_offset (56)
115// CHECK-NEXT:    1 | offset_to_top (0)
116// CHECK-NEXT:    2 | Test1::E RTTI
117// CHECK-NEXT:        -- (Test1::E, 0) vtable address --
118// CHECK-NEXT:        -- (Test1::X, 0) vtable address --
119// CHECK-NEXT:    3 | void Test1::X::x()
120// CHECK-NEXT:    4 | void Test1::E::f()
121// CHECK-NEXT:    5 | void Test1::E::h()
122// CHECK-NEXT:    6 | vbase_offset (40)
123// CHECK-NEXT:    7 | offset_to_top (-16)
124// CHECK-NEXT:    8 | Test1::E RTTI
125// CHECK-NEXT:        -- (Test1::B, 16) vtable address --
126// CHECK-NEXT:        -- (Test1::D, 16) vtable address --
127// CHECK-NEXT:    9 | void Test1::E::f()
128// CHECK-NEXT:        [this adjustment: -16 non-virtual]
129// CHECK-NEXT:   10 | void Test1::E::h()
130// CHECK-NEXT:        [this adjustment: -16 non-virtual]
131// CHECK-NEXT:   11 | vbase_offset (24)
132// CHECK-NEXT:   12 | offset_to_top (-32)
133// CHECK-NEXT:   13 | Test1::E RTTI
134// CHECK-NEXT:        -- (Test1::C, 32) vtable address --
135// CHECK-NEXT:   14 | void Test1::C::g()
136// CHECK-NEXT:   15 | void Test1::E::h()
137// CHECK-NEXT:        [this adjustment: -32 non-virtual]
138// CHECK-NEXT:   16 | vcall_offset (-56)
139// CHECK-NEXT:   17 | vcall_offset (-24)
140// CHECK-NEXT:   18 | vcall_offset (-56)
141// CHECK-NEXT:   19 | offset_to_top (-56)
142// CHECK-NEXT:   20 | Test1::E RTTI
143// CHECK-NEXT:        -- (Test1::A, 56) vtable address --
144// CHECK-NEXT:   21 | void Test1::E::f()
145// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
146// CHECK-NEXT:   22 | void Test1::C::g()
147// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
148// CHECK-NEXT:   23 | void Test1::E::h()
149// CHECK-NEXT:        [this adjustment: 0 non-virtual, -40 vcall offset offset]
150struct E : X, D {
151  int ie;
152  void f();
153  void h ();
154};
155void E::f() { }
156
157}
158
159namespace Test2 {
160
161// From http://www.codesourcery.com/public/cxx-abi/abi.html#class-types.
162
163struct A { virtual void f(); };
164struct B : virtual public A { int i; };
165struct C : virtual public A { int j; };
166
167// CHECK:      Vtable for 'Test2::D' (11 entries).
168// CHECK-NEXT:    0 | vbase_offset (0)
169// CHECK-NEXT:    1 | vcall_offset (0)
170// CHECK-NEXT:    2 | offset_to_top (0)
171// CHECK-NEXT:    3 | Test2::D RTTI
172// CHECK-NEXT:        -- (Test2::A, 0) vtable address --
173// CHECK-NEXT:        -- (Test2::B, 0) vtable address --
174// CHECK-NEXT:        -- (Test2::D, 0) vtable address --
175// CHECK-NEXT:    4 | void Test2::A::f()
176// CHECK-NEXT:    5 | void Test2::D::d()
177// CHECK-NEXT:    6 | vbase_offset (-16)
178// CHECK-NEXT:    7 | vcall_offset (-16)
179// CHECK-NEXT:    8 | offset_to_top (-16)
180// CHECK-NEXT:    9 | Test2::D RTTI
181// CHECK-NEXT:        -- (Test2::C, 16) vtable address --
182// CHECK-NEXT:   10 | [unused] void Test2::A::f()
183struct D : public B, public C {
184  virtual void d();
185};
186void D::d() { }
187
188}
189
190namespace Test3 {
191
192// From http://www.codesourcery.com/public/cxx-abi/abi-examples.html#vtable-ctor
193
194struct V1 {
195  int v1;
196  virtual void f();
197};
198
199struct V2 : virtual V1 {
200  int v2;
201  virtual void f();
202};
203
204// CHECK:      Vtable for 'Test3::C' (14 entries).
205// CHECK-NEXT:    0 | vbase_offset (32)
206// CHECK-NEXT:    1 | vbase_offset (16)
207// CHECK-NEXT:    2 | offset_to_top (0)
208// CHECK-NEXT:    3 | Test3::C RTTI
209// CHECK-NEXT:        -- (Test3::C, 0) vtable address --
210// CHECK-NEXT:    4 | void Test3::C::f()
211// CHECK-NEXT:    5 | vcall_offset (-16)
212// CHECK-NEXT:    6 | offset_to_top (-16)
213// CHECK-NEXT:    7 | Test3::C RTTI
214// CHECK-NEXT:        -- (Test3::V1, 16) vtable address --
215// CHECK-NEXT:    8 | void Test3::C::f()
216// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
217// CHECK-NEXT:    9 | vcall_offset (-32)
218// CHECK-NEXT:   10 | vbase_offset (-16)
219// CHECK-NEXT:   11 | offset_to_top (-32)
220// CHECK-NEXT:   12 | Test3::C RTTI
221// CHECK-NEXT:        -- (Test3::V2, 32) vtable address --
222// CHECK-NEXT:   13 | void Test3::C::f()
223// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
224
225// CHECK:      Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries).
226// CHECK-NEXT:    0 | vcall_offset (0)
227// CHECK-NEXT:    1 | vbase_offset (-16)
228// CHECK-NEXT:    2 | offset_to_top (0)
229// CHECK-NEXT:    3 | Test3::V2 RTTI
230// CHECK-NEXT:        -- (Test3::V2, 32) vtable address --
231// CHECK-NEXT:    4 | void Test3::V2::f()
232// CHECK-NEXT:    5 | vcall_offset (16)
233// CHECK-NEXT:    6 | offset_to_top (16)
234// CHECK-NEXT:    7 | Test3::V2 RTTI
235// CHECK-NEXT:        -- (Test3::V1, 16) vtable address --
236// CHECK-NEXT:    8 | void Test3::V2::f()
237// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
238struct C : virtual V1, virtual V2 {
239  int c;
240  virtual void f();
241};
242void C::f() { }
243
244struct B {
245  int b;
246};
247
248// CHECK:      Vtable for 'Test3::D' (15 entries).
249// CHECK-NEXT:    0 | vbase_offset (40)
250// CHECK-NEXT:    1 | vbase_offset (24)
251// CHECK-NEXT:    2 | offset_to_top (0)
252// CHECK-NEXT:    3 | Test3::D RTTI
253// CHECK-NEXT:        -- (Test3::C, 0) vtable address --
254// CHECK-NEXT:        -- (Test3::D, 0) vtable address --
255// CHECK-NEXT:    4 | void Test3::C::f()
256// CHECK-NEXT:    5 | void Test3::D::g()
257// CHECK-NEXT:    6 | vcall_offset (-24)
258// CHECK-NEXT:    7 | offset_to_top (-24)
259// CHECK-NEXT:    8 | Test3::D RTTI
260// CHECK-NEXT:        -- (Test3::V1, 24) vtable address --
261// CHECK-NEXT:    9 | void Test3::C::f()
262// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
263// CHECK-NEXT:   10 | vcall_offset (-40)
264// CHECK-NEXT:   11 | vbase_offset (-16)
265// CHECK-NEXT:   12 | offset_to_top (-40)
266// CHECK-NEXT:   13 | Test3::D RTTI
267// CHECK-NEXT:        -- (Test3::V2, 40) vtable address --
268// CHECK-NEXT:   14 | void Test3::C::f()
269// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
270
271// CHECK:      Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries).
272// CHECK-NEXT:    0 | vbase_offset (40)
273// CHECK-NEXT:    1 | vbase_offset (24)
274// CHECK-NEXT:    2 | offset_to_top (0)
275// CHECK-NEXT:    3 | Test3::C RTTI
276// CHECK-NEXT:        -- (Test3::C, 0) vtable address --
277// CHECK-NEXT:    4 | void Test3::C::f()
278// CHECK-NEXT:    5 | vcall_offset (-24)
279// CHECK-NEXT:    6 | offset_to_top (-24)
280// CHECK-NEXT:    7 | Test3::C RTTI
281// CHECK-NEXT:        -- (Test3::V1, 24) vtable address --
282// CHECK-NEXT:    8 | void Test3::C::f()
283// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
284// CHECK-NEXT:    9 | vcall_offset (-40)
285// CHECK-NEXT:   10 | vbase_offset (-16)
286// CHECK-NEXT:   11 | offset_to_top (-40)
287// CHECK-NEXT:   12 | Test3::C RTTI
288// CHECK-NEXT:        -- (Test3::V2, 40) vtable address --
289// CHECK-NEXT:   13 | void Test3::C::f()
290// CHECK-NEXT:        [this adjustment: 0 non-virtual, -32 vcall offset offset]
291
292// CHECK:      Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries).
293// CHECK-NEXT:    0 | vcall_offset (0)
294// CHECK-NEXT:    1 | vbase_offset (-16)
295// CHECK-NEXT:    2 | offset_to_top (0)
296// CHECK-NEXT:    3 | Test3::V2 RTTI
297// CHECK-NEXT:        -- (Test3::V2, 40) vtable address --
298// CHECK-NEXT:    4 | void Test3::V2::f()
299// CHECK-NEXT:    5 | vcall_offset (16)
300// CHECK-NEXT:    6 | offset_to_top (16)
301// CHECK-NEXT:    7 | Test3::V2 RTTI
302// CHECK-NEXT:        -- (Test3::V1, 24) vtable address --
303// CHECK-NEXT:    8 | void Test3::V2::f()
304// CHECK-NEXT:        [this adjustment: 0 non-virtual, -24 vcall offset offset]
305struct D : B, C {
306  int d;
307  virtual void g();
308};
309void D::g() { }
310
311}
312