1 // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
2
3 struct Left {
4 virtual void left();
5 };
6
7 struct Right {
8 virtual void right();
9 };
10
11 struct ChildNoOverride : Left, Right {
12 };
13
14 struct ChildOverride : Left, Right {
15 virtual void left();
16 virtual void right();
17 };
18
19 extern "C" void foo(void *);
20
call_left_no_override(ChildNoOverride * child)21 void call_left_no_override(ChildNoOverride *child) {
22 // CHECK: define void @"\01?call_left_no_override
23 // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
24
25 child->left();
26 // Only need to cast 'this' to Left*.
27 // CHECK: %[[LEFT:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to %struct.Left*
28 // CHECK: %[[VFPTR:.*]] = bitcast %struct.Left* %[[LEFT]] to void (%struct.Left*)***
29 // CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)**, void (%struct.Left*)*** %[[VFPTR]]
30 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)*, void (%struct.Left*)** %[[VFTABLE]], i64 0
31 // CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)*, void (%struct.Left*)** %[[VFUN]]
32 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Left* %[[LEFT]])
33 // CHECK: ret
34 }
35
left()36 void ChildOverride::left() {
37 // CHECK: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"(%struct.ChildOverride* %[[THIS:.*]])
38 //
39 // No need to adjust 'this' as the ChildOverride's layout begins with Left.
40 // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
41 // CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
42
43 foo(this);
44 // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
45 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
46 // CHECK: call void @foo(i8* %[[THIS_i8]])
47 // CHECK: ret
48 }
49
call_left_override(ChildOverride * child)50 void call_left_override(ChildOverride *child) {
51 // CHECK: define void @"\01?call_left_override
52 // CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
53
54 child->left();
55 // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to void (%struct.ChildOverride*)***
56 // CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)**, void (%struct.ChildOverride*)*** %[[VFPTR]]
57 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0
58 // CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFUN]]
59 //
60 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.ChildOverride* %[[CHILD]])
61 // CHECK: ret
62 }
63
call_right_no_override(ChildNoOverride * child)64 void call_right_no_override(ChildNoOverride *child) {
65 // CHECK: define void @"\01?call_right_no_override
66 // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
67
68 child->right();
69 // When calling a right base's virtual method, one needs to adjust 'this' at
70 // the caller site.
71 //
72 // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8*
73 // CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
74 // CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right*
75 //
76 // CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)***
77 // CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]]
78 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0
79 // CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)*, void (%struct.Right*)** %[[VFUN]]
80 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Right* %[[RIGHT]])
81 // CHECK: ret
82 }
83
right()84 void ChildOverride::right() {
85 // CHECK: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8*
86 //
87 // ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we
88 // need to adjust 'this' before use.
89 //
90 // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
91 // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
92 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.ChildOverride*
93 // CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
94
95 foo(this);
96 // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
97 // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
98 // CHECK: call void @foo(i8* %[[THIS_PARAM]])
99 // CHECK: ret
100 }
101
call_right_override(ChildOverride * child)102 void call_right_override(ChildOverride *child) {
103 // CHECK: define void @"\01?call_right_override
104 // CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
105
106 child->right();
107 // When calling a right child's virtual method, one needs to adjust 'this' at
108 // the caller site.
109 //
110 // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
111 //
112 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
113 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to void (i8*)***
114 // CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
115 // CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 0
116 // CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
117 //
118 // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
119 // CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
120 //
121 // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[RIGHT]])
122 // CHECK: ret
123 }
124
125 struct GrandchildOverride : ChildOverride {
126 virtual void right();
127 };
128
right()129 void GrandchildOverride::right() {
130 // CHECK: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8*
131 //
132 // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4
133 // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
134 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.GrandchildOverride*
135 // CHECK: store %struct.GrandchildOverride* %[[THIS]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
136
137 foo(this);
138 // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
139 // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
140 // CHECK: call void @foo(i8* %[[THIS_PARAM]])
141 // CHECK: ret
142 }
143
call_grandchild_right(GrandchildOverride * obj)144 void call_grandchild_right(GrandchildOverride *obj) {
145 // Just make sure we don't crash.
146 obj->right();
147 }
148
emit_ctors()149 void emit_ctors() {
150 Left l;
151 // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
152 // CHECK-NOT: getelementptr
153 // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Left@@6B@" to i32 (...)**)
154 // CHECK: ret
155
156 Right r;
157 // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
158 // CHECK-NOT: getelementptr
159 // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Right@@6B@" to i32 (...)**)
160 // CHECK: ret
161
162 ChildOverride co;
163 // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
164 // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
165 // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
166 // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
167 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
168 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
169 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
170 // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
171 // CHECK: ret
172
173 GrandchildOverride gc;
174 // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
175 // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
176 // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
177 // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
178 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
179 // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
180 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
181 // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
182 // CHECK: ret
183 }
184
185 struct LeftWithNonVirtualDtor {
186 virtual void left();
187 ~LeftWithNonVirtualDtor();
188 };
189
190 struct AsymmetricChild : LeftWithNonVirtualDtor, Right {
191 virtual ~AsymmetricChild();
192 };
193
call_asymmetric_child_complete_dtor()194 void call_asymmetric_child_complete_dtor() {
195 // CHECK-LABEL: define void @"\01?call_asymmetric_child_complete_dtor@@YAXXZ"
196 AsymmetricChild obj;
197 // CHECK: call x86_thiscallcc %struct.AsymmetricChild* @"\01??0AsymmetricChild@@QAE@XZ"(%struct.AsymmetricChild* %[[OBJ:.*]])
198 // CHECK-NOT: getelementptr
199 // CHECK: call x86_thiscallcc void @"\01??1AsymmetricChild@@UAE@XZ"(%struct.AsymmetricChild* %[[OBJ]])
200 // CHECK: ret
201 }
202