xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o %t.ll > %t
2f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=EMITS-VFTABLE %s < %t.ll
3f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=NO-VFTABLE %s < %t.ll
4*0a6a1f1dSLionel Sambuc // RUN: FileCheck %s < %t
5f4a2713aSLionel Sambuc 
6f4a2713aSLionel Sambuc struct A {
7*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'A' (3 entries)
8*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void A::f()
9*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void A::g()
10*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void A::h()
11*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'A' (3 entries)
12*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void A::f()
13*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void A::g()
14*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void A::h()
15f4a2713aSLionel Sambuc 
16f4a2713aSLionel Sambuc   virtual void f();
17f4a2713aSLionel Sambuc   virtual void g();
18f4a2713aSLionel Sambuc   virtual void h();
19f4a2713aSLionel Sambuc   int ia;
20f4a2713aSLionel Sambuc };
21f4a2713aSLionel Sambuc A a;
22f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
use(A * obj)23*0a6a1f1dSLionel Sambuc void use(A *obj) { obj->f(); }
24f4a2713aSLionel Sambuc 
25f4a2713aSLionel Sambuc struct B : A {
26*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'A' in 'B' (5 entries)
27*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void B::f()
28*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void A::g()
29*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void A::h()
30*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void B::i()
31*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void B::j()
32*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'B' (3 entries)
33*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void B::f()
34*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void B::i()
35*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void B::j()
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc   virtual void f();  // overrides A::f()
38f4a2713aSLionel Sambuc   virtual void i();
39f4a2713aSLionel Sambuc   virtual void j();
40f4a2713aSLionel Sambuc };
41f4a2713aSLionel Sambuc B b;
42f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
use(B * obj)43*0a6a1f1dSLionel Sambuc void use(B *obj) { obj->f(); }
44f4a2713aSLionel Sambuc 
45f4a2713aSLionel Sambuc struct C {
46*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'C' (2 entries)
47*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | C::~C() [scalar deleting]
48*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void C::f()
49*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'C' (2 entries).
50*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | C::~C() [scalar deleting]
51*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void C::f()
52f4a2713aSLionel Sambuc 
53f4a2713aSLionel Sambuc   virtual ~C();
54f4a2713aSLionel Sambuc   virtual void f();
55f4a2713aSLionel Sambuc };
f()56f4a2713aSLionel Sambuc void C::f() {}
57f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7C@@6B@"
use(C * obj)58*0a6a1f1dSLionel Sambuc void use(C *obj) { obj->f(); }
59f4a2713aSLionel Sambuc 
60f4a2713aSLionel Sambuc struct D {
61*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'D' (2 entries)
62*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void D::f()
63*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | D::~D() [scalar deleting]
64*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'D' (2 entries)
65*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void D::f()
66*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | D::~D() [scalar deleting]
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   virtual void f();
69f4a2713aSLionel Sambuc   virtual ~D();
70f4a2713aSLionel Sambuc };
71f4a2713aSLionel Sambuc D d;
72f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
use(D * obj)73*0a6a1f1dSLionel Sambuc void use(D *obj) { obj->f(); }
74f4a2713aSLionel Sambuc 
75f4a2713aSLionel Sambuc struct E : A {
76*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'A' in 'E' (5 entries)
77*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void A::f()
78*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void A::g()
79*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void A::h()
80*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | E::~E() [scalar deleting]
81*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void E::i()
82*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'E' (2 entries).
83*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | E::~E() [scalar deleting]
84*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void E::i()
85f4a2713aSLionel Sambuc 
86f4a2713aSLionel Sambuc   // ~E would be the key method, but it isn't used, and MS ABI has no key
87f4a2713aSLionel Sambuc   // methods.
88f4a2713aSLionel Sambuc   virtual ~E();
89f4a2713aSLionel Sambuc   virtual void i();
90f4a2713aSLionel Sambuc };
i()91f4a2713aSLionel Sambuc void E::i() {}
92f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7E@@6B@"
use(E * obj)93*0a6a1f1dSLionel Sambuc void use(E *obj) { obj->i(); }
94f4a2713aSLionel Sambuc 
95f4a2713aSLionel Sambuc struct F : A {
96*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'A' in 'F' (5 entries)
97*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void A::f()
98*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void A::g()
99*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void A::h()
100*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void F::i()
101*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | F::~F() [scalar deleting]
102*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'F' (2 entries).
103*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void F::i()
104*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | F::~F() [scalar deleting]
105f4a2713aSLionel Sambuc 
106f4a2713aSLionel Sambuc   virtual void i();
107f4a2713aSLionel Sambuc   virtual ~F();
108f4a2713aSLionel Sambuc };
109f4a2713aSLionel Sambuc F f;
110f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
use(F * obj)111*0a6a1f1dSLionel Sambuc void use(F *obj) { obj->i(); }
112f4a2713aSLionel Sambuc 
113f4a2713aSLionel Sambuc struct G : E {
114*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'A' in 'E' in 'G' (6 entries)
115*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void G::f()
116*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void A::g()
117*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void A::h()
118*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | G::~G() [scalar deleting]
119*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void E::i()
120*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 5 | void G::j()
121*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable indices for 'G' (3 entries).
122*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void G::f()
123*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | G::~G() [scalar deleting]
124*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 5 | void G::j()
125f4a2713aSLionel Sambuc 
126f4a2713aSLionel Sambuc   virtual void f();  // overrides A::f()
127f4a2713aSLionel Sambuc   virtual ~G();
128f4a2713aSLionel Sambuc   virtual void j();
129f4a2713aSLionel Sambuc };
j()130f4a2713aSLionel Sambuc void G::j() {}
131f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7G@@6B@"
use(G * obj)132*0a6a1f1dSLionel Sambuc void use(G *obj) { obj->j(); }
133f4a2713aSLionel Sambuc 
134f4a2713aSLionel Sambuc // Test that the usual Itanium-style key method does not emit a vtable.
135f4a2713aSLionel Sambuc struct H {
136f4a2713aSLionel Sambuc   virtual void f();
137f4a2713aSLionel Sambuc };
f()138f4a2713aSLionel Sambuc void H::f() {}
139f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7H@@6B@"
140f4a2713aSLionel Sambuc 
141f4a2713aSLionel Sambuc struct Empty { };
142f4a2713aSLionel Sambuc 
143f4a2713aSLionel Sambuc struct I : Empty {
144*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'I' (2 entries)
145*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void I::f()
146*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void I::g()
147f4a2713aSLionel Sambuc   virtual void f();
148f4a2713aSLionel Sambuc   virtual void g();
149f4a2713aSLionel Sambuc };
150f4a2713aSLionel Sambuc 
151f4a2713aSLionel Sambuc I i;
use(I * obj)152*0a6a1f1dSLionel Sambuc void use(I *obj) { obj->f(); }
153f4a2713aSLionel Sambuc 
154f4a2713aSLionel Sambuc struct J {
155*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'J' (6 entries)
156*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void J::foo(long)
157*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void J::foo(int)
158*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void J::foo(short)
159*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void J::bar(long)
160*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void J::bar(int)
161*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 5 | void J::bar(short)
162f4a2713aSLionel Sambuc   virtual void foo(short);
163f4a2713aSLionel Sambuc   virtual void bar(short);
164f4a2713aSLionel Sambuc   virtual void foo(int);
165f4a2713aSLionel Sambuc   virtual void bar(int);
166f4a2713aSLionel Sambuc   virtual void foo(long);
167f4a2713aSLionel Sambuc   virtual void bar(long);
168f4a2713aSLionel Sambuc };
169f4a2713aSLionel Sambuc 
170f4a2713aSLionel Sambuc J j;
use(J * obj)171*0a6a1f1dSLionel Sambuc void use(J *obj) { obj->foo(42); }
172f4a2713aSLionel Sambuc 
173f4a2713aSLionel Sambuc struct K : J {
174*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'J' in 'K' (9 entries)
175*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void J::foo(long)
176*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void J::foo(int)
177*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void J::foo(short)
178*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void J::bar(long)
179*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void J::bar(int)
180*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 5 | void J::bar(short)
181*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 6 | void K::bar(double)
182*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 7 | void K::bar(float)
183*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 8 | void K::foo(float)
184f4a2713aSLionel Sambuc   virtual void bar(float);
185f4a2713aSLionel Sambuc   virtual void foo(float);
186f4a2713aSLionel Sambuc   virtual void bar(double);
187f4a2713aSLionel Sambuc };
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc K k;
use(K * obj)190*0a6a1f1dSLionel Sambuc void use(K *obj) { obj->foo(42.0f); }
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc struct L : J {
193*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'J' in 'L' (9 entries)
194*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void J::foo(long)
195*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void L::foo(int)
196*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void J::foo(short)
197*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void J::bar(long)
198*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 4 | void J::bar(int)
199*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 5 | void J::bar(short)
200*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 6 | void L::foo(float)
201*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 7 | void L::bar(double)
202*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 8 | void L::bar(float)
203f4a2713aSLionel Sambuc 
204f4a2713aSLionel Sambuc   // This case is interesting. Since the J::foo(int) override is the first method in
205f4a2713aSLionel Sambuc   // the class, foo(float) precedes the bar(double) and bar(float) in the vftable.
206f4a2713aSLionel Sambuc   virtual void foo(int);
207f4a2713aSLionel Sambuc   virtual void bar(float);
208f4a2713aSLionel Sambuc   virtual void foo(float);
209f4a2713aSLionel Sambuc   virtual void bar(double);
210f4a2713aSLionel Sambuc };
211f4a2713aSLionel Sambuc 
212f4a2713aSLionel Sambuc L l;
use(L * obj)213*0a6a1f1dSLionel Sambuc void use(L *obj) { obj->foo(42.0f); }
214f4a2713aSLionel Sambuc 
215f4a2713aSLionel Sambuc struct M : J {
216*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'J' in 'M' (11 entries)
217*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  0 | void J::foo(long)
218*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  1 | void M::foo(int)
219*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  2 | void J::foo(short)
220*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  3 | void J::bar(long)
221*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  4 | void J::bar(int)
222*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  5 | void J::bar(short)
223*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  6 | void M::foo(float)
224*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  7 | void M::spam(long)
225*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  8 | void M::spam(int)
226*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:  9 | void M::bar(double)
227*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 10 | void M::bar(float)
228f4a2713aSLionel Sambuc 
229f4a2713aSLionel Sambuc   virtual void foo(int);
230f4a2713aSLionel Sambuc   virtual void spam(int);
231f4a2713aSLionel Sambuc   virtual void bar(float);
232f4a2713aSLionel Sambuc   virtual void bar(double);
233f4a2713aSLionel Sambuc   virtual void foo(float);
234f4a2713aSLionel Sambuc   virtual void spam(long);
235f4a2713aSLionel Sambuc };
236f4a2713aSLionel Sambuc 
237f4a2713aSLionel Sambuc M m;
use(M * obj)238*0a6a1f1dSLionel Sambuc void use(M *obj) { obj->foo(42.0f); }
239f4a2713aSLionel Sambuc 
240f4a2713aSLionel Sambuc struct N {
241*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'N' (4 entries)
242*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void N::operator+(int)
243*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void N::operator+(short)
244*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void N::operator*(int)
245*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void N::operator*(short)
246f4a2713aSLionel Sambuc   virtual void operator+(short);
247f4a2713aSLionel Sambuc   virtual void operator*(short);
248f4a2713aSLionel Sambuc   virtual void operator+(int);
249f4a2713aSLionel Sambuc   virtual void operator*(int);
250f4a2713aSLionel Sambuc };
251f4a2713aSLionel Sambuc 
252f4a2713aSLionel Sambuc N n;
use(N * obj)253*0a6a1f1dSLionel Sambuc void use(N *obj) { obj->operator+(42); }
254*0a6a1f1dSLionel Sambuc 
255*0a6a1f1dSLionel Sambuc struct O { virtual A *f(); };
256*0a6a1f1dSLionel Sambuc struct P : O { virtual B *f(); };
257*0a6a1f1dSLionel Sambuc P p;
use(O * obj)258*0a6a1f1dSLionel Sambuc void use(O *obj) { obj->f(); }
use(P * obj)259*0a6a1f1dSLionel Sambuc void use(P *obj) { obj->f(); }
260*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'O' (1 entry)
261*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | A *O::f()
262*0a6a1f1dSLionel Sambuc 
263*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'O' in 'P' (1 entry)
264*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | B *P::f()
265*0a6a1f1dSLionel Sambuc 
266*0a6a1f1dSLionel Sambuc struct Q {
267*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'Q' (2 entries)
268*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void Q::foo(int)
269*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void Q::bar(int)
270*0a6a1f1dSLionel Sambuc   void foo(short);
271*0a6a1f1dSLionel Sambuc   void bar(short);
272*0a6a1f1dSLionel Sambuc   virtual void bar(int);
273*0a6a1f1dSLionel Sambuc   virtual void foo(int);
274*0a6a1f1dSLionel Sambuc };
275*0a6a1f1dSLionel Sambuc 
276*0a6a1f1dSLionel Sambuc Q q;
use(Q * obj)277*0a6a1f1dSLionel Sambuc void use(Q *obj) { obj->foo(42); }
278*0a6a1f1dSLionel Sambuc 
279*0a6a1f1dSLionel Sambuc // Inherited non-virtual overloads don't participate in the ordering.
280*0a6a1f1dSLionel Sambuc struct R : Q {
281*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'Q' in 'R' (4 entries)
282*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 0 | void Q::foo(int)
283*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 1 | void Q::bar(int)
284*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 2 | void R::bar(long)
285*0a6a1f1dSLionel Sambuc   // CHECK-NEXT: 3 | void R::foo(long)
286*0a6a1f1dSLionel Sambuc   virtual void bar(long);
287*0a6a1f1dSLionel Sambuc   virtual void foo(long);
288*0a6a1f1dSLionel Sambuc };
289*0a6a1f1dSLionel Sambuc 
290*0a6a1f1dSLionel Sambuc R r;
use(R * obj)291*0a6a1f1dSLionel Sambuc void use(R *obj) { obj->foo(42l); }
292*0a6a1f1dSLionel Sambuc 
293*0a6a1f1dSLionel Sambuc struct S {
294*0a6a1f1dSLionel Sambuc   // CHECK-LABEL: VFTable for 'S' (1 entry).
295*0a6a1f1dSLionel Sambuc   // CHECK-NEXT:   0 | void S::f() [deleted]
296*0a6a1f1dSLionel Sambuc   virtual void f() = delete;
297*0a6a1f1dSLionel Sambuc   S();
298*0a6a1f1dSLionel Sambuc   // EMITS-VFTABLE-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)]
299*0a6a1f1dSLionel Sambuc };
300*0a6a1f1dSLionel Sambuc 
S()301*0a6a1f1dSLionel Sambuc S::S() {}
302