• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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