<div dir="ltr">Hi Yung,<div><br></div><div>Bummer.</div><div><br></div><div>At first glance this looks like a failure to construct a future for a type with no default constructor - is that your read? Do you know if MSVC 2013's futures library supports that?</div><div><br></div><div>I'm on the road, but will be back in ~3 hours - when I get back I can try some workarounds for this. If that's too long for the builders, feel free to revert for now. </div><div><br></div><div>- Lang.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 29, 2016 at 5:44 PM, Yung, Douglas <span dir="ltr"><<a href="mailto:douglas.yung@sony.com" target="_blank">douglas.yung@sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Lang,<br>
<br>
I believe your checkin caused the Windows build to break when compiling with Visual Studio 2013. When building your change, I am seeing the following errors:<br>
<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(294): error C2512: 'llvm::Expected<int>' : no appropriate default constructor available [C:\src\build\tools\lli\lli.<wbr>vcxproj]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(286) : while compiling class template member function 'std::_Associated_state<_Ty>::<wbr>_Associated_state(std::_<wbr>Deleter_base<_Ty> *)'<br>
with<br>
[<br>
_Ty=llvm::Expected<int><br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(1481) : see reference to function template instantiation 'std::_Associated_state<_Ty>::<wbr>_Associated_state(std::_<wbr>Deleter_base<_Ty> *)' being compiled<br>
with<br>
[<br>
_Ty=llvm::Expected<int><br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(1018) : see reference to class template instantiation 'std::_Associated_state<_Ty>' being compiled<br>
with<br>
[<br>
_Ty=llvm::Expected<int><br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(1014) : while compiling class template member function 'llvm::Expected<int> &std::_State_manager<_Ty>::_<wbr>Get_value(void) const'<br>
with<br>
[<br>
_Ty=llvm::Expected<int><br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(1132) : see reference to function template instantiation 'llvm::Expected<int> &std::_State_manager<_Ty>::_<wbr>Get_value(void) const' being compiled<br>
with<br>
[<br>
_Ty=llvm::Expected<int><br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\future(1101) : see reference to class template instantiation 'std::_State_manager<_Ty>' being compiled<br>
with<br>
[<br>
_Ty=llvm::Expected<int><br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\utility(198) : see reference to class template instantiation 'std::future<llvm::Expected<<wbr>int>>' being compiled<br>
C:\src\llvm\include\llvm/<wbr>Support/AlignOf.h(224) : see reference to class template instantiation 'std::pair<std::future<llvm::<wbr>Expected<int>>,<wbr>SequenceNumberT>' being compiled<br>
with<br>
[<br>
SequenceNumberT=uint16_t<br>
]<br>
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\type_traits(<wbr>584) : see reference to class template instantiation 'llvm::detail::AlignerImpl<T1,<wbr>T2,T3,T4,T5,T6,T7,T8,T9,T10>' being compiled<br>
with<br>
[<br>
T1=std::pair<std::future<llvm:<wbr>:Expected<int>>,uint16_t><br>
, T2=char<br>
, T3=char<br>
, T4=char<br>
, T5=char<br>
, T6=char<br>
, T7=char<br>
, T8=char<br>
, T9=char<br>
, T10=char<br>
]<br>
C:\src\llvm\include\llvm/<wbr>Support/AlignOf.h(83) : see reference to class template instantiation 'std::is_abstract<T>' being compiled<br>
with<br>
[<br>
T=llvm::detail::AlignerImpl<<wbr>std::pair<std::future<llvm::<wbr>Expected<int>>,uint16_t>,char,<wbr>char,char,char,char,char,char,<wbr>char,char><br>
]<br>
C:\src\llvm\include\llvm/<wbr>Support/AlignOf.h(253) : see reference to class template instantiation 'llvm::AlignOf<llvm::detail::<wbr>AlignerImpl<T1,T2,T3,T4,T5,T6,<wbr>T7,T8,T9,T10>>' being compiled<br>
Building Custom Rule C:/src/llvm/tools/clang/tools/<wbr>arcmt-test/CMakeLists.txt<br>
with<br>
[<br>
T1=std::pair<std::future<llvm:<wbr>:Expected<int>>,uint16_t><br>
, T2=char<br>
, T3=char<br>
, T4=char<br>
, T5=char<br>
, T6=char<br>
, T7=char<br>
, T8=char<br>
, T9=char<br>
, T10=char<br>
]<br>
C:\src\llvm\include\llvm/<wbr>Support/Error.h(831) : see reference to class template instantiation 'llvm::AlignedCharArrayUnion<<wbr>std::pair<std::future<llvm::<wbr>Expected<int>>,<wbr>SequenceNumberT>,char,char,<wbr>char,char,char,char,char,char,<wbr>char>' being compiled<br>
with<br>
[<br>
CMake does not need to re-run because C:\src\build\tools\clang\<wbr>tools\arcmt-test\CMakeFiles\<wbr>generate.stamp is up-to-date.<br>
SequenceNumberT=uint16_t<br>
]<br>
c:\src\llvm\include\llvm\<wbr>executionengine\orc\RPCUtils.<wbr>h(447) : see reference to class template instantiation 'llvm::Expected<std::pair<std:<wbr>:future<llvm::Expected<int>>,<wbr>SequenceNumberT>>' being compiled<br>
with<br>
[<br>
SequenceNumberT=uint16_t<br>
]<br>
C:\src\llvm\include\llvm/<wbr>ExecutionEngine/Orc/<wbr>OrcRemoteTargetClient.h(606) : see reference to function template instantiation 'llvm::Expected<int> llvm::orc::remote::RPC<llvm::<wbr>orc::remote::RPCChannel,<wbr>uint32_t,uint16_t>::<wbr>callSTHandling<llvm::orc::<wbr>remote::OrcRemoteTargetRPCAPI:<wbr>:CallIntVoid,llvm::orc::<wbr>remote::OrcRemoteTargetClient<<wbr>llvm::orc::remote::RPCChannel><wbr>::callIntVoid::<lambda_<wbr>1e43ba3f76d819646569b43fe46505<wbr>bc>,llvm::JITTargetAddress>(<wbr>ChannelT &,HandleFtor &,const llvm::JITTargetAddress &)' being compiled<br>
with<br>
[<br>
ChannelT=llvm::orc::remote::<wbr>RPCChannel<br>
, HandleFtor=llvm::orc::remote::<wbr>OrcRemoteTargetClient<llvm::<wbr>orc::remote::RPCChannel>::<wbr>callIntVoid::<lambda_<wbr>1e43ba3f76d819646569b43fe46505<wbr>bc><br>
]<br>
C:\src\llvm\include\llvm/<wbr>ExecutionEngine/Orc/<wbr>OrcRemoteTargetClient.h(606) : see reference to function template instantiation 'llvm::Expected<int> llvm::orc::remote::RPC<llvm::<wbr>orc::remote::RPCChannel,<wbr>uint32_t,uint16_t>::<wbr>callSTHandling<llvm::orc::<wbr>remote::OrcRemoteTargetRPCAPI:<wbr>:CallIntVoid,llvm::orc::<wbr>remote::OrcRemoteTargetClient<<wbr>llvm::orc::remote::RPCChannel><wbr>::callIntVoid::<lambda_<wbr>1e43ba3f76d819646569b43fe46505<wbr>bc>,llvm::JITTargetAddress>(<wbr>ChannelT &,HandleFtor &,const llvm::JITTargetAddress &)' being compiled<br>
with<br>
[<br>
ChannelT=llvm::orc::remote::<wbr>RPCChannel<br>
, HandleFtor=llvm::orc::remote::<wbr>OrcRemoteTargetClient<llvm::<wbr>orc::remote::RPCChannel>::<wbr>callIntVoid::<lambda_<wbr>1e43ba3f76d819646569b43fe46505<wbr>bc><br>
]<br>
C:\src\llvm\include\llvm/<wbr>ExecutionEngine/Orc/<wbr>OrcRemoteTargetClient.h(600) : while compiling class template member function 'llvm::Expected<int> llvm::orc::remote::<wbr>OrcRemoteTargetClient<llvm::<wbr>orc::remote::RPCChannel>::<wbr>callIntVoid(llvm::<wbr>JITTargetAddress)'<br>
C:\src\llvm\tools\lli\lli.cpp(<wbr>694) : see reference to function template instantiation 'llvm::Expected<int> llvm::orc::remote::<wbr>OrcRemoteTargetClient<llvm::<wbr>orc::remote::RPCChannel>::<wbr>callIntVoid(llvm::<wbr>JITTargetAddress)' being compiled<br>
C:\src\llvm\tools\lli\lli.cpp(<wbr>666) : see reference to class template instantiation 'llvm::orc::remote::<wbr>OrcRemoteTargetClient<llvm::<wbr>orc::remote::RPCChannel>' being compiled<br>
OrcLazyJIT.cpp<br>
<br>
<br>
Can you take a look into this?<br>
<br>
Douglas Yung<br>
<div><div class="h5"><br>
> -----Original Message-----<br>
> From: llvm-commits [mailto:<a href="mailto:llvm-commits-bounces@lists.llvm.org">llvm-commits-bounces@<wbr>lists.llvm.org</a>] On<br>
> Behalf Of Lang Hames via llvm-commits<br>
> Sent: Monday, August 29, 2016 14:57<br>
> To: <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
> Subject: [llvm] r280016 - [ORC][RPC] Make the future type of an Orc RPC<br>
> call Error/Expected rather than<br>
><br>
> Author: lhames<br>
> Date: Mon Aug 29 16:56:30 2016<br>
> New Revision: 280016<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=280016&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=280016&view=rev</a><br>
> Log:<br>
> [ORC][RPC] Make the future type of an Orc RPC call Error/Expected<br>
> rather than Optional.<br>
><br>
> For void functions the return type of a nonblocking call changes from<br>
> Expected<future<Optional<bool><wbr>>> to Expected<future<Error>>, and for<br>
> functions returning T the return type changes from<br>
> Expected<future<Optional<T>>> to Expected<future<Expected<T>>>.<br>
><br>
> Inner results need to be checked (since the RPC connection may have<br>
> dropped out before a result came back) and Error/Expected provide<br>
> stronger checking requirements. It also allows us drop the crufty<br>
> 'optionalToError' function and just collapse Errors in the single-<br>
> threaded call primitives.<br>
><br>
><br>
> Modified:<br>
> llvm/trunk/include/llvm/<wbr>ExecutionEngine/Orc/RPCUtils.h<br>
> llvm/trunk/unittests/<wbr>ExecutionEngine/Orc/<wbr>RPCUtilsTest.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/<wbr>ExecutionEngine/Orc/RPCUtils.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/include/<wbr>llvm/ExecutionEngine/Orc/<wbr>RPCUtils.h?rev=2800<br>
> 16&r1=280015&r2=280016&view=<wbr>diff<br>
> ==============================<wbr>==============================<wbr>===========<br>
> =======<br>
> --- llvm/trunk/include/llvm/<wbr>ExecutionEngine/Orc/RPCUtils.h (original)<br>
> +++ llvm/trunk/include/llvm/<wbr>ExecutionEngine/Orc/RPCUtils.h Mon Aug 29<br>
</div></div>> +++ 16:56:30 2016<br>
<div><div class="h5">> @@ -17,7 +17,6 @@<br>
> #include <map><br>
> #include <vector><br>
><br>
> -#include "llvm/ADT/Optional.h"<br>
> #include "llvm/ADT/STLExtras.h"<br>
> #include "llvm/ExecutionEngine/Orc/<wbr>OrcError.h"<br>
><br>
> @@ -61,6 +60,7 @@ public:<br>
> // partially specialized.<br>
> class RPCBase {<br>
> protected:<br>
> +<br>
> // RPC Function description type.<br>
> //<br>
> // This class provides the information and operations needed to<br>
> support the @@ -69,10 +69,7 @@ protected:<br>
> // betwen the two. Both specializations have the same interface:<br>
> //<br>
> // Id - The function's unique identifier.<br>
> - // OptionalReturn - The return type for asyncronous calls.<br>
> - // ErrorReturn - The return type for synchronous calls.<br>
> - // optionalToErrorReturn - Conversion from a valid OptionalReturn to<br>
> an<br>
> - // ErrorReturn.<br>
> + // ErrorReturn - The return type for blocking calls.<br>
> // readResult - Deserialize a result from a channel.<br>
> // abandon - Abandon a promised (asynchronous) result.<br>
> // respond - Retun a result on the channel.<br>
> @@ -91,32 +88,25 @@ protected:<br>
><br>
> static const FunctionIdT Id = FuncId;<br>
><br>
> - typedef Optional<RetT> OptionalReturn;<br>
> -<br>
> typedef Expected<RetT> ErrorReturn;<br>
><br>
> - static ErrorReturn optionalToErrorReturn(<wbr>OptionalReturn &&V) {<br>
> - assert(V && "Return value not available");<br>
> - return std::move(*V);<br>
> - }<br>
> -<br>
> template <typename ChannelT><br>
> - static Error readResult(ChannelT &C, std::promise<OptionalReturn><br>
> &P) {<br>
> + static Error readResult(ChannelT &C, std::promise<ErrorReturn> &P)<br>
</div></div>> + {<br>
<div><div class="h5">> RetT Val;<br>
> auto Err = deserialize(C, Val);<br>
> auto Err2 = endReceiveMessage(C);<br>
> Err = joinErrors(std::move(Err), std::move(Err2));<br>
> -<br>
> - if (Err) {<br>
> - P.set_value(OptionalReturn());<br>
> + if (Err)<br>
> return Err;<br>
> - }<br>
> +<br>
> P.set_value(std::move(Val));<br>
> return Error::success();<br>
> }<br>
><br>
> - static void abandon(std::promise<<wbr>OptionalReturn> &P) {<br>
> - P.set_value(OptionalReturn());<br>
> + static void abandon(std::promise<<wbr>ErrorReturn> &P) {<br>
> + P.set_value(<br>
> + make_error<StringError>("RPC function call failed to return",<br>
> + inconvertibleErrorCode()));<br>
> }<br>
><br>
> template <typename ChannelT, typename SequenceNumberT> @@ -148,22<br>
> +138,20 @@ protected:<br>
><br>
> static const FunctionIdT Id = FuncId;<br>
><br>
> - typedef bool OptionalReturn;<br>
> typedef Error ErrorReturn;<br>
><br>
> - static ErrorReturn optionalToErrorReturn(<wbr>OptionalReturn &&V) {<br>
> - assert(V && "Return value not available");<br>
> - return Error::success();<br>
> - }<br>
> -<br>
> template <typename ChannelT><br>
> - static Error readResult(ChannelT &C, std::promise<OptionalReturn><br>
> &P) {<br>
> + static Error readResult(ChannelT &C, std::promise<ErrorReturn> &P)<br>
</div></div>> + {<br>
<div><div class="h5">> // Void functions don't have anything to deserialize, so we're<br>
> good.<br>
> - P.set_value(true);<br>
> + P.set_value(Error::success());<br>
> return endReceiveMessage(C);<br>
> }<br>
><br>
> - static void abandon(std::promise<<wbr>OptionalReturn> &P) {<br>
> P.set_value(false); }<br>
> + static void abandon(std::promise<<wbr>ErrorReturn> &P) {<br>
> + P.set_value(<br>
> + make_error<StringError>("RPC function call failed to return",<br>
> + inconvertibleErrorCode()));<br>
> + }<br>
><br>
> template <typename ChannelT, typename SequenceNumberT><br>
> static Error respond(ChannelT &C, SequenceNumberT SeqNo, @@ -<br>
> 380,17 +368,17 @@ public:<br>
><br>
> /// Return type for asynchronous call primitives.<br>
> template <typename Func><br>
> - using AsyncCallResult = std::future<typename Func::OptionalReturn>;<br>
> + using AsyncCallResult = std::future<typename Func::ErrorReturn>;<br>
><br>
> /// Return type for asynchronous call-with-seq primitives.<br>
> template <typename Func><br>
> using AsyncCallWithSeqResult =<br>
> - std::pair<std::future<typename Func::OptionalReturn>,<br>
> SequenceNumberT>;<br>
> + std::pair<AsyncCallResult<<wbr>Func>, SequenceNumberT>;<br>
><br>
> /// Serialize Args... to channel C, but do not call C.send().<br>
> ///<br>
> /// Returns an error (on serialization failure) or a pair of:<br>
> - /// (1) A future Optional<T> (or future<bool> for void functions),<br>
> and<br>
> + /// (1) A future Expected<T> (or future<bool> for void functions),<br>
</div></div>> + and<br>
<div><div class="h5">> /// (2) A sequence number.<br>
> ///<br>
> /// This utility function is primarily used for single-threaded mode<br>
> support, @@ -401,7 +389,7 @@ public:<br>
> Expected<<wbr>AsyncCallWithSeqResult<Func>><br>
> appendCallAsyncWithSeq(<wbr>ChannelT &C, const ArgTs &... Args) {<br>
> auto SeqNo = SequenceNumberMgr.<wbr>getSequenceNumber();<br>
> - std::promise<typename Func::OptionalReturn> Promise;<br>
> + std::promise<typename Func::ErrorReturn> Promise;<br>
> auto Result = Promise.get_future();<br>
> OutstandingResults[SeqNo] =<br>
> createOutstandingResult<Func>(<wbr>std::move(Promise));<br>
> @@ -431,7 +419,7 @@ public:<br>
><br>
> /// Serialize Args... to channel C, but do not call send.<br>
> /// Returns an error if serialization fails, otherwise returns a<br>
> - /// std::future<Optional<T>> (or a future<bool> for void functions).<br>
> + /// std::future<Expected<T>> (or a future<bool> for void functions).<br>
> template <typename Func, typename... ArgTs><br>
> Expected<AsyncCallResult<Func><wbr>> appendCallAsync(ChannelT &C,<br>
> const ArgTs &...<br>
> Args) { @@ -460,7 +448,7 @@ public:<br>
> auto &ResultAndSeqNo = *ResultAndSeqNoOrErr;<br>
> if (auto Err = waitForResult(C, ResultAndSeqNo.second,<br>
> HandleOther))<br>
> return std::move(Err);<br>
> - return Func::optionalToErrorReturn(<wbr>ResultAndSeqNo.first.get());<br>
> + return ResultAndSeqNo.first.get();<br>
> } else<br>
> return ResultAndSeqNoOrErr.takeError(<wbr>);<br>
> }<br>
> @@ -656,7 +644,7 @@ private:<br>
> class OutstandingResultImpl : public OutstandingResult {<br>
> private:<br>
> public:<br>
> - OutstandingResultImpl(std::<wbr>promise<typename Func::OptionalReturn><br>
> &&P)<br>
> + OutstandingResultImpl(std::<wbr>promise<typename Func::ErrorReturn><br>
> &&P)<br>
> : P(std::move(P)) {}<br>
><br>
> Error readResult(ChannelT &C) override { return<br>
> Func::readResult(C, P); } @@ -664,13 +652,13 @@ private:<br>
> void abandon() override { Func::abandon(P); }<br>
><br>
> private:<br>
> - std::promise<typename Func::OptionalReturn> P;<br>
> + std::promise<typename Func::ErrorReturn> P;<br>
> };<br>
><br>
> // Create an outstanding result for the given function.<br>
> template <typename Func><br>
> std::unique_ptr<<wbr>OutstandingResult><br>
> - createOutstandingResult(std::<wbr>promise<typename Func::OptionalReturn><br>
> &&P) {<br>
> + createOutstandingResult(std::<wbr>promise<typename Func::ErrorReturn><br>
> &&P)<br>
</div></div>> + {<br>
<span class="">> return<br>
> llvm::make_unique<<wbr>OutstandingResultImpl<Func>>(<wbr>std::move(P));<br>
> }<br>
><br>
><br>
> Modified: llvm/trunk/unittests/<wbr>ExecutionEngine/Orc/<wbr>RPCUtilsTest.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/llvm/trunk/unittests/<wbr>ExecutionEngine/Orc/<wbr>RPCUtilsTest.cpp?rev=2<br>
> 80016&r1=280015&r2=280016&<wbr>view=diff<br>
> ==============================<wbr>==============================<wbr>===========<br>
> =======<br>
> --- llvm/trunk/unittests/<wbr>ExecutionEngine/Orc/<wbr>RPCUtilsTest.cpp<br>
> (original)<br>
> +++ llvm/trunk/unittests/<wbr>ExecutionEngine/Orc/<wbr>RPCUtilsTest.cpp Mon Aug<br>
> 29<br>
</span>> +++ 16:56:30 2016<br>
<div class="HOEnZb"><div class="h5">> @@ -102,8 +102,8 @@ TEST_F(DummyRPC, TestAsyncVoidBool) {<br>
> }<br>
><br>
> // Verify that the function returned ok.<br>
> - auto Val = ResOrErr->first.get();<br>
> - EXPECT_TRUE(Val) << "Remote void function failed to execute.";<br>
> + auto Err = ResOrErr->first.get();<br>
> + EXPECT_TRUE(!!Err) << "Remote void function failed to execute.";<br>
> }<br>
><br>
> TEST_F(DummyRPC, TestAsyncIntInt) {<br>
> @@ -179,8 +179,8 @@ TEST_F(DummyRPC, TestSerialization) {<br>
> }<br>
><br>
> // Verify that the function returned ok.<br>
> - auto Val = ResOrErr->first.get();<br>
> - EXPECT_TRUE(Val) << "Remote void function failed to execute.";<br>
> + auto Err = ResOrErr->first.get();<br>
> + EXPECT_TRUE(!!Err) << "Remote void function failed to execute.";<br>
> }<br>
><br>
> // Test the synchronous call API.<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org">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/<wbr>mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>