blob: 9a065d4c02fe4737b28d60d0edb451a679e776c6 [file] [log] [blame]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +00001// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o - > %t 2>&1
2// RUN: FileCheck --check-prefix=EMITS-VTABLE %s < %t
Reid Kleckner5a8b0492013-05-29 16:18:30 +00003// RUN: FileCheck --check-prefix=NO-VTABLE %s < %t
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +00004// RUN: FileCheck --check-prefix=CHECK-A %s < %t
5// RUN: FileCheck --check-prefix=CHECK-B %s < %t
6// RUN: FileCheck --check-prefix=CHECK-C %s < %t
7// RUN: FileCheck --check-prefix=CHECK-D %s < %t
8// RUN: FileCheck --check-prefix=CHECK-E %s < %t
9// RUN: FileCheck --check-prefix=CHECK-F %s < %t
10// RUN: FileCheck --check-prefix=CHECK-G %s < %t
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000011// RUN: FileCheck --check-prefix=CHECK-I %s < %t
12
13// FIXME: Currently, we only test VFTableContext in the AST, but still use
14// VTableContext for CodeGen. We should remove the "Vtable" checks below when we
15// completely switch from VTableContext to VFTableContext.
16// Currently, the order of Vtable vs VFTable output depends on whether the
17// v*table info was required by a constructor or a method definition.
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000018
19struct A {
Timur Iskhodzhanov8f189a92013-08-21 06:25:03 +000020 // CHECK-A: VFTable for 'A' (3 entries)
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000021 // CHECK-A-NEXT: 0 | void A::f()
22 // CHECK-A-NEXT: 1 | void A::g()
23 // CHECK-A-NEXT: 2 | void A::h()
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000024
Timur Iskhodzhanov8f189a92013-08-21 06:25:03 +000025 // CHECK-A: Vtable for 'A' (3 entries)
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000026 // CHECK-A-NEXT: 0 | void A::f()
27 // CHECK-A-NEXT: 1 | void A::g()
28 // CHECK-A-NEXT: 2 | void A::h()
29
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000030 virtual void f();
31 virtual void g();
32 virtual void h();
33 int ia;
34};
Reid Kleckner5a8b0492013-05-29 16:18:30 +000035A a;
36// EMITS-VTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000037
38struct B : A {
39 // CHECK-B: Vtable for 'B' (5 entries)
40 // CHECK-B-NEXT: 0 | void B::f()
41 // CHECK-B-NEXT: 1 | void A::g()
42 // CHECK-B-NEXT: 2 | void A::h()
43 // CHECK-B-NEXT: 3 | void B::i()
44 // CHECK-B-NEXT: 4 | void B::j()
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000045
46 // CHECK-B: VFTable for 'A' in 'B' (5 entries)
47 // CHECK-B-NEXT: 0 | void B::f()
48 // CHECK-B-NEXT: 1 | void A::g()
49 // CHECK-B-NEXT: 2 | void A::h()
50 // CHECK-B-NEXT: 3 | void B::i()
51 // CHECK-B-NEXT: 4 | void B::j()
52
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000053 virtual void f(); // overrides A::f()
54 virtual void i();
55 virtual void j();
56};
Reid Kleckner5a8b0492013-05-29 16:18:30 +000057B b;
58// EMITS-VTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000059
60struct C {
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000061 // CHECK-C: VFTable for 'C' (2 entries)
62 // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
63 // CHECK-C-NEXT: 1 | void C::f()
64 // CHECK-C: VFTable indices for 'C' (2 entries).
65 // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
66 // CHECK-C-NEXT: 1 | void C::f()
67
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000068 // CHECK-C: Vtable for 'C' (2 entries)
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +000069 // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000070 // CHECK-C-NEXT: 1 | void C::f()
71 // CHECK-C: VTable indices for 'C' (2 entries).
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +000072 // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000073 // CHECK-C-NEXT: 1 | void C::f()
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000074
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000075 virtual ~C();
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000076 virtual void f();
77};
78void C::f() {}
Reid Kleckner5a8b0492013-05-29 16:18:30 +000079// NO-VTABLE-NOT: @"\01??_7C@@6B@"
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000080
81struct D {
82 // CHECK-D: Vtable for 'D' (2 entries)
83 // CHECK-D-NEXT: 0 | void D::f()
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +000084 // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000085
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000086 // CHECK-D: VFTable for 'D' (2 entries)
87 // CHECK-D-NEXT: 0 | void D::f()
88 // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
89
90 virtual void f();
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000091 virtual ~D();
92};
Reid Kleckner5a8b0492013-05-29 16:18:30 +000093D d;
94// EMITS-VTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +000095
96struct E : A {
Timur Iskhodzhanov635de282013-07-30 09:46:19 +000097 // CHECK-E: VFTable for 'A' in 'E' (5 entries)
98 // CHECK-E-NEXT: 0 | void A::f()
99 // CHECK-E-NEXT: 1 | void A::g()
100 // CHECK-E-NEXT: 2 | void A::h()
101 // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
102 // CHECK-E-NEXT: 4 | void E::i()
103 // CHECK-E: VFTable indices for 'E' (2 entries).
104 // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
105 // CHECK-E-NEXT: 4 | void E::i()
106
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000107 // CHECK-E: Vtable for 'E' (5 entries)
108 // CHECK-E-NEXT: 0 | void A::f()
109 // CHECK-E-NEXT: 1 | void A::g()
110 // CHECK-E-NEXT: 2 | void A::h()
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000111 // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000112 // CHECK-E-NEXT: 4 | void E::i()
113 // CHECK-E: VTable indices for 'E' (2 entries).
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000114 // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000115 // CHECK-E-NEXT: 4 | void E::i()
116
Reid Kleckner5a8b0492013-05-29 16:18:30 +0000117 // ~E would be the key method, but it isn't used, and MS ABI has no key
118 // methods.
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000119 virtual ~E();
120 virtual void i();
121};
122void E::i() {}
Reid Kleckner5a8b0492013-05-29 16:18:30 +0000123// NO-VTABLE-NOT: @"\01??_7E@@6B@"
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000124
125struct F : A {
126 // CHECK-F: Vtable for 'F' (5 entries)
127 // CHECK-F-NEXT: 0 | void A::f()
128 // CHECK-F-NEXT: 1 | void A::g()
129 // CHECK-F-NEXT: 2 | void A::h()
130 // CHECK-F-NEXT: 3 | void F::i()
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000131 // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000132 // CHECK-F: VTable indices for 'F' (2 entries).
133 // CHECK-F-NEXT: 3 | void F::i()
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000134 // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
Timur Iskhodzhanov635de282013-07-30 09:46:19 +0000135
136 // CHECK-F: VFTable for 'A' in 'F' (5 entries)
137 // CHECK-F-NEXT: 0 | void A::f()
138 // CHECK-F-NEXT: 1 | void A::g()
139 // CHECK-F-NEXT: 2 | void A::h()
140 // CHECK-F-NEXT: 3 | void F::i()
141 // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
142 // CHECK-F: VFTable indices for 'F' (2 entries).
143 // CHECK-F-NEXT: 3 | void F::i()
144 // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
145
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000146 virtual void i();
147 virtual ~F();
148};
Reid Kleckner5a8b0492013-05-29 16:18:30 +0000149F f;
150// EMITS-VTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000151
152struct G : E {
Timur Iskhodzhanov635de282013-07-30 09:46:19 +0000153 // CHECK-G: VFTable for 'A' in 'E' in 'G' (6 entries)
154 // CHECK-G-NEXT: 0 | void G::f()
155 // CHECK-G-NEXT: 1 | void A::g()
156 // CHECK-G-NEXT: 2 | void A::h()
157 // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
158 // CHECK-G-NEXT: 4 | void E::i()
159 // CHECK-G-NEXT: 5 | void G::j()
160 // CHECK-G: VFTable indices for 'G' (3 entries).
161 // CHECK-G-NEXT: 0 | void G::f()
162 // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
163 // CHECK-G-NEXT: 5 | void G::j()
164
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000165 // CHECK-G: Vtable for 'G' (6 entries)
166 // CHECK-G-NEXT: 0 | void G::f()
167 // CHECK-G-NEXT: 1 | void A::g()
168 // CHECK-G-NEXT: 2 | void A::h()
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000169 // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000170 // CHECK-G-NEXT: 4 | void E::i()
171 // CHECK-G-NEXT: 5 | void G::j()
172 // CHECK-G: VTable indices for 'G' (3 entries).
173 // CHECK-G-NEXT: 0 | void G::f()
Timur Iskhodzhanov59660c22013-02-13 08:37:51 +0000174 // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000175 // CHECK-G-NEXT: 5 | void G::j()
Timur Iskhodzhanov635de282013-07-30 09:46:19 +0000176
Timur Iskhodzhanov649c7312013-01-21 13:02:41 +0000177 virtual void f(); // overrides A::f()
178 virtual ~G();
179 virtual void j();
180};
181void G::j() {}
Reid Kleckner5a8b0492013-05-29 16:18:30 +0000182// NO-VTABLE-NOT: @"\01??_7G@@6B@"
Reid Klecknerc72ff4f2013-05-29 16:51:17 +0000183
184// Test that the usual Itanium-style key method does not emit a vtable.
185struct H {
186 virtual void f();
187};
188void H::f() {}
189// NO-VTABLE-NOT: @"\01??_7H@@6B@"
Timur Iskhodzhanov635de282013-07-30 09:46:19 +0000190
191struct Empty { };
192
193struct I : Empty {
194 // CHECK-I: VFTable for 'I' (2 entries)
195 // CHECK-I-NEXT: 0 | void I::f()
196 // CHECK-I-NEXT: 1 | void I::g()
197 virtual void f();
198 virtual void g();
199};
200
201I i;