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