Skip to content

Commit 98616cf

Browse files
committed
[ORC] Add an ExecutorAddr::toPtr overload for function types.
In the common case of converting an ExecutorAddr to a function pointer type, this eliminates the need for the '(*)' boilerplate to explicitly specify a function pointer. E.g.: auto *F = A.toPtr<int(*)()>(); can now be written as auto *F = A.toPtr<int()>();
1 parent c2a5a87 commit 98616cf

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

llvm/include/llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,22 @@ class ExecutorAddr {
4343

4444
/// Cast this ExecutorAddr to a pointer of the given type.
4545
/// Warning: This should only be used when JITing in-process.
46-
template <typename T> T toPtr() const {
47-
static_assert(std::is_pointer<T>::value, "T must be a pointer type");
46+
template <typename T>
47+
std::enable_if_t<std::is_pointer<T>::value, T> toPtr() const {
4848
uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
4949
assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
5050
return reinterpret_cast<T>(IntPtr);
5151
}
5252

53+
/// Cast this ExecutorAddr to a pointer of the given function type.
54+
/// Warning: This should only be used when JITing in-process.
55+
template <typename T>
56+
std::enable_if_t<std::is_function<T>::value, T *> toPtr() const {
57+
uintptr_t IntPtr = static_cast<uintptr_t>(Addr);
58+
assert(IntPtr == Addr && "ExecutorAddr value out of range for uintptr_t");
59+
return reinterpret_cast<T *>(IntPtr);
60+
}
61+
5362
uint64_t getValue() const { return Addr; }
5463
void setValue(uint64_t Addr) { this->Addr = Addr; }
5564
bool isNull() const { return Addr == 0; }

llvm/unittests/ExecutionEngine/Orc/ExecutorAddressTest.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ TEST(ExecutorAddrTest, PtrConversion) {
4747
EXPECT_EQ(XPtr, &X);
4848
}
4949

50+
static void F() {}
51+
52+
TEST(ExecutorAddrTest, PtrConversionWithFunctionType) {
53+
// Test that function types (as opposed to function pointer types) can be
54+
// used with toPtr.
55+
auto FAddr = ExecutorAddr::fromPtr(F);
56+
void (*FPtr)() = FAddr.toPtr<void()>();
57+
58+
EXPECT_EQ(FPtr, &F);
59+
}
60+
5061
TEST(ExecutorAddrTest, AddrRanges) {
5162
ExecutorAddr A0(0), A1(1), A2(2), A3(3);
5263
ExecutorAddrRange R0(A0, A1), R1(A1, A2), R2(A2, A3), R3(A0, A2), R4(A1, A3);

0 commit comments

Comments
 (0)