From cdd3d384cda3210d6ba254c4bfd01d8314311295 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 11 Jan 2016 05:44:39 +0000 Subject: [PATCH] [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257316 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ExecutionEngine/Orc/RPCUtils.h | 140 +++++++++++--------- 1 file changed, 76 insertions(+), 64 deletions(-) diff --git a/include/llvm/ExecutionEngine/Orc/RPCUtils.h b/include/llvm/ExecutionEngine/Orc/RPCUtils.h index 465a464193e..a2f0edb7334 100644 --- a/include/llvm/ExecutionEngine/Orc/RPCUtils.h +++ b/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 + class ProcedureHelper { + public: + static const ProcedureIdT Id = ProcId; + }; + + template class CallHelper; + + template + class CallHelper> { + 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 class HandlerHelper; + + template + class HandlerHelper> { + public: + template + static std::error_code handle(ChannelT &C, HandlerT Handler) { + return readAndHandle(C, Handler, llvm::index_sequence_for()); + } + + private: + template + static std::error_code readAndHandle(ChannelT &C, HandlerT Handler, + llvm::index_sequence _) { + std::tuple RPCArgs; + if (auto EC = deserialize_seq(C, std::get(RPCArgs)...)) + return EC; + return Handler(std::get(RPCArgs)...); + } + }; + + template class ReadArgs { + public: + std::error_code operator()() { return std::error_code(); } + }; + + template + class ReadArgs : public ReadArgs { + public: + ReadArgs(ArgT &Arg, ArgTs &... Args) + : ReadArgs(Args...), Arg(Arg) {} + + std::error_code operator()(ArgT &ArgVal, ArgTs &... ArgVals) { + this->Arg = std::move(ArgVal); + return ReadArgs::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 class RPC { +template +class RPC : public RPCBase { public: /// Utility class for defining/referring to RPC procedures. /// @@ -89,75 +160,16 @@ public: /// }) /// /* handle EC */; /// - template class Procedure { - public: - static const ProcedureIdT Id = ProcId; - }; - -private: - template class CallHelper; - - template - class CallHelper> { - 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 + using Procedure = ProcedureHelper; - template class HandlerHelper; - - template - class HandlerHelper> { - public: - template - static std::error_code handle(ChannelT &C, HandlerT Handler) { - return readAndHandle(C, Handler, llvm::index_sequence_for()); - } - - private: - template - static std::error_code readAndHandle(ChannelT &C, HandlerT Handler, - llvm::index_sequence _) { - std::tuple RPCArgs; - if (auto EC = deserialize_seq(C, std::get(RPCArgs)...)) - return EC; - return Handler(std::get(RPCArgs)...); - } - }; - - template class ReadArgs { - public: - std::error_code operator()() { return std::error_code(); } - }; - - template - class ReadArgs : public ReadArgs { - public: - ReadArgs(ArgT &Arg, ArgTs &... Args) - : ReadArgs(Args...), Arg(Arg) {} - - std::error_code operator()(ArgT &ArgVal, ArgTs &... ArgVals) { - this->Arg = std::move(ArgVal); - return ReadArgs::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 static std::error_code appendCall(ChannelT &C, const ArgTs &... Args) { - return CallHelper::call(C, Args...); + return CallHelper::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 static std::error_code handle(ChannelT &C, HandlerT Handler) { - return HandlerHelper::handle(C, Handler); + return HandlerHelper::handle(C, Handler); } /// Deserialize a ProcedureIdT from C and verify it matches the id for Proc. -- 2.34.1