1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
28f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
38f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovstruct Left {
48f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  virtual void left();
58f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov};
68f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
78f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovstruct Right {
88f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  virtual void right();
98f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov};
108f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
118f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovstruct ChildNoOverride : Left, Right {
128f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov};
138f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
148f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovstruct ChildOverride : Left, Right {
158f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  virtual void left();
168f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  virtual void right();
178f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov};
188f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
198f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovextern "C" void foo(void *);
208f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
218f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid call_left_no_override(ChildNoOverride *child) {
228f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define void @"\01?call_left_no_override
238f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
248f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
258f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  child->left();
268f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// Only need to cast 'this' to Left*.
278f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[LEFT:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to %struct.Left*
288f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[VFPTR:.*]] = bitcast %struct.Left* %[[LEFT]] to void (%struct.Left*)***
293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)**, void (%struct.Left*)*** %[[VFPTR]]
303ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)*, void (%struct.Left*)** %[[VFTABLE]], i64 0
313ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)*, void (%struct.Left*)** %[[VFUN]]
328f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Left* %[[LEFT]])
338f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
348f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
358f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
368f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid ChildOverride::left() {
378f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"(%struct.ChildOverride* %[[THIS:.*]])
388f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
398f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// No need to adjust 'this' as the ChildOverride's layout begins with Left.
408f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
418f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
428f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
438f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  foo(this);
443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
458f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
468f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call void @foo(i8* %[[THIS_i8]])
478f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
488f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
498f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
508f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid call_left_override(ChildOverride *child) {
518f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define void @"\01?call_left_override
528f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
538f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
548f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  child->left();
558f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to void (%struct.ChildOverride*)***
563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)**, void (%struct.ChildOverride*)*** %[[VFPTR]]
573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0
583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFUN]]
598f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
608f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.ChildOverride* %[[CHILD]])
618f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
628f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
638f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
648f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid call_right_no_override(ChildNoOverride *child) {
658f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define void @"\01?call_right_no_override
668f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride
678f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
688f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  child->right();
698f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// When calling a right base's virtual method, one needs to adjust 'this' at
708f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// the caller site.
718f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
728f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8*
733ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
748f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right*
758f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
768f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)***
773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]]
783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0
793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)*, void (%struct.Right*)** %[[VFUN]]
808f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Right* %[[RIGHT]])
818f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
828f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
838f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
848f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid ChildOverride::right() {
858f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8*
868f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
878f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we
888f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// need to adjust 'this' before use.
898f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
908f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4
913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
928f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.ChildOverride*
938f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4
948f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
958f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  foo(this);
963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]]
978f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
988f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call void @foo(i8* %[[THIS_PARAM]])
998f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
1008f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
1018f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
1028f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid call_right_override(ChildOverride *child) {
1038f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define void @"\01?call_right_override
1048f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD:.*]] = load %struct.ChildOverride
1058f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
1068f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  child->right();
1078f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// When calling a right child's virtual method, one needs to adjust 'this' at
1088f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// the caller site.
1098f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
1108f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
1118f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
1123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
1138f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to void (i8*)***
1143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]]
1153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 0
1163ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]]
1178f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
1188f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8*
1193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4
1208f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
1218f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[RIGHT]])
1228f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
1238f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
1248f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
1258f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovstruct GrandchildOverride : ChildOverride {
1268f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  virtual void right();
1278f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov};
1288f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
1298f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid GrandchildOverride::right() {
1308f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8*
1318f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov//
1328f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4
1333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4
1348f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.GrandchildOverride*
1358f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: store %struct.GrandchildOverride* %[[THIS]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4
1368f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
1378f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  foo(this);
1383ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]]
1398f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
1408f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: call void @foo(i8* %[[THIS_PARAM]])
1418f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov// CHECK: ret
1428f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
1438f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov
1448f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanovvoid call_grandchild_right(GrandchildOverride *obj) {
1458f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  // Just make sure we don't crash.
1468f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov  obj->right();
1478f189a9911a992a5c4118c3789485a85bd96e045Timur Iskhodzhanov}
148a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov
149a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanovvoid emit_ctors() {
150a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  Left l;
151a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ"
152a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK-NOT: getelementptr
1530e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Left@@6B@" to i32 (...)**)
154a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: ret
155a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov
156a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  Right r;
157a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ"
158a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK-NOT: getelementptr
1590e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7Right@@6B@" to i32 (...)**)
160a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: ret
161a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov
162a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  ChildOverride co;
163a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ"
1643ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK:   %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride**
1650e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)***
1660e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
167a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8*
1683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK:   %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
1690e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
1700e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
171a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: ret
172a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov
173a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  GrandchildOverride gc;
174a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ"
1753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK:   %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride**
1760e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)***
1770e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
178a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK:   %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8*
1793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  // CHECK:   %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4
1800e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)***
1810e2c34f92f00628d48968dfea096d36381f494cbStephen Hines  // CHECK:   store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]]
182a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov  // CHECK: ret
183a53d7a0259ff88f78ba8ecac7d0cb3ea96302b1dTimur Iskhodzhanov}
18482552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov
18582552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanovstruct LeftWithNonVirtualDtor {
18682552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  virtual void left();
18782552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  ~LeftWithNonVirtualDtor();
18882552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov};
18982552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov
19082552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanovstruct AsymmetricChild : LeftWithNonVirtualDtor, Right {
19182552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  virtual ~AsymmetricChild();
19282552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov};
19382552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov
19482552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanovvoid call_asymmetric_child_complete_dtor() {
19582552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  // CHECK-LABEL: define void @"\01?call_asymmetric_child_complete_dtor@@YAXXZ"
19682552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  AsymmetricChild obj;
19782552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  // CHECK: call x86_thiscallcc %struct.AsymmetricChild* @"\01??0AsymmetricChild@@QAE@XZ"(%struct.AsymmetricChild* %[[OBJ:.*]])
19882552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  // CHECK-NOT: getelementptr
19982552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  // CHECK: call x86_thiscallcc void @"\01??1AsymmetricChild@@UAE@XZ"(%struct.AsymmetricChild* %[[OBJ]])
20082552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov  // CHECK: ret
20182552742a1002cf1408d6f371efc9cc6a9f2d7ccTimur Iskhodzhanov}
202