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