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 5namespace Test1 { 6 7// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial. 8struct A { 9 virtual void f(); 10 ~A(); 11}; 12 13// CHECK: define void @_ZN5Test11AD2Ev 14// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2), i8*** 15A::~A() 16{ 17} 18 19} 20 21namespace Test2 { 22 23// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial. 24struct A { 25 virtual void f(); 26 ~A(); 27}; 28 29// CHECK: define void @_ZN5Test21AD2Ev 30// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2), i8*** 31A::~A() { 32 f(); 33} 34 35} 36 37namespace 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. 41struct Field { 42 ~Field() { } 43}; 44 45struct A { 46 virtual void f(); 47 ~A(); 48 49 Field field; 50}; 51 52// CHECK: define void @_ZN5Test31AD2Ev 53// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2), i8*** 54A::~A() { 55 56} 57 58} 59 60namespace Test4 { 61 62// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body 63// isn't trivial. 64 65void f(); 66 67struct Field { 68 ~Field() { f(); } 69}; 70 71struct A { 72 virtual void f(); 73 ~A(); 74 75 Field field; 76}; 77 78// CHECK: define void @_ZN5Test41AD2Ev 79// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2), i8*** 80A::~A() 81{ 82} 83 84} 85 86namespace 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 91struct Field { 92 ~Field(); 93}; 94 95struct A { 96 virtual void f(); 97 ~A(); 98 99 Field field; 100}; 101 102// CHECK: define void @_ZN5Test51AD2Ev 103// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2), i8*** 104A::~A() 105{ 106} 107 108} 109 110namespace 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 115struct NonTrivialDestructorBody { 116 ~NonTrivialDestructorBody(); 117}; 118 119struct Field { 120 NonTrivialDestructorBody nonTrivialDestructorBody; 121}; 122 123struct A { 124 virtual void f(); 125 ~A(); 126 127 Field field; 128}; 129 130// CHECK: define void @_ZN5Test61AD2Ev 131// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2), i8*** 132A::~A() 133{ 134} 135 136} 137 138namespace 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 143struct NonTrivialDestructorBody { 144 ~NonTrivialDestructorBody(); 145}; 146 147struct Field : NonTrivialDestructorBody { }; 148 149struct A { 150 virtual void f(); 151 ~A(); 152 153 Field field; 154}; 155 156// CHECK: define void @_ZN5Test71AD2Ev 157// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2), i8*** 158A::~A() 159{ 160} 161 162} 163 164namespace 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 169struct NonTrivialDestructorBody { 170 ~NonTrivialDestructorBody(); 171}; 172 173struct Field : virtual NonTrivialDestructorBody { }; 174 175struct A { 176 virtual void f(); 177 ~A(); 178 179 Field field; 180}; 181 182// CHECK: define void @_ZN5Test81AD2Ev 183// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2), i8*** 184A::~A() 185{ 186} 187 188} 189 190namespace Test9 { 191 192// Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor. 193struct A { virtual ~A () { } }; 194struct B : virtual A {}; 195struct C : virtual B { 196 virtual ~C(); 197}; 198C::~C() {} 199 200} 201