forked from OSchip/llvm-project
[MS ABI] Allow fastcall member function pointers to get CodeGen'd
This restriction appears unnecessary and most likely came about during early work for musttail. llvm-svn: 239500
This commit is contained in:
parent
01b9bb42d4
commit
ac936ff5ab
|
@ -2423,20 +2423,15 @@ MicrosoftCXXABI::BuildMemberPointer(const CXXRecordDecl *RD,
|
|||
FirstField = CGM.GetAddrOfFunction(MD, Ty);
|
||||
FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy);
|
||||
} else {
|
||||
if (FPT->getCallConv() == CC_X86FastCall) {
|
||||
CGM.ErrorUnsupported(MD, "pointer to fastcall virtual member function");
|
||||
FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
|
||||
} 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;
|
||||
}
|
||||
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.
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
// 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.
|
||||
// RUN: %clang_cc1 -fms-extensions -triple i686-pc-windows-msvc %s -emit-llvm -o - | FileCheck %s
|
||||
|
||||
struct A {
|
||||
virtual void __fastcall f(int a, int b); // expected-error {{cannot compile this pointer to fastcall virtual member function yet}}
|
||||
virtual void __fastcall f(int a, int b);
|
||||
};
|
||||
void (__fastcall A::*doit())(int, int) {
|
||||
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