Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
      2 
      3 // See Test9 for test description.
      4 // CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant
      5 namespace Test1 {
      6 
      7 // Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial.
      8 struct A {
      9   virtual void f();
     10   ~A();
     11 };
     12 
     13 // CHECK-LABEL: define void @_ZN5Test11AD2Ev
     14 // CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
     15 A::~A()
     16 {
     17 }
     18 
     19 }
     20 
     21 namespace Test2 {
     22 
     23 // Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial.
     24 struct A {
     25   virtual void f();
     26   ~A();
     27 };
     28 
     29 // CHECK-LABEL: define void @_ZN5Test21AD2Ev
     30 // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test21AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
     31 A::~A() {
     32   f();
     33 }
     34 
     35 }
     36 
     37 namespace Test3 {
     38 
     39 // Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial
     40 // and Field's destructor body is also trivial.
     41 struct Field {
     42   ~Field() { }
     43 };
     44 
     45 struct A {
     46   virtual void f();
     47   ~A();
     48 
     49   Field field;
     50 };
     51 
     52 // CHECK-LABEL: define void @_ZN5Test31AD2Ev
     53 // CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test31AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
     54 A::~A() {
     55 
     56 }
     57 
     58 }
     59 
     60 namespace Test4 {
     61 
     62 // Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body
     63 // isn't trivial.
     64 
     65 void f();
     66 
     67 struct Field {
     68   ~Field() { f(); }
     69 };
     70 
     71 struct A {
     72   virtual void f();
     73   ~A();
     74 
     75   Field field;
     76 };
     77 
     78 // CHECK-LABEL: define void @_ZN5Test41AD2Ev
     79 // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test41AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
     80 A::~A()
     81 {
     82 }
     83 
     84 }
     85 
     86 namespace Test5 {
     87 
     88 // Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't
     89 // available in this translation unit.
     90 
     91 struct Field {
     92   ~Field();
     93 };
     94 
     95 struct A {
     96   virtual void f();
     97   ~A();
     98 
     99   Field field;
    100 };
    101 
    102 // CHECK-LABEL: define void @_ZN5Test51AD2Ev
    103 // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test51AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
    104 A::~A()
    105 {
    106 }
    107 
    108 }
    109 
    110 namespace Test6 {
    111 
    112 // Check that we do initialize the vtable pointer in A::~A(), since Field has a member
    113 // variable with a non-trivial destructor body.
    114 
    115 struct NonTrivialDestructorBody {
    116   ~NonTrivialDestructorBody();
    117 };
    118 
    119 struct Field {
    120   NonTrivialDestructorBody nonTrivialDestructorBody;
    121 };
    122 
    123 struct A {
    124   virtual void f();
    125   ~A();
    126 
    127   Field field;
    128 };
    129 
    130 // CHECK-LABEL: define void @_ZN5Test61AD2Ev
    131 // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test61AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
    132 A::~A()
    133 {
    134 }
    135 
    136 }
    137 
    138 namespace Test7 {
    139 
    140 // Check that we do initialize the vtable pointer in A::~A(), since Field has a base
    141 // class with a non-trivial destructor body.
    142 
    143 struct NonTrivialDestructorBody {
    144   ~NonTrivialDestructorBody();
    145 };
    146 
    147 struct Field : NonTrivialDestructorBody { };
    148 
    149 struct A {
    150   virtual void f();
    151   ~A();
    152 
    153   Field field;
    154 };
    155 
    156 // CHECK-LABEL: define void @_ZN5Test71AD2Ev
    157 // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test71AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
    158 A::~A()
    159 {
    160 }
    161 
    162 }
    163 
    164 namespace Test8 {
    165 
    166 // Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base
    167 // class with a non-trivial destructor body.
    168 
    169 struct NonTrivialDestructorBody {
    170   ~NonTrivialDestructorBody();
    171 };
    172 
    173 struct Field : virtual NonTrivialDestructorBody { };
    174 
    175 struct A {
    176   virtual void f();
    177   ~A();
    178 
    179   Field field;
    180 };
    181 
    182 // CHECK-LABEL: define void @_ZN5Test81AD2Ev
    183 // CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test81AE, i32 0, i32 2) to i32 (...)**), i32 (...)***
    184 A::~A()
    185 {
    186 }
    187 
    188 }
    189 
    190 namespace Test9 {
    191 
    192 // Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor.
    193 struct A { virtual ~A () { } };
    194 struct B : virtual A {};
    195 struct C : virtual B {
    196   virtual ~C();
    197 };
    198 C::~C() {}
    199 
    200 }
    201