diff options
Diffstat (limited to 'clang/test/CodeGenCXX')
4 files changed, 64 insertions, 43 deletions
diff --git a/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp index f9db2680e33..5bed69ff117 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp @@ -19,7 +19,7 @@ struct ChildOverride : Left, Right { extern "C" void foo(void *); void call_left_no_override(ChildNoOverride *child) { -// CHECK: define void @"\01?call_left_no_override +// CHECK-LABEL: define void @"\01?call_left_no_override // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride child->left(); @@ -34,7 +34,8 @@ void call_left_no_override(ChildNoOverride *child) { } void ChildOverride::left() { -// CHECK: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ"(%struct.ChildOverride* %[[THIS:.*]]) +// CHECK-LABEL: define x86_thiscallcc void @"\01?left@ChildOverride@@UAEXXZ" +// CHECK-SAME: (%struct.ChildOverride* %[[THIS:.*]]) // // No need to adjust 'this' as the ChildOverride's layout begins with Left. // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4 @@ -48,7 +49,7 @@ void ChildOverride::left() { } void call_left_override(ChildOverride *child) { -// CHECK: define void @"\01?call_left_override +// CHECK-LABEL: define void @"\01?call_left_override // CHECK: %[[CHILD:.*]] = load %struct.ChildOverride child->left(); @@ -62,7 +63,7 @@ void call_left_override(ChildOverride *child) { } void call_right_no_override(ChildNoOverride *child) { -// CHECK: define void @"\01?call_right_no_override +// CHECK-LABEL: define void @"\01?call_right_no_override // CHECK: %[[CHILD:.*]] = load %struct.ChildNoOverride child->right(); @@ -82,25 +83,27 @@ void call_right_no_override(ChildNoOverride *child) { } void ChildOverride::right() { -// CHECK: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8* +// CHECK-LABEL: define x86_thiscallcc void @"\01?right@ChildOverride@@UAEXXZ"(i8* // // ChildOverride::right gets 'this' cast to Right* in ECX (i.e. this+4) so we // need to adjust 'this' before use. // // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4 -// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4 -// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.ChildOverride* -// CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4 +// CHECK: %[[THIS_INIT:.*]] = bitcast i8* %[[ECX:.*]] to %struct.ChildOverride* +// CHECK: store %struct.ChildOverride* %[[THIS_INIT]], %struct.ChildOverride** %[[THIS_ADDR]], align 4 +// CHECK: %[[THIS_RELOAD:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]] +// CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS_RELOAD]] to i8* +// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4 +// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.ChildOverride* foo(this); -// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]] // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* // CHECK: call void @foo(i8* %[[THIS_PARAM]]) // CHECK: ret } void call_right_override(ChildOverride *child) { -// CHECK: define void @"\01?call_right_override +// CHECK-LABEL: define void @"\01?call_right_override // CHECK: %[[CHILD:.*]] = load %struct.ChildOverride child->right(); @@ -127,15 +130,17 @@ struct GrandchildOverride : ChildOverride { }; void GrandchildOverride::right() { -// CHECK: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8* +// CHECK-LABEL: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8* // // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4 -// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4 -// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.GrandchildOverride* -// CHECK: store %struct.GrandchildOverride* %[[THIS]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4 +// CHECK: %[[THIS_INIT:.*]] = bitcast i8* %[[ECX:.*]] to %struct.GrandchildOverride* +// CHECK: store %struct.GrandchildOverride* %[[THIS_INIT]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4 +// CHECK: %[[THIS_RELOAD:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]] +// CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS_RELOAD]] to i8* +// CHECK: %[[THIS_ADJUSTED:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 -4 +// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJUSTED]] to %struct.GrandchildOverride* foo(this); -// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]] // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8* // CHECK: call void @foo(i8* %[[THIS_PARAM]]) // CHECK: ret @@ -148,19 +153,19 @@ void call_grandchild_right(GrandchildOverride *obj) { void emit_ctors() { Left l; - // CHECK: define {{.*}} @"\01??0Left@@QAE@XZ" + // CHECK-LABEL: define {{.*}} @"\01??0Left@@QAE@XZ" // CHECK-NOT: getelementptr // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Left@@6B@" to i32 (...)**) // CHECK: ret Right r; - // CHECK: define {{.*}} @"\01??0Right@@QAE@XZ" + // CHECK-LABEL: define {{.*}} @"\01??0Right@@QAE@XZ" // CHECK-NOT: getelementptr // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7Right@@6B@" to i32 (...)**) // CHECK: ret ChildOverride co; - // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ" + // CHECK-LABEL: define {{.*}} @"\01??0ChildOverride@@QAE@XZ" // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] @@ -171,7 +176,7 @@ void emit_ctors() { // CHECK: ret GrandchildOverride gc; - // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ" + // CHECK-LABEL: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ" // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ({ [1 x i8*] }* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp index bb73f8773cc..2f141b2a66e 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp @@ -24,6 +24,7 @@ struct D : virtual C { D::D() {} // Forces vftable emission. // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ" +// Note that the vtordisp is applied before really adjusting to D*. // CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}} // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8* // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX_i8]], i32 -4 diff --git a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp index 20ecaf43165..c9dd1dd7d8e 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t +// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=i386-pc-win32 -emit-llvm -o %t // RUN: FileCheck %s < %t // RUN: FileCheck --check-prefix=CHECK2 %s < %t // For now, just make sure x86_64 doesn't crash. -// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t +// RUN: %clang_cc1 %s -fno-rtti -std=c++11 -Wno-inaccessible-base -triple=x86_64-pc-win32 -emit-llvm -o %t struct VBase { virtual ~VBase(); @@ -52,12 +52,14 @@ B::B() { B::~B() { // CHECK-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ" - // Adjust the this parameter: - // CHECK: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8* - // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8]], i32 -8 - // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* - // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 - // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] + // Store initial this: + // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B* + // CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4 + // Reload and adjust the this parameter: + // CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] + // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8* + // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8 + // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B* // Restore the vfptr that could have been changed by a subclass. // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* @@ -97,11 +99,11 @@ B::~B() { // CHECK2: ret // CHECK2-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_GB@@UAEPAXI@Z" - // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8* + // CHECK2: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR:.*]], align 4 + // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] + // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8 // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* - // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 - // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] // CHECK2: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[THIS]]) // ... // CHECK2: ret @@ -113,13 +115,17 @@ void B::foo() { // B::foo gets 'this' cast to VBase* in ECX (i.e. this+8) so we // need to adjust 'this' before use. // -// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*, align 4 -// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -8 -// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* -// CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR]], align 4 +// Store initial this: +// CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B* +// CHECK: store %struct.B* %{{.*}}, %struct.B** %[[THIS_ADDR]], align 4 +// +// Reload and adjust the this parameter: +// CHECK: %[[THIS_RELOAD:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] +// CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %struct.B* %[[THIS_RELOAD]] to i8* +// CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -8 +// CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %struct.B* field = 42; -// CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8* // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0 // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32** @@ -284,11 +290,16 @@ struct D : virtual Z, B, C { D::~D() { // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*{{.*}}) - // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8* - // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24 - // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"* - // CHECK: store %"struct.diamond::D"* %[[THIS]], %"struct.diamond::D"** %[[THIS_VAL:.*]], align 4 - // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_VAL]] + // Store initial this: + // CHECK: %[[THIS_ADDR:.*]] = alloca %"struct.diamond::D"* + // CHECK: store %"struct.diamond::D"* %{{.*}}, %"struct.diamond::D"** %[[THIS_ADDR]], align 4 + // + // Reload and adjust the this parameter: + // CHECK: %[[THIS_RELOAD:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_ADDR]] + // CHECK: %[[THIS_UNADJ_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS_RELOAD]] to i8* + // CHECK: %[[THIS_ADJ_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_UNADJ_i8]], i32 -24 + // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_ADJ_i8]] to %"struct.diamond::D"* + // // CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8* // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i32 4 // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"* diff --git a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp index b97c432f5e0..385e9cc17b1 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp @@ -196,7 +196,11 @@ void C::g(NonTrivial o) { } // BITCODE-LABEL: define void @"\01?g@C@pr30293@@UAAXUNonTrivial@2@@Z"(<{ i8*, %"struct.pr30293::NonTrivial" }>* inalloca) -// BITCODE: %[[this1:[^ ]*]] = load i8*, i8** %[[thisaddr:[^ ]*]], align 4 -// BITCODE-NEXT: %[[this2:[^ ]*]] = getelementptr inbounds i8, i8* %[[this1]], i32 -4 -// BITCODE-NEXT: store i8* %[[this2]], i8** %[[thisaddr]], align 4 +// BITCODE: %[[thisaddr:[^ ]*]] = getelementptr inbounds <{ i8*, %"struct.pr30293::NonTrivial" }>, <{ i8*, %"struct.pr30293::NonTrivial" }>* {{.*}}, i32 0, i32 0 +// BITCODE: %[[thisaddr1:[^ ]*]] = bitcast i8** %[[thisaddr]] to %"struct.pr30293::C"** +// BITCODE: %[[this1:[^ ]*]] = load %"struct.pr30293::C"*, %"struct.pr30293::C"** %[[thisaddr1]], align 4 +// BITCODE: %[[this2:[^ ]*]] = bitcast %"struct.pr30293::C"* %[[this1]] to i8* +// BITCODE: %[[this3:[^ ]*]] = getelementptr inbounds i8, i8* %[[this2]], i32 -4 +// BITCODE: %[[this4:[^ ]*]] = bitcast i8* %[[this3]] to %"struct.pr30293::C"* +// BITCODE: store %"struct.pr30293::C"* %[[this4]], %"struct.pr30293::C"** @"\01?whatsthis@pr30293@@3PAUC@1@A", align 4 } |