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