16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// RUN: FileCheck %s < %t
36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct A {
56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual ~A();
66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual void z1();
76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct B {
106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual ~B();
116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct C : A, B {
146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries).
156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   1 | void A::z1()
176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'B' in 'C' (1 entry).
196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: Thunks for 'C::~C()' (1 entry).
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable indices for 'C' (1 entry).
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual ~C();
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid build_vftable(C *obj) { delete obj; }
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct D {
336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // No virtual destructor here!
346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual void z4();
356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct E : D, B {
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Implicit virtual dtor here!
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'D' in 'E' (1 entry).
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | void D::z4()
426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'B' in 'E' (1 entry).
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | E::~E() [scalar deleting]
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: Thunks for 'E::~E()' (1 entry).
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable indices for 'E' (1 entry).
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | E::~E() [scalar deleting]
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid build_vftable(E *obj) { delete obj; }
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct F : D, B {
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // Implicit virtual dtor here!
596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'D' in 'F' (1 entry).
616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | void D::z4()
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'B' in 'F' (1 entry).
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | F::~F() [scalar deleting]
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: Thunks for 'F::~F()' (1 entry).
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable indices for 'F' (1 entry).
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | F::~F() [scalar deleting]
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid build_vftable(F *obj) { delete obj; }
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesstruct G : F {
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'D' in 'F' in 'G' (1 entry).
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | void D::z4()
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable for 'B' in 'F' in 'G' (1 entry).
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | G::~G() [scalar deleting]
836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: Thunks for 'G::~G()' (1 entry).
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-LABEL: VFTable indices for 'G' (1 entry).
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // CHECK-NEXT:   0 | G::~G() [scalar deleting]
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  virtual ~G();
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines};
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid build_vftable(G *obj) { delete obj; }
95