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