[PATCH] D66360: Expose constructing a virtual method dispatch through the include/clang/CodeGen APIs.
pschuh created this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits. In swift, we want to be able to call c++ virtual methods by looking up in the virtual table. There appears to exist no way currently, via the standard APIs, to take a CXXMethodDecl and a llvm::Value representing a this-ptr and construct the llvm instructions necessary to extract the method from the virtual table as well as adjust the this-ptr. For reference, this is used in https://github.com/apple/swift/pull/26658. Repository: rC Clang https://reviews.llvm.org/D66360 Files: include/clang/CodeGen/CodeGenABITypes.h include/clang/CodeGen/SwiftCallingConv.h lib/CodeGen/CodeGenABITypes.cpp lib/CodeGen/SwiftCallingConv.cpp Index: lib/CodeGen/SwiftCallingConv.cpp === --- lib/CodeGen/SwiftCallingConv.cpp +++ lib/CodeGen/SwiftCallingConv.cpp @@ -11,9 +11,11 @@ //===--===// #include "clang/CodeGen/SwiftCallingConv.h" -#include "clang/Basic/TargetInfo.h" +#include "CGCXXABI.h" +#include "CodeGenFunction.h" #include "CodeGenModule.h" #include "TargetInfo.h" +#include "clang/Basic/TargetInfo.h" using namespace clang; using namespace CodeGen; @@ -862,3 +864,25 @@ bool swiftcall::isSwiftErrorLoweredInRegister(CodeGenModule &CGM) { return getSwiftABIInfo(CGM).isSwiftErrorInRegister(); } + +llvm::Value *swiftcall::lowerCXXVirtualMethodDeclReference( +CodeGenModule &CGM, const CXXMethodDecl *MD, llvm::Value *&thisPtr, +CharUnits alignment, llvm::FunctionType *type, +llvm::IRBuilderBase *builder) { + assert(MD->isVirtual()); + + CodeGenFunction CGF(CGM, true); + CGF.Builder.SetInsertPoint(builder->GetInsertBlock(), + builder->GetInsertPoint()); + Address thisAddr(thisPtr, alignment); + auto callee = CGCallee::forVirtual(nullptr, MD, thisAddr, type); + const CGCallee &concreteCallee = callee.prepareConcreteCallee(CGF); + Address newThisAddr = + CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(CGF, MD, + thisAddr, true); + thisPtr = newThisAddr.getPointer(); + auto *result = concreteCallee.getFunctionPointer(); + builder->SetInsertPoint(CGF.Builder.GetInsertBlock(), + CGF.Builder.GetInsertPoint()); + return result; +} Index: lib/CodeGen/CodeGenABITypes.cpp === --- lib/CodeGen/CodeGenABITypes.cpp +++ lib/CodeGen/CodeGenABITypes.cpp @@ -52,6 +52,17 @@ return CGM.getTypes().arrangeCXXMethodType(RD, FTP, MD); } +const CGFunctionInfo & +CodeGen::arrangeCXXMethodDeclaration(CodeGenModule &CGM, + const CXXMethodDecl *MD) { + return CGM.getTypes().arrangeCXXMethodDeclaration(MD); +} + +llvm::FunctionType *CodeGen::getFunctionType(CodeGenModule &CGM, + const CGFunctionInfo &FI) { + return CGM.getTypes().GetFunctionType(FI); +} + const CGFunctionInfo & CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType, Index: include/clang/CodeGen/SwiftCallingConv.h === --- include/clang/CodeGen/SwiftCallingConv.h +++ include/clang/CodeGen/SwiftCallingConv.h @@ -22,14 +22,18 @@ namespace llvm { class IntegerType; class Type; + class Value; class StructType; class VectorType; + class FunctionType; + class IRBuilderBase; } namespace clang { class Decl; class FieldDecl; class ASTRecordLayout; +class CXXMethodDecl; namespace CodeGen { class ABIArgInfo; @@ -177,6 +181,14 @@ /// Is swifterror lowered to a register by the target ABI? bool isSwiftErrorLoweredInRegister(CodeGenModule &CGM); +/// Lookup a virtual method `MD` from the vtable and adjusts the this ptr. +llvm::Value *lowerCXXVirtualMethodDeclReference(CodeGenModule &CGM, +const CXXMethodDecl *MD, +llvm::Value *&thisPtr, +CharUnits alignment, +llvm::FunctionType *type, +llvm::IRBuilderBase *builder); + } // end namespace swiftcall } // end namespace CodeGen } // end namespace clang Index: include/clang/CodeGen/CodeGenABITypes.h === --- include/clang/CodeGen/CodeGenABITypes.h +++ include/clang/CodeGen/CodeGenABITypes.h @@ -65,6 +65,9 @@ const FunctionProtoType *FTP, const CXXMethodDecl *MD); +const CGFunctionInfo &arrangeCXXMethodDeclaration(CodeGenModule &CGM, +
[PATCH] D66360: Expose constructing a virtual method dispatch through the include/clang/CodeGen APIs.
pschuh updated this revision to Diff 217566. pschuh added a comment. Herald added a subscriber: mgorny. Your suggestions of pulling the builder out as an API and exposing CGCallee made everything a lot simpler. Unfortunately, I had to split the CGCallee header because it threatened to pull EHScopeStack.h and CGValue.h to be public (and transitively CodeGenTBAA.h). The old CGCall.h header now just contains the Args and ReturnValueSlot. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66360/new/ https://reviews.llvm.org/D66360 Files: include/clang/CodeGen/Address.h include/clang/CodeGen/CGCallee.h include/clang/CodeGen/CodeGenABITypes.h include/clang/CodeGen/FunctionBuilder.h lib/CodeGen/Address.h lib/CodeGen/CGBuilder.h lib/CodeGen/CGCall.h lib/CodeGen/CGCleanup.h lib/CodeGen/CGObjCRuntime.h lib/CodeGen/CGValue.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodeGenABITypes.cpp lib/CodeGen/FunctionBuilder.cpp Index: lib/CodeGen/FunctionBuilder.cpp === --- /dev/null +++ lib/CodeGen/FunctionBuilder.cpp @@ -0,0 +1,48 @@ +//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// +// +// This exposes a subset of the CodeGenFunction API. +// +//===--===// + +#include "clang/CodeGen/FunctionBuilder.h" +#include "CGCXXABI.h" +#include "CodeGenFunction.h" +#include "clang/Basic/TargetInfo.h" + +using namespace clang; +using namespace CodeGen; + +namespace { +class FunctionBuilderImpl : public FunctionBuilder { + public: + CodeGenFunction CGF; + + FunctionBuilderImpl(CodeGenModule &CGM) + : CGF(CGM, /*suppressNewContext=*/true) {} +}; +} // namespace + +FunctionBuilder::~FunctionBuilder() {} + +std::unique_ptr FunctionBuilder::Create(CodeGenModule &CGM) { + return std::unique_ptr(new FunctionBuilderImpl(CGM)); +} + +CodeGenFunction &FunctionBuilder::CGF() { + return static_cast(this)->CGF; +} + +llvm::IRBuilderBase &FunctionBuilder::getBuilder() { return CGF().Builder; } + +Address FunctionBuilder::emitAdjustThisArgumentForVirtualFunctionCall( +Address thisAddr, GlobalDecl GD, bool VirtualCall) { + return CGF().CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall( + CGF(), GD, thisAddr, VirtualCall); +} Index: lib/CodeGen/CodeGenABITypes.cpp === --- lib/CodeGen/CodeGenABITypes.cpp +++ lib/CodeGen/CodeGenABITypes.cpp @@ -52,6 +52,17 @@ return CGM.getTypes().arrangeCXXMethodType(RD, FTP, MD); } +const CGFunctionInfo & +CodeGen::arrangeCXXMethodDeclaration(CodeGenModule &CGM, + const CXXMethodDecl *MD) { + return CGM.getTypes().arrangeCXXMethodDeclaration(MD); +} + +llvm::FunctionType *CodeGen::getFunctionType(CodeGenModule &CGM, + const CGFunctionInfo &FI) { + return CGM.getTypes().GetFunctionType(FI); +} + const CGFunctionInfo & CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType, Index: lib/CodeGen/CMakeLists.txt === --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -84,6 +84,7 @@ CodeGenTypes.cpp ConstantInitBuilder.cpp CoverageMappingGen.cpp + FunctionBuilder.cpp ItaniumCXXABI.cpp MacroPPCallbacks.cpp MicrosoftCXXABI.cpp Index: lib/CodeGen/CGValue.h === --- lib/CodeGen/CGValue.h +++ lib/CodeGen/CGValue.h @@ -18,7 +18,7 @@ #include "clang/AST/Type.h" #include "llvm/IR/Value.h" #include "llvm/IR/Type.h" -#include "Address.h" +#include "clang/CodeGen/Address.h" #include "CodeGenTBAA.h" namespace llvm { Index: lib/CodeGen/CGObjCRuntime.h === --- lib/CodeGen/CGObjCRuntime.h +++ lib/CodeGen/CGObjCRuntime.h @@ -18,6 +18,7 @@ #include "CGCall.h" #include "CGCleanup.h" #include "CGValue.h" +#include "ABIInfo.h" #include "clang/AST/DeclObjC.h" #include "clang/Basic/IdentifierTable.h" // Selector Index: lib/CodeGen/CGCleanup.h === --- lib/CodeGen/CGCleanup.h +++ lib/CodeGen/CGCleanup.h @@ -15,7 +15,7 @@ #include "EHScopeStack.h" -#include "Address.h" +#include "clang/CodeGen/Address.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" Index: lib/CodeGen/CGCall.h === --- lib/CodeGen/CGCall.h +++ lib/CodeGen/CGCall.h @@ -19,11 +19,9 @@ #i
[PATCH] D66360: Expose constructing a virtual method dispatch through the include/clang/CodeGen APIs.
pschuh added a comment. Hi John, maybe take a look? Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D66360/new/ https://reviews.llvm.org/D66360 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits