1// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s 2 3struct Left { 4 virtual void left(); 5}; 6 7struct Right { 8 virtual void right(); 9}; 10 11struct ChildNoOverride : Left, Right { 12}; 13 14struct ChildOverride : Left, Right { 15 virtual void left(); 16 virtual void right(); 17}; 18 19extern "C" void foo(void *); 20 21void 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 36void 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 50void 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 64void 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 84void 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 102void 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 125struct GrandchildOverride : ChildOverride { 126 virtual void right(); 127}; 128 129void 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 144void call_grandchild_right(GrandchildOverride *obj) { 145 // Just make sure we don't crash. 146 obj->right(); 147} 148 149void 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 185struct LeftWithNonVirtualDtor { 186 virtual void left(); 187 ~LeftWithNonVirtualDtor(); 188}; 189 190struct AsymmetricChild : LeftWithNonVirtualDtor, Right { 191 virtual ~AsymmetricChild(); 192}; 193 194void 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