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