[ORC] Add a WrappedHandlerReturn type to map handler return types onto error

return types.

This class allows user provided handlers to return either error-wrapped types
or plain types. In the latter case, the plain type is wrapped with a success
value of Error or Expected<T> type to fit it into the rest of the serialization
machinery.

This patch allows us to remove the RPC unit-test workaround added in r286646.

llvm-svn: 286701
This commit is contained in:
Lang Hames 2016-11-12 02:19:31 +00:00
parent 8fa568d761
commit 03418af046
2 changed files with 36 additions and 9 deletions

View File

@ -314,6 +314,37 @@ static Error respond(ChannelT &C, const FunctionIdT &ResponseId,
return C.endSendMessage();
}
// Converts a given type to the equivalent error return type.
template <typename T>
class WrappedHandlerReturn {
public:
using Type = Expected<T>;
};
template <typename T>
class WrappedHandlerReturn<Expected<T>> {
public:
using Type = Expected<T>;
};
template <>
class WrappedHandlerReturn<void> {
public:
using Type = Error;
};
template <>
class WrappedHandlerReturn<Error> {
public:
using Type = Error;
};
template <>
class WrappedHandlerReturn<ErrorSuccess> {
public:
using Type = Error;
};
// This template class provides utilities related to RPC function handlers.
// The base case applies to non-function types (the template class is
// specialized for function types) and inherits from the appropriate
@ -342,7 +373,7 @@ public:
// Call the given handler with the given arguments.
template <typename HandlerT>
static typename ResultTraits<RetT>::ErrorReturnType
static typename WrappedHandlerReturn<RetT>::Type
runHandler(HandlerT &Handler, ArgStorage &Args) {
return runHandlerHelper<RetT>(Handler, Args,
llvm::index_sequence_for<ArgTs...>());
@ -366,9 +397,7 @@ private:
// For non-void user handlers: unwrap the args tuple and call the handler,
// returning the result.
template <typename RetTAlt, typename HandlerT, size_t... Indexes>
static typename std::enable_if<
!std::is_void<RetTAlt>::value,
typename ResultTraits<RetT>::ErrorReturnType>::type
static typename std::enable_if<!std::is_void<RetTAlt>::value, RetT>::type
runHandlerHelper(HandlerT &Handler, ArgStorage &Args,
llvm::index_sequence<Indexes...>) {
return Handler(std::move(std::get<Indexes>(Args))...);
@ -377,13 +406,11 @@ private:
// For void user handlers: unwrap the args tuple and call the handler, then
// return Error::success().
template <typename RetTAlt, typename HandlerT, size_t... Indexes>
static typename std::enable_if<
std::is_void<RetTAlt>::value,
typename ResultTraits<RetT>::ErrorReturnType>::type
static typename std::enable_if<std::is_void<RetTAlt>::value, Error>::type
runHandlerHelper(HandlerT &Handler, ArgStorage &Args,
llvm::index_sequence<Indexes...>) {
Handler(std::move(std::get<Indexes>(Args))...);
return ResultTraits<RetT>::ErrorReturnType::success();
return Error::success();
}
template <typename ChannelT, typename... CArgTs, size_t... Indexes>

View File

@ -191,7 +191,7 @@ TEST(DummyRPC, TestSerialization) {
Server.addHandler<DummyRPCAPI::AllTheTypes>(
[&](int8_t S8, uint8_t U8, int16_t S16, uint16_t U16,
int32_t S32, uint32_t U32, int64_t S64, uint64_t U64,
bool B, std::string S, std::vector<int> V) -> Error {
bool B, std::string S, std::vector<int> V) {
EXPECT_EQ(S8, -101) << "int8_t serialization broken";
EXPECT_EQ(U8, 250) << "uint8_t serialization broken";