diff options
| author | Lang Hames <lhames@gmail.com> | 2016-01-11 05:44:39 +0000 |
|---|---|---|
| committer | Lang Hames <lhames@gmail.com> | 2016-01-11 05:44:39 +0000 |
| commit | 4439631009e8e9b1dedd578a8d51cdc04efde21d (patch) | |
| tree | 6d69eb57ddbff0f9af8dc4e4671efc129a9a04e2 | |
| parent | 14d917302f46fe017b081c726e22b6e24115dee1 (diff) | |
| download | bcm5719-llvm-4439631009e8e9b1dedd578a8d51cdc04efde21d.tar.gz bcm5719-llvm-4439631009e8e9b1dedd578a8d51cdc04efde21d.zip | |
[ORC] Move ORC RPC helper classes that rely on partial specialization into a
non-template base class.
Hopefully this should fix the issues with the windows bots arrising from
r257305.
llvm-svn: 257316
| -rw-r--r-- | llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h | 140 |
1 files changed, 76 insertions, 64 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h index 465a464193e..a2f0edb7334 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h @@ -20,6 +20,76 @@ namespace llvm { namespace orc { namespace remote { +// Base class containing utilities that require partial specialization. +// These cannot be included in RPC, as template class members cannot be +// partially specialized. +class RPCBase { +protected: + template <typename ProcedureIdT, ProcedureIdT ProcId, typename... Ts> + class ProcedureHelper { + public: + static const ProcedureIdT Id = ProcId; + }; + + template <typename ChannelT, typename Proc> class CallHelper; + + template <typename ChannelT, typename ProcedureIdT, ProcedureIdT ProcId, + typename... ArgTs> + class CallHelper<ChannelT, ProcedureHelper<ProcedureIdT, ProcId, ArgTs...>> { + public: + static std::error_code call(ChannelT &C, const ArgTs &... Args) { + if (auto EC = serialize(C, ProcId)) + return EC; + // If you see a compile-error on this line you're probably calling a + // function with the wrong signature. + return serialize_seq(C, Args...); + } + }; + + template <typename ChannelT, typename Proc> class HandlerHelper; + + template <typename ChannelT, typename ProcedureIdT, ProcedureIdT ProcId, + typename... ArgTs> + class HandlerHelper<ChannelT, + ProcedureHelper<ProcedureIdT, ProcId, ArgTs...>> { + public: + template <typename HandlerT> + static std::error_code handle(ChannelT &C, HandlerT Handler) { + return readAndHandle(C, Handler, llvm::index_sequence_for<ArgTs...>()); + } + + private: + template <typename HandlerT, size_t... Is> + static std::error_code readAndHandle(ChannelT &C, HandlerT Handler, + llvm::index_sequence<Is...> _) { + std::tuple<ArgTs...> RPCArgs; + if (auto EC = deserialize_seq(C, std::get<Is>(RPCArgs)...)) + return EC; + return Handler(std::get<Is>(RPCArgs)...); + } + }; + + template <typename... ArgTs> class ReadArgs { + public: + std::error_code operator()() { return std::error_code(); } + }; + + template <typename ArgT, typename... ArgTs> + class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> { + public: + ReadArgs(ArgT &Arg, ArgTs &... Args) + : ReadArgs<ArgTs...>(Args...), Arg(Arg) {} + + std::error_code operator()(ArgT &ArgVal, ArgTs &... ArgVals) { + this->Arg = std::move(ArgVal); + return ReadArgs<ArgTs...>::operator()(ArgVals...); + } + + private: + ArgT &Arg; + }; +}; + /// Contains primitive utilities for defining, calling and handling calls to /// remote procedures. ChannelT is a bidirectional stream conforming to the /// RPCChannel interface (see RPCChannel.h), and ProcedureIdT is a procedure @@ -62,7 +132,8 @@ namespace remote { /// read yet. Expect will deserialize the id and assert that it matches Proc's /// id. If it does not, and unexpected RPC call error is returned. -template <typename ChannelT, typename ProcedureIdT = uint32_t> class RPC { +template <typename ChannelT, typename ProcedureIdT = uint32_t> +class RPC : public RPCBase { public: /// Utility class for defining/referring to RPC procedures. /// @@ -89,75 +160,16 @@ public: /// }) /// /* handle EC */; /// - template <ProcedureIdT ProcId, typename... Ts> class Procedure { - public: - static const ProcedureIdT Id = ProcId; - }; - -private: - template <typename Proc> class CallHelper; - - template <ProcedureIdT ProcId, typename... ArgTs> - class CallHelper<Procedure<ProcId, ArgTs...>> { - public: - static std::error_code call(ChannelT &C, const ArgTs &... Args) { - if (auto EC = serialize(C, ProcId)) - return EC; - // If you see a compile-error on this line you're probably calling a - // function with the wrong signature. - return serialize_seq(C, Args...); - } - }; + template <ProcedureIdT ProcId, typename... Ts> + using Procedure = ProcedureHelper<ProcedureIdT, ProcId, Ts...>; - template <typename Proc> class HandlerHelper; - - template <ProcedureIdT ProcId, typename... ArgTs> - class HandlerHelper<Procedure<ProcId, ArgTs...>> { - public: - template <typename HandlerT> - static std::error_code handle(ChannelT &C, HandlerT Handler) { - return readAndHandle(C, Handler, llvm::index_sequence_for<ArgTs...>()); - } - - private: - template <typename HandlerT, size_t... Is> - static std::error_code readAndHandle(ChannelT &C, HandlerT Handler, - llvm::index_sequence<Is...> _) { - std::tuple<ArgTs...> RPCArgs; - if (auto EC = deserialize_seq(C, std::get<Is>(RPCArgs)...)) - return EC; - return Handler(std::get<Is>(RPCArgs)...); - } - }; - - template <typename... ArgTs> class ReadArgs { - public: - std::error_code operator()() { return std::error_code(); } - }; - - template <typename ArgT, typename... ArgTs> - class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> { - public: - ReadArgs(ArgT &Arg, ArgTs &... Args) - : ReadArgs<ArgTs...>(Args...), Arg(Arg) {} - - std::error_code operator()(ArgT &ArgVal, ArgTs &... ArgVals) { - this->Arg = std::move(ArgVal); - return ReadArgs<ArgTs...>::operator()(ArgVals...); - } - - private: - ArgT &Arg; - }; - -public: /// Serialize Args... to channel C, but do not call C.send(). /// /// For buffered channels, this can be used to queue up several calls before /// flushing the channel. template <typename Proc, typename... ArgTs> static std::error_code appendCall(ChannelT &C, const ArgTs &... Args) { - return CallHelper<Proc>::call(C, Args...); + return CallHelper<ChannelT, Proc>::call(C, Args...); } /// Serialize Args... to channel C and call C.send(). @@ -178,7 +190,7 @@ public: /// the arguments used in the Proc typedef. template <typename Proc, typename HandlerT> static std::error_code handle(ChannelT &C, HandlerT Handler) { - return HandlerHelper<Proc>::handle(C, Handler); + return HandlerHelper<ChannelT, Proc>::handle(C, Handler); } /// Deserialize a ProcedureIdT from C and verify it matches the id for Proc. |

