diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h index 53619fa8ef6..0745099a37b 100644 --- a/include/clang/CodeGen/CodeGenABITypes.h +++ b/include/clang/CodeGen/CodeGenABITypes.h @@ -66,6 +66,9 @@ const CGFunctionInfo &arrangeCXXMethodType(CodeGenModule &CGM, const FunctionProtoType *FTP, const CXXMethodDecl *MD); +const CGFunctionInfo &arrangeCXXMethodDeclaration(CodeGenModule &CGM, + const CXXMethodDecl *MD); + const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, CanQualType returnType, ArrayRef argTypes, @@ -76,6 +79,9 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, 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 diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h index 5aa9be2d67c..586235c74d8 100644 --- a/include/clang/CodeGen/SwiftCallingConv.h +++ b/include/clang/CodeGen/SwiftCallingConv.h @@ -23,14 +23,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; @@ -178,6 +182,14 @@ void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI); /// 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 diff --git a/lib/CodeGen/CodeGenABITypes.cpp b/lib/CodeGen/CodeGenABITypes.cpp index 27f5d53ffe1..99fb82541a6 100644 --- a/lib/CodeGen/CodeGenABITypes.cpp +++ b/lib/CodeGen/CodeGenABITypes.cpp @@ -54,6 +54,17 @@ CodeGen::arrangeCXXMethodType(CodeGenModule &CGM, 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, diff --git a/lib/CodeGen/SwiftCallingConv.cpp b/lib/CodeGen/SwiftCallingConv.cpp index 75a0fa5ce18..53e74c33057 100644 --- a/lib/CodeGen/SwiftCallingConv.cpp +++ b/lib/CodeGen/SwiftCallingConv.cpp @@ -12,9 +12,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; @@ -863,3 +865,25 @@ void swiftcall::computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI) { 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; +}