<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 15, 2016 at 8:36 AM, Aaron Ballman via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div>On Mon, Jan 11, 2016 at 12:44 AM, Lang Hames via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: lhames<br>
> Date: Sun Jan 10 23:44:39 2016<br>
> New Revision: 257316<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=257316&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=257316&view=rev</a><br>
> Log:<br>
> [ORC] Move ORC RPC helper classes that rely on partial specialization into a<br>
> non-template base class.<br>
><br>
> Hopefully this should fix the issues with the windows bots arrising from<br>
> r257305.<br>
><br>
> Modified:<br>
> llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h<br>
><br>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h?rev=257316&r1=257315&r2=257316&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h?rev=257316&r1=257315&r2=257316&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h (original)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h Sun Jan 10 23:44:39 2016<br>
> @@ -20,6 +20,76 @@ namespace llvm {<br>
> namespace orc {<br>
> namespace remote {<br>
><br>
> +// Base class containing utilities that require partial specialization.<br>
> +// These cannot be included in RPC, as template class members cannot be<br>
> +// partially specialized.<br>
> +class RPCBase {<br>
> +protected:<br>
> + template <typename ProcedureIdT, ProcedureIdT ProcId, typename... Ts><br>
> + class ProcedureHelper {<br>
> + public:<br>
> + static const ProcedureIdT Id = ProcId;<br>
> + };<br>
> +<br>
> + template <typename ChannelT, typename Proc> class CallHelper;<br>
> +<br>
> + template <typename ChannelT, typename ProcedureIdT, ProcedureIdT ProcId,<br>
> + typename... ArgTs><br>
> + class CallHelper<ChannelT, ProcedureHelper<ProcedureIdT, ProcId, ArgTs...>> {<br>
> + public:<br>
> + static std::error_code call(ChannelT &C, const ArgTs &... Args) {<br>
> + if (auto EC = serialize(C, ProcId))<br>
> + return EC;<br>
> + // If you see a compile-error on this line you're probably calling a<br>
> + // function with the wrong signature.<br>
> + return serialize_seq(C, Args...);<br>
> + }<br>
> + };<br>
> +<br>
> + template <typename ChannelT, typename Proc> class HandlerHelper;<br>
> +<br>
> + template <typename ChannelT, typename ProcedureIdT, ProcedureIdT ProcId,<br>
> + typename... ArgTs><br>
> + class HandlerHelper<ChannelT,<br>
> + ProcedureHelper<ProcedureIdT, ProcId, ArgTs...>> {<br>
> + public:<br>
> + template <typename HandlerT><br>
> + static std::error_code handle(ChannelT &C, HandlerT Handler) {<br>
> + return readAndHandle(C, Handler, llvm::index_sequence_for<ArgTs...>());<br>
> + }<br>
> +<br>
> + private:<br>
> + template <typename HandlerT, size_t... Is><br>
> + static std::error_code readAndHandle(ChannelT &C, HandlerT Handler,<br>
> + llvm::index_sequence<Is...> _) {<br>
> + std::tuple<ArgTs...> RPCArgs;<br>
> + if (auto EC = deserialize_seq(C, std::get<Is>(RPCArgs)...))<br>
> + return EC;<br>
> + return Handler(std::get<Is>(RPCArgs)...);<br>
<br>
</div></div>This is causing several instances of the following diagnostic:<br>
<br>
/opt/llvm/build-llvm/src/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:65:28:<br>
warning: variable ‘RPCArgs’ set but not used<br>
[-Wunused-but-set-variable]<br>
/opt/llvm/build-llvm/src/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:<br>
In instantiation of ‘static std::error_code<br>
llvm::orc::remote::RPCBase::HandlerHelper<ChannelT,<br>
llvm::orc::remote::RPCBase::ProcedureHelper<ProcedureIdT, ProcId,<br>
ArgTs ...> >::readAndHandle(ChannelT&, HandlerT,<br>
llvm::index_sequence<Is ...>) [with HandlerT =<br>
llvm::orc::remote::RPCBase::MemberFnWrapper<llvm::orc::remote::OrcRemoteTargetServer<FDRPCChannel,<br>
llvm::orc::OrcX86_64> >; long unsigned int ...Is = {}; ChannelT =<br>
llvm::orc::remote::RPCChannel; ProcedureIdT = unsigned int;<br>
ProcedureIdT ProcId = 15u; ArgTs = {}]’:<br>
/opt/llvm/build-llvm/src/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:58:76:<br>
required from ‘static std::error_code<br>
llvm::orc::remote::RPCBase::HandlerHelper<ChannelT,<br>
llvm::orc::remote::RPCBase::ProcedureHelper<ProcedureIdT, ProcId,<br>
ArgTs ...> >::handle(ChannelT&, HandlerT) [with HandlerT =<br>
llvm::orc::remote::RPCBase::MemberFnWrapper<llvm::orc::remote::OrcRemoteTargetServer<FDRPCChannel,<br>
llvm::orc::OrcX86_64> >; ChannelT = llvm::orc::remote::RPCChannel;<br>
ProcedureIdT = unsigned int; ProcedureIdT ProcId = 15u; ArgTs = {}]’<br>
/opt/llvm/build-llvm/src/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:207:60:<br>
required from ‘static std::error_code<br>
llvm::orc::remote::RPC<ChannelT, ProcedureIdT>::handle(ChannelT&,<br>
HandlerT) [with Proc =<br>
llvm::orc::remote::RPCBase::ProcedureHelper<unsigned int, 15u>;<br>
HandlerT = llvm::orc::remote::RPCBase::MemberFnWrapper<llvm::orc::remote::OrcRemoteTargetServer<FDRPCChannel,<br>
llvm::orc::OrcX86_64> >; ChannelT = llvm::orc::remote::RPCChannel;<br>
ProcedureIdT = unsigned int]’<br>
/opt/llvm/build-llvm/src/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:216:70:<br>
required from ‘static std::error_code<br>
llvm::orc::remote::RPC<ChannelT, ProcedureIdT>::handle(ChannelT&,<br>
ClassT&, std::error_code (ClassT::*)(ArgTs ...)) [with Proc =<br>
llvm::orc::remote::RPCBase::ProcedureHelper<unsigned int, 15u>; ClassT<br>
= llvm::orc::remote::OrcRemoteTargetServer<FDRPCChannel,<br>
llvm::orc::OrcX86_64>; ArgTs = {}; ChannelT =<br>
llvm::orc::remote::RPCChannel; ProcedureIdT = unsigned int]’<br>
/opt/llvm/build-llvm/src/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h:87:75:<br>
required from ‘std::error_code<br>
llvm::orc::remote::OrcRemoteTargetServer<ChannelT,<br>
TargetT>::handleKnownProcedure(llvm::orc::remote::OrcRemoteTargetRPCAPI::JITProcId)<br>
[with ChannelT = FDRPCChannel; TargetT = llvm::orc::OrcX86_64]’<br>
/opt/llvm/build-llvm/src/llvm/tools/lli/ChildTarget/ChildTarget.cpp:66:51:<br>
required from here<br>
<br>
I'm not comfortable trying to address this myself, but if you could<br>
fix it, I would appreciate it.<br></blockquote><div><br></div><div>My best guess is that this is a GCC diagnostic bug. It is warning about the local variable being unused when its use in a parameter pack expansion has no elements.<br><br>We could add a (void) cast to workaround it, but I'm not sure how high of a priority warning cleanliness with GCC 4.7 is. Actually, this reproduces in 4.8 too - not sure beyond that (don't have 4.9/5.0 on hand).<br><br>Yep, here's a reproduction of the GCC bug:<br><br><div>blaikie@blaikie-linux:/tmp/dbginfo$ g++-4.7 expand.cpp -std=c++11 -Wunused-but-set-variable </div><div>blaikie@blaikie-linux:/tmp/dbginfo$ g++-4.7 expand.cpp -std=c++11 -Wunused-but-set-variable -DFAIL</div><div><div>expand.cpp: In instantiation of ‘static void foo<Args>::func(Args ...) [with long unsigned int ...Is = {}; Args = {}]’:</div><div>expand.cpp:17:17: required from here</div><div>expand.cpp:9:23: warning: variable ‘t’ set but not used [-Wunused-but-set-variable]</div></div><div>blaikie@blaikie-linux:/tmp/dbginfo$ cat expand.cpp</div><div>#include <cstdlib></div><div>#include <tuple></div><div>void f(int) { }</div><div>void f() { }</div><div>template<typename... Args></div><div>struct foo {</div><div> template<size_t... Is></div><div> static void func(Args... a) {</div><div> std::tuple<Args...> t;</div><div> f(std::get<Is>(t)...);</div><div> }</div><div>};</div><div><br></div><div>int main() {</div><div> foo<int>::func<0>(0);</div><div>#ifdef FAIL</div><div> foo<>::func<>();</div><div>#endif</div><div>}</div><br>- Dave</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
Thanks!<br>
<br>
~Aaron<br>
<div><div><br>
> + }<br>
> + };<br>
> +<br>
> + template <typename... ArgTs> class ReadArgs {<br>
> + public:<br>
> + std::error_code operator()() { return std::error_code(); }<br>
> + };<br>
> +<br>
> + template <typename ArgT, typename... ArgTs><br>
> + class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {<br>
> + public:<br>
> + ReadArgs(ArgT &Arg, ArgTs &... Args)<br>
> + : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}<br>
> +<br>
> + std::error_code operator()(ArgT &ArgVal, ArgTs &... ArgVals) {<br>
> + this->Arg = std::move(ArgVal);<br>
> + return ReadArgs<ArgTs...>::operator()(ArgVals...);<br>
> + }<br>
> +<br>
> + private:<br>
> + ArgT &Arg;<br>
> + };<br>
> +};<br>
> +<br>
> /// Contains primitive utilities for defining, calling and handling calls to<br>
> /// remote procedures. ChannelT is a bidirectional stream conforming to the<br>
> /// RPCChannel interface (see RPCChannel.h), and ProcedureIdT is a procedure<br>
> @@ -62,7 +132,8 @@ namespace remote {<br>
> /// read yet. Expect will deserialize the id and assert that it matches Proc's<br>
> /// id. If it does not, and unexpected RPC call error is returned.<br>
><br>
> -template <typename ChannelT, typename ProcedureIdT = uint32_t> class RPC {<br>
> +template <typename ChannelT, typename ProcedureIdT = uint32_t><br>
> +class RPC : public RPCBase {<br>
> public:<br>
> /// Utility class for defining/referring to RPC procedures.<br>
> ///<br>
> @@ -89,75 +160,16 @@ public:<br>
> /// })<br>
> /// /* handle EC */;<br>
> ///<br>
> - template <ProcedureIdT ProcId, typename... Ts> class Procedure {<br>
> - public:<br>
> - static const ProcedureIdT Id = ProcId;<br>
> - };<br>
> -<br>
> -private:<br>
> - template <typename Proc> class CallHelper;<br>
> -<br>
> - template <ProcedureIdT ProcId, typename... ArgTs><br>
> - class CallHelper<Procedure<ProcId, ArgTs...>> {<br>
> - public:<br>
> - static std::error_code call(ChannelT &C, const ArgTs &... Args) {<br>
> - if (auto EC = serialize(C, ProcId))<br>
> - return EC;<br>
> - // If you see a compile-error on this line you're probably calling a<br>
> - // function with the wrong signature.<br>
> - return serialize_seq(C, Args...);<br>
> - }<br>
> - };<br>
> + template <ProcedureIdT ProcId, typename... Ts><br>
> + using Procedure = ProcedureHelper<ProcedureIdT, ProcId, Ts...>;<br>
><br>
> - template <typename Proc> class HandlerHelper;<br>
> -<br>
> - template <ProcedureIdT ProcId, typename... ArgTs><br>
> - class HandlerHelper<Procedure<ProcId, ArgTs...>> {<br>
> - public:<br>
> - template <typename HandlerT><br>
> - static std::error_code handle(ChannelT &C, HandlerT Handler) {<br>
> - return readAndHandle(C, Handler, llvm::index_sequence_for<ArgTs...>());<br>
> - }<br>
> -<br>
> - private:<br>
> - template <typename HandlerT, size_t... Is><br>
> - static std::error_code readAndHandle(ChannelT &C, HandlerT Handler,<br>
> - llvm::index_sequence<Is...> _) {<br>
> - std::tuple<ArgTs...> RPCArgs;<br>
> - if (auto EC = deserialize_seq(C, std::get<Is>(RPCArgs)...))<br>
> - return EC;<br>
> - return Handler(std::get<Is>(RPCArgs)...);<br>
> - }<br>
> - };<br>
> -<br>
> - template <typename... ArgTs> class ReadArgs {<br>
> - public:<br>
> - std::error_code operator()() { return std::error_code(); }<br>
> - };<br>
> -<br>
> - template <typename ArgT, typename... ArgTs><br>
> - class ReadArgs<ArgT, ArgTs...> : public ReadArgs<ArgTs...> {<br>
> - public:<br>
> - ReadArgs(ArgT &Arg, ArgTs &... Args)<br>
> - : ReadArgs<ArgTs...>(Args...), Arg(Arg) {}<br>
> -<br>
> - std::error_code operator()(ArgT &ArgVal, ArgTs &... ArgVals) {<br>
> - this->Arg = std::move(ArgVal);<br>
> - return ReadArgs<ArgTs...>::operator()(ArgVals...);<br>
> - }<br>
> -<br>
> - private:<br>
> - ArgT &Arg;<br>
> - };<br>
> -<br>
> -public:<br>
> /// Serialize Args... to channel C, but do not call C.send().<br>
> ///<br>
> /// For buffered channels, this can be used to queue up several calls before<br>
> /// flushing the channel.<br>
> template <typename Proc, typename... ArgTs><br>
> static std::error_code appendCall(ChannelT &C, const ArgTs &... Args) {<br>
> - return CallHelper<Proc>::call(C, Args...);<br>
> + return CallHelper<ChannelT, Proc>::call(C, Args...);<br>
> }<br>
><br>
> /// Serialize Args... to channel C and call C.send().<br>
> @@ -178,7 +190,7 @@ public:<br>
> /// the arguments used in the Proc typedef.<br>
> template <typename Proc, typename HandlerT><br>
> static std::error_code handle(ChannelT &C, HandlerT Handler) {<br>
> - return HandlerHelper<Proc>::handle(C, Handler);<br>
> + return HandlerHelper<ChannelT, Proc>::handle(C, Handler);<br>
> }<br>
><br>
> /// Deserialize a ProcedureIdT from C and verify it matches the id for Proc.<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div></div>