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 (...)***
~A()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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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 {
~FieldTest3::Field42 ~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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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 {
~FieldTest4::Field68 ~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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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, i64 0, i64 2) to i32 (...)**), i32 (...)***
~A()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.
~ATest9::A193 struct A { virtual ~A () { } };
194 struct B : virtual A {};
195 struct C : virtual B {
196 virtual ~C();
197 };
~C()198 C::~C() {}
199
200 }
201