forked from OSchip/llvm-project
Revert "[MS ABI] Allow fastcall member function pointers to get CodeGen'd"
Revert "[MS ABI] Allow memfn pointers with unconvertible types to be formed" This reverts r239499 and r239503; the former breaks tests [1] and the latter is based on the former. [1] http://lab.llvm.org:8080/green/job/clang-stage2-configure-Rlto_check/4473/testReport/Clang/CodeGenCXX/microsoft_abi_virtual_member_pointers_cpp/ llvm-svn: 239511
This commit is contained in:
parent
af37ad19a9
commit
aad3b8486d
|
@ -2423,15 +2423,25 @@ MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD,
|
||||||
FirstField = CGM.GetAddrOfFunction(MD, Ty);
|
FirstField = CGM.GetAddrOfFunction(MD, Ty);
|
||||||
FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy);
|
FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy);
|
||||||
} else {
|
} else {
|
||||||
auto &VTableContext = CGM.getMicrosoftVTableContext();
|
if (!CGM.getTypes().isFuncTypeConvertible(
|
||||||
MicrosoftVTableContext::MethodVFTableLocation ML =
|
MD->getType()->castAs<FunctionType>())) {
|
||||||
VTableContext.getMethodVFTableLocation(MD);
|
CGM.ErrorUnsupported(MD, "pointer to virtual member function with "
|
||||||
llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML);
|
"incomplete return or parameter type");
|
||||||
FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy);
|
FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
|
||||||
// Include the vfptr adjustment if the method is in a non-primary vftable.
|
} else if (FPT->getCallConv() == CC_X86FastCall) {
|
||||||
NonVirtualBaseAdjustment += ML.VFPtrOffset;
|
CGM.ErrorUnsupported(MD, "pointer to fastcall virtual member function");
|
||||||
if (ML.VBase)
|
FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
|
||||||
VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4;
|
} else {
|
||||||
|
auto &VTableContext = CGM.getMicrosoftVTableContext();
|
||||||
|
MicrosoftVTableContext::MethodVFTableLocation ML =
|
||||||
|
VTableContext.getMethodVFTableLocation(MD);
|
||||||
|
llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML);
|
||||||
|
FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy);
|
||||||
|
// Include the vfptr adjustment if the method is in a non-primary vftable.
|
||||||
|
NonVirtualBaseAdjustment += ML.VFPtrOffset;
|
||||||
|
if (ML.VBase)
|
||||||
|
VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rest of the fields are common with data member pointers.
|
// The rest of the fields are common with data member pointers.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
|
// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
|
||||||
// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
|
// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
|
@ -13,15 +13,12 @@ struct U {
|
||||||
U(const U &);
|
U(const U &);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct B;
|
|
||||||
|
|
||||||
struct C {
|
struct C {
|
||||||
virtual void foo();
|
virtual void foo();
|
||||||
virtual int bar(int, double);
|
virtual int bar(int, double);
|
||||||
virtual S baz(int);
|
virtual S baz(int);
|
||||||
virtual S qux(U);
|
virtual S qux(U);
|
||||||
virtual void thud(...);
|
virtual void thud(...);
|
||||||
virtual void (B::*plugh())();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -50,8 +47,6 @@ void f() {
|
||||||
void (C::*ptr6)(...);
|
void (C::*ptr6)(...);
|
||||||
ptr6 = &C::thud;
|
ptr6 = &C::thud;
|
||||||
|
|
||||||
auto ptr7 = &C::plugh;
|
|
||||||
|
|
||||||
|
|
||||||
// CHECK32-LABEL: define void @"\01?f@@YAXXZ"()
|
// CHECK32-LABEL: define void @"\01?f@@YAXXZ"()
|
||||||
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr
|
// CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr
|
||||||
|
@ -172,18 +167,4 @@ void f() {
|
||||||
// CHECK64: ret void
|
// CHECK64: ret void
|
||||||
// CHECK64: }
|
// CHECK64: }
|
||||||
|
|
||||||
// CHECK32: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BBE@AE"(%struct.C* %this, ...) {{.*}} comdat align 2 {
|
|
||||||
// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %vtable, i64 5
|
|
||||||
// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
|
||||||
// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
|
||||||
// CHECK32: ret void
|
|
||||||
// CHECK32: }
|
|
||||||
|
|
||||||
// CHECK64: define linkonce_odr void @"\01??_9C@@$BCI@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 {
|
|
||||||
// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %vtable, i64 5
|
|
||||||
// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]]
|
|
||||||
// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...)
|
|
||||||
// CHECK64: ret void
|
|
||||||
// CHECK64: }
|
|
||||||
|
|
||||||
// CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}
|
// CHECK32: #[[ATTR]] = {{{.*}}"thunk"{{.*}}}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s
|
// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm-only -verify
|
||||||
|
|
||||||
|
// We reject this because LLVM doesn't forward the second regparm through the
|
||||||
|
// thunk.
|
||||||
|
|
||||||
struct A {
|
struct A {
|
||||||
virtual void __fastcall f(int a, int b);
|
virtual void __fastcall f(int a, int b); // expected-error {{cannot compile this pointer to fastcall virtual member function yet}}
|
||||||
};
|
};
|
||||||
void (__fastcall A::*doit())(int, int) {
|
void (__fastcall A::*doit())(int, int) {
|
||||||
return &A::f;
|
return &A::f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: define linkonce_odr x86_fastcallcc void @"\01??_9A@@$BA@AI"(%struct.A* inreg %this, ...) {{.*}} comdat align 2 {
|
|
||||||
// CHECK: [[VPTR:%.*]] = getelementptr inbounds void (%struct.A*, ...)*, void (%struct.A*, ...)** %vtable, i64 0
|
|
||||||
// CHECK: [[CALLEE:%.*]] = load void (%struct.A*, ...)*, void (%struct.A*, ...)** [[VPTR]]
|
|
||||||
// CHECK: musttail call x86_fastcallcc void (%struct.A*, ...) [[CALLEE]](%struct.A* inreg %{{.*}}, ...)
|
|
||||||
// CHECK: ret void
|
|
||||||
// CHECK: }
|
|
||||||
|
|
Loading…
Reference in New Issue