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,
+ const CXXMethodDecl *MD);
+
const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
CanQualType returnType,
ArrayRef<CanQualType> 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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits