Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
      2 // RUN: FileCheck %s < %t
      3 
      4 struct A {
      5   virtual ~A();
      6   virtual void z1();
      7 };
      8 
      9 struct B {
     10   virtual ~B();
     11 };
     12 
     13 struct C : A, B {
     14   // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries).
     15   // CHECK-NEXT:   0 | C::~C() [scalar deleting]
     16   // CHECK-NEXT:   1 | void A::z1()
     17 
     18   // CHECK-LABEL: VFTable for 'B' in 'C' (1 entry).
     19   // CHECK-NEXT:   0 | C::~C() [scalar deleting]
     20   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
     21 
     22   // CHECK-LABEL: Thunks for 'C::~C()' (1 entry).
     23   // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
     24 
     25   // CHECK-LABEL: VFTable indices for 'C' (1 entry).
     26   // CHECK-NEXT:   0 | C::~C() [scalar deleting]
     27   virtual ~C();
     28 };
     29 
     30 void build_vftable(C *obj) { delete obj; }
     31 
     32 struct D {
     33   // No virtual destructor here!
     34   virtual void z4();
     35 };
     36 
     37 struct E : D, B {
     38   // Implicit virtual dtor here!
     39 
     40   // CHECK-LABEL: VFTable for 'D' in 'E' (1 entry).
     41   // CHECK-NEXT:   0 | void D::z4()
     42 
     43   // CHECK-LABEL: VFTable for 'B' in 'E' (1 entry).
     44   // CHECK-NEXT:   0 | E::~E() [scalar deleting]
     45   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
     46 
     47   // CHECK-LABEL: Thunks for 'E::~E()' (1 entry).
     48   // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
     49 
     50   // CHECK-LABEL: VFTable indices for 'E' (1 entry).
     51   // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
     52   // CHECK-NEXT:   0 | E::~E() [scalar deleting]
     53 };
     54 
     55 void build_vftable(E *obj) { delete obj; }
     56 
     57 struct F : D, B {
     58   // Implicit virtual dtor here!
     59 
     60   // CHECK-LABEL: VFTable for 'D' in 'F' (1 entry).
     61   // CHECK-NEXT:   0 | void D::z4()
     62 
     63   // CHECK-LABEL: VFTable for 'B' in 'F' (1 entry).
     64   // CHECK-NEXT:   0 | F::~F() [scalar deleting]
     65   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
     66 
     67   // CHECK-LABEL: Thunks for 'F::~F()' (1 entry).
     68   // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
     69 
     70   // CHECK-LABEL: VFTable indices for 'F' (1 entry).
     71   // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
     72   // CHECK-NEXT:   0 | F::~F() [scalar deleting]
     73 };
     74 
     75 void build_vftable(F *obj) { delete obj; }
     76 
     77 struct G : F {
     78   // CHECK-LABEL: VFTable for 'D' in 'F' in 'G' (1 entry).
     79   // CHECK-NEXT:   0 | void D::z4()
     80 
     81   // CHECK-LABEL: VFTable for 'B' in 'F' in 'G' (1 entry).
     82   // CHECK-NEXT:   0 | G::~G() [scalar deleting]
     83   // CHECK-NEXT:       [this adjustment: -4 non-virtual]
     84 
     85   // CHECK-LABEL: Thunks for 'G::~G()' (1 entry).
     86   // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
     87 
     88   // CHECK-LABEL: VFTable indices for 'G' (1 entry).
     89   // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
     90   // CHECK-NEXT:   0 | G::~G() [scalar deleting]
     91   virtual ~G();
     92 };
     93 
     94 void build_vftable(G *obj) { delete obj; }
     95