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, + const CXXMethodDecl *MD); + const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType, ArrayRef argTypes, @@ -75,6 +78,9 @@ llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM, const FunctionDecl *FD); +llvm::FunctionType *getFunctionType(CodeGenModule &CGM, + const CGFunctionInfo &FI); + llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T); /// Given a non-bitfield struct field, return its index within the elements of 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: 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/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; +}