<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 11, 2016 at 10:48 PM, Lang Hames 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lhames<br>
Date: Tue Jan 12 00:48:52 2016<br>
New Revision: 257452<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=257452&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=257452&view=rev</a><br>
Log:<br>
[Orc] Add overloads of RPC::handle and RPC::expect that take member functions as<br>
handlers.<br>
<br>
It is expected that RPC handlers will usually be member functions. Accepting them<br>
directly in handle and expect allows for the remove of a lot of lambdas an<br>
explicit error variables.<br>
<br>
This patch also uses this new feature to substantially tidy up the<br>
OrcRemoteTargetServer class.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h?rev=257452&r1=257451&r2=257452&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h?rev=257452&r1=257451&r2=257452&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h Tue Jan 12 00:48:52 2016<br>
@@ -43,41 +43,54 @@ public:<br>
   }<br>
<br>
   std::error_code handleKnownProcedure(JITProcId Id) {<br>
+    typedef OrcRemoteTargetServer ThisT;<br>
+<br>
     DEBUG(dbgs() << "Handling known proc: " << getJITProcIdName(Id) << "\n");<br>
<br>
     switch (Id) {<br>
     case CallIntVoidId:<br>
-      return handleCallIntVoid();<br>
+      return handle<CallIntVoid>(Channel, *this, &ThisT::handleCallIntVoid);<br></blockquote><div><br></div><div>Might be able to stamp this switch out with a macro/.def file too.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     case CallMainId:<br>
-      return handleCallMain();<br>
+      return handle<CallMain>(Channel, *this, &ThisT::handleCallMain);<br>
     case CallVoidVoidId:<br>
-      return handleCallVoidVoid();<br>
+      return handle<CallVoidVoid>(Channel, *this, &ThisT::handleCallVoidVoid);<br>
     case CreateRemoteAllocatorId:<br>
-      return handleCreateRemoteAllocator();<br>
+      return handle<CreateRemoteAllocator>(Channel, *this,<br>
+                                           &ThisT::handleCreateRemoteAllocator);<br>
     case CreateIndirectStubsOwnerId:<br>
-      return handleCreateIndirectStubsOwner();<br>
+      return handle<CreateIndirectStubsOwner>(<br>
+          Channel, *this, &ThisT::handleCreateIndirectStubsOwner);<br>
     case DestroyRemoteAllocatorId:<br>
-      return handleDestroyRemoteAllocator();<br>
+      return handle<DestroyRemoteAllocator>(<br>
+          Channel, *this, &ThisT::handleDestroyRemoteAllocator);<br>
+    case DestroyIndirectStubsOwnerId:<br>
+      return handle<DestroyIndirectStubsOwner>(<br>
+          Channel, *this, &ThisT::handleDestroyIndirectStubsOwner);<br>
     case EmitIndirectStubsId:<br>
-      return handleEmitIndirectStubs();<br>
+      return handle<EmitIndirectStubs>(Channel, *this,<br>
+                                       &ThisT::handleEmitIndirectStubs);<br>
     case EmitResolverBlockId:<br>
-      return handleEmitResolverBlock();<br>
+      return handle<EmitResolverBlock>(Channel, *this,<br>
+                                       &ThisT::handleEmitResolverBlock);<br>
     case EmitTrampolineBlockId:<br>
-      return handleEmitTrampolineBlock();<br>
+      return handle<EmitTrampolineBlock>(Channel, *this,<br>
+                                         &ThisT::handleEmitTrampolineBlock);<br>
     case GetSymbolAddressId:<br>
-      return handleGetSymbolAddress();<br>
+      return handle<GetSymbolAddress>(Channel, *this,<br>
+                                      &ThisT::handleGetSymbolAddress);<br>
     case GetRemoteInfoId:<br>
-      return handleGetRemoteInfo();<br>
+      return handle<GetRemoteInfo>(Channel, *this, &ThisT::handleGetRemoteInfo);<br>
     case ReadMemId:<br>
-      return handleReadMem();<br>
+      return handle<ReadMem>(Channel, *this, &ThisT::handleReadMem);<br>
     case ReserveMemId:<br>
-      return handleReserveMem();<br>
+      return handle<ReserveMem>(Channel, *this, &ThisT::handleReserveMem);<br>
     case SetProtectionsId:<br>
-      return handleSetProtections();<br>
+      return handle<SetProtections>(Channel, *this,<br>
+                                    &ThisT::handleSetProtections);<br>
     case WriteMemId:<br>
-      return handleWriteMem();<br>
+      return handle<WriteMem>(Channel, *this, &ThisT::handleWriteMem);<br>
     case WritePtrId:<br>
-      return handleWritePtr();<br>
+      return handle<WritePtr>(Channel, *this, &ThisT::handleWritePtr);<br>
     default:<br>
       return orcError(OrcErrorCode::UnexpectedRPCCall);<br>
     }<br>
@@ -160,16 +173,10 @@ private:<br>
     return CompiledFnAddr;<br>
   }<br>
<br>
-  std::error_code handleCallIntVoid() {<br>
+  std::error_code handleCallIntVoid(TargetAddress Addr) {<br>
     typedef int (*IntVoidFnTy)();<br>
-<br>
-    IntVoidFnTy Fn = nullptr;<br>
-    if (std::error_code EC =<br>
-            handle<CallIntVoid>(Channel, [&](TargetAddress Addr) {<br>
-              Fn = reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr));<br>
-              return std::error_code();<br>
-            }))<br>
-      return EC;<br>
+    IntVoidFnTy Fn =<br>
+        reinterpret_cast<IntVoidFnTy>(static_cast<uintptr_t>(Addr));<br>
<br>
     DEBUG(dbgs() << "  Calling "<br>
                  << reinterpret_cast<void *>(reinterpret_cast<intptr_t>(Fn))<br>
@@ -180,19 +187,11 @@ private:<br>
     return call<CallIntVoidResponse>(Channel, Result);<br>
   }<br>
<br>
-  std::error_code handleCallMain() {<br>
+  std::error_code handleCallMain(TargetAddress Addr,<br>
+                                 std::vector<std::string> Args) {<br>
     typedef int (*MainFnTy)(int, const char *[]);<br>
<br>
-    MainFnTy Fn = nullptr;<br>
-    std::vector<std::string> Args;<br>
-    if (std::error_code EC = handle<CallMain>(<br>
-            Channel, [&](TargetAddress Addr, std::vector<std::string> &A) {<br>
-              Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr));<br>
-              Args = std::move(A);<br>
-              return std::error_code();<br>
-            }))<br>
-      return EC;<br>
-<br>
+    MainFnTy Fn = reinterpret_cast<MainFnTy>(static_cast<uintptr_t>(Addr));<br>
     int ArgC = Args.size() + 1;<br>
     int Idx = 1;<br>
     std::unique_ptr<const char *[]> ArgV(new const char *[ArgC + 1]);<br>
@@ -207,16 +206,10 @@ private:<br>
     return call<CallMainResponse>(Channel, Result);<br>
   }<br>
<br>
-  std::error_code handleCallVoidVoid() {<br>
+  std::error_code handleCallVoidVoid(TargetAddress Addr) {<br>
     typedef void (*VoidVoidFnTy)();<br>
-<br>
-    VoidVoidFnTy Fn = nullptr;<br>
-    if (std::error_code EC =<br>
-            handle<CallIntVoid>(Channel, [&](TargetAddress Addr) {<br>
-              Fn = reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr));<br>
-              return std::error_code();<br>
-            }))<br>
-      return EC;<br>
+    VoidVoidFnTy Fn =<br>
+        reinterpret_cast<VoidVoidFnTy>(static_cast<uintptr_t>(Addr));<br>
<br>
     DEBUG(dbgs() << "  Calling " << reinterpret_cast<void *>(Fn) << "\n");<br>
     Fn();<br>
@@ -225,66 +218,48 @@ private:<br>
     return call<CallVoidVoidResponse>(Channel);<br>
   }<br>
<br>
-  std::error_code handleCreateRemoteAllocator() {<br>
-    return handle<CreateRemoteAllocator>(<br>
-        Channel, [&](ResourceIdMgr::ResourceId Id) {<br>
-          auto I = Allocators.find(Id);<br>
-          if (I != Allocators.end())<br>
-            return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse);<br>
-          DEBUG(dbgs() << "  Created allocator " << Id << "\n");<br>
-          Allocators[Id] = Allocator();<br>
-          return std::error_code();<br>
-        });<br>
-  }<br>
-<br>
-  std::error_code handleCreateIndirectStubsOwner() {<br>
-    return handle<CreateIndirectStubsOwner>(<br>
-        Channel, [&](ResourceIdMgr::ResourceId Id) {<br>
-          auto I = IndirectStubsOwners.find(Id);<br>
-          if (I != IndirectStubsOwners.end())<br>
-            return orcError(<br>
-                OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse);<br>
-          DEBUG(dbgs() << "  Create indirect stubs owner " << Id << "\n");<br>
-          IndirectStubsOwners[Id] = ISBlockOwnerList();<br>
-          return std::error_code();<br>
-        });<br>
-  }<br>
-<br>
-  std::error_code handleDestroyRemoteAllocator() {<br>
-    return handle<DestroyRemoteAllocator>(<br>
-        Channel, [&](ResourceIdMgr::ResourceId Id) {<br>
-          auto I = Allocators.find(Id);<br>
-          if (I == Allocators.end())<br>
-            return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);<br>
-          Allocators.erase(I);<br>
-          DEBUG(dbgs() << "  Destroyed allocator " << Id << "\n");<br>
-          return std::error_code();<br>
-        });<br>
-  }<br>
-<br>
-  std::error_code handleDestroyIndirectStubsOwner() {<br>
-    return handle<DestroyIndirectStubsOwner>(<br>
-        Channel, [&](ResourceIdMgr::ResourceId Id) {<br>
-          auto I = IndirectStubsOwners.find(Id);<br>
-          if (I == IndirectStubsOwners.end())<br>
-            return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);<br>
-          IndirectStubsOwners.erase(I);<br>
-          return std::error_code();<br>
-        });<br>
-  }<br>
-<br>
-  std::error_code handleEmitIndirectStubs() {<br>
-    ResourceIdMgr::ResourceId ISOwnerId = ~0U;<br>
-    uint32_t NumStubsRequired = 0;<br>
-<br>
-    if (auto EC = handle<EmitIndirectStubs>(<br>
-            Channel, readArgs(ISOwnerId, NumStubsRequired)))<br>
-      return EC;<br>
+  std::error_code handleCreateRemoteAllocator(ResourceIdMgr::ResourceId Id) {<br>
+    auto I = Allocators.find(Id);<br>
+    if (I != Allocators.end())<br>
+      return orcError(OrcErrorCode::RemoteAllocatorIdAlreadyInUse);<br>
+    DEBUG(dbgs() << "  Created allocator " << Id << "\n");<br>
+    Allocators[Id] = Allocator();<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  std::error_code handleCreateIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {<br>
+    auto I = IndirectStubsOwners.find(Id);<br>
+    if (I != IndirectStubsOwners.end())<br>
+      return orcError(OrcErrorCode::RemoteIndirectStubsOwnerIdAlreadyInUse);<br>
+    DEBUG(dbgs() << "  Create indirect stubs owner " << Id << "\n");<br>
+    IndirectStubsOwners[Id] = ISBlockOwnerList();<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  std::error_code handleDestroyRemoteAllocator(ResourceIdMgr::ResourceId Id) {<br>
+    auto I = Allocators.find(Id);<br>
+    if (I == Allocators.end())<br>
+      return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);<br>
+    Allocators.erase(I);<br>
+    DEBUG(dbgs() << "  Destroyed allocator " << Id << "\n");<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  std::error_code<br>
+  handleDestroyIndirectStubsOwner(ResourceIdMgr::ResourceId Id) {<br>
+    auto I = IndirectStubsOwners.find(Id);<br>
+    if (I == IndirectStubsOwners.end())<br>
+      return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);<br>
+    IndirectStubsOwners.erase(I);<br>
+    return std::error_code();<br>
+  }<br>
<br>
-    DEBUG(dbgs() << "  ISMgr " << ISOwnerId << " request " << NumStubsRequired<br>
+  std::error_code handleEmitIndirectStubs(ResourceIdMgr::ResourceId Id,<br>
+                                          uint32_t NumStubsRequired) {<br>
+    DEBUG(dbgs() << "  ISMgr " << Id << " request " << NumStubsRequired<br>
                  << " stubs.\n");<br>
<br>
-    auto StubOwnerItr = IndirectStubsOwners.find(ISOwnerId);<br>
+    auto StubOwnerItr = IndirectStubsOwners.find(Id);<br>
     if (StubOwnerItr == IndirectStubsOwners.end())<br>
       return orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist);<br>
<br>
@@ -307,9 +282,6 @@ private:<br>
   }<br>
<br>
   std::error_code handleEmitResolverBlock() {<br>
-    if (auto EC = handle<EmitResolverBlock>(Channel, doNothing))<br>
-      return EC;<br>
-<br>
     std::error_code EC;<br>
     ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(<br>
         TargetT::ResolverCodeSize, nullptr,<br>
@@ -326,11 +298,7 @@ private:<br>
   }<br>
<br>
   std::error_code handleEmitTrampolineBlock() {<br>
-    if (auto EC = handle<EmitTrampolineBlock>(Channel, doNothing))<br>
-      return EC;<br>
-<br>
     std::error_code EC;<br>
-<br>
     auto TrampolineBlock =<br>
         sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(<br>
             sys::Process::getPageSize(), nullptr,<br>
@@ -358,21 +326,14 @@ private:<br>
         NumTrampolines);<br>
   }<br>
<br>
-  std::error_code handleGetSymbolAddress() {<br>
-    std::string SymbolName;<br>
-    if (auto EC = handle<GetSymbolAddress>(Channel, readArgs(SymbolName)))<br>
-      return EC;<br>
-<br>
-    TargetAddress SymbolAddr = SymbolLookup(SymbolName);<br>
-    DEBUG(dbgs() << "  Symbol '" << SymbolName<br>
-                 << "' =  " << format("0x%016x", SymbolAddr) << "\n");<br>
-    return call<GetSymbolAddressResponse>(Channel, SymbolAddr);<br>
+  std::error_code handleGetSymbolAddress(const std::string &Name) {<br>
+    TargetAddress Addr = SymbolLookup(Name);<br>
+    DEBUG(dbgs() << "  Symbol '" << Name << "' =  " << format("0x%016x", Addr)<br>
+                 << "\n");<br>
+    return call<GetSymbolAddressResponse>(Channel, Addr);<br>
   }<br>
<br>
   std::error_code handleGetRemoteInfo() {<br>
-    if (auto EC = handle<GetRemoteInfo>(Channel, doNothing))<br>
-      return EC;<br>
-<br>
     std::string ProcessTriple = sys::getProcessTriple();<br>
     uint32_t PointerSize = TargetT::PointerSize;<br>
     uint32_t PageSize = sys::Process::getPageSize();<br>
@@ -389,16 +350,8 @@ private:<br>
                                        IndirectStubSize);<br>
   }<br>
<br>
-  std::error_code handleReadMem() {<br>
-    char *Src = nullptr;<br>
-    uint64_t Size = 0;<br>
-    if (std::error_code EC =<br>
-            handle<ReadMem>(Channel, [&](TargetAddress RSrc, uint64_t RSize) {<br>
-              Src = reinterpret_cast<char *>(static_cast<uintptr_t>(RSrc));<br>
-              Size = RSize;<br>
-              return std::error_code();<br>
-            }))<br>
-      return EC;<br>
+  std::error_code handleReadMem(TargetAddress RSrc, uint64_t Size) {<br>
+    char *Src = reinterpret_cast<char *>(static_cast<uintptr_t>(RSrc));<br>
<br>
     DEBUG(dbgs() << "  Reading " << Size << " bytes from "<br>
                  << static_cast<void *>(Src) << "\n");<br>
@@ -412,62 +365,49 @@ private:<br>
     return Channel.send();<br>
   }<br>
<br>
-  std::error_code handleReserveMem() {<br>
+  std::error_code handleReserveMem(ResourceIdMgr::ResourceId Id, uint64_t Size,<br>
+                                   uint32_t Align) {<br>
+    auto I = Allocators.find(Id);<br>
+    if (I == Allocators.end())<br>
+      return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);<br>
+    auto &Allocator = I->second;<br>
     void *LocalAllocAddr = nullptr;<br>
-<br>
-    if (std::error_code EC =<br>
-            handle<ReserveMem>(Channel, [&](ResourceIdMgr::ResourceId Id,<br>
-                                            uint64_t Size, uint32_t Align) {<br>
-              auto I = Allocators.find(Id);<br>
-              if (I == Allocators.end())<br>
-                return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);<br>
-              auto &Allocator = I->second;<br>
-              auto EC2 = Allocator.allocate(LocalAllocAddr, Size, Align);<br>
-              DEBUG(dbgs() << "  Allocator " << Id << " reserved "<br>
-                           << LocalAllocAddr << " (" << Size<br>
-                           << " bytes, alignment " << Align << ")\n");<br>
-              return EC2;<br>
-            }))<br>
+    if (auto EC = Allocator.allocate(LocalAllocAddr, Size, Align))<br>
       return EC;<br>
<br>
+    DEBUG(dbgs() << "  Allocator " << Id << " reserved " << LocalAllocAddr<br>
+                 << " (" << Size << " bytes, alignment " << Align << ")\n");<br>
+<br>
     TargetAddress AllocAddr =<br>
         static_cast<TargetAddress>(reinterpret_cast<uintptr_t>(LocalAllocAddr));<br>
<br>
     return call<ReserveMemResponse>(Channel, AllocAddr);<br>
   }<br>
<br>
-  std::error_code handleSetProtections() {<br>
-    return handle<ReserveMem>(Channel, [&](ResourceIdMgr::ResourceId Id,<br>
-                                           TargetAddress Addr, uint32_t Flags) {<br>
-      auto I = Allocators.find(Id);<br>
-      if (I == Allocators.end())<br>
-        return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);<br>
-      auto &Allocator = I->second;<br>
-      void *LocalAddr = reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));<br>
-      DEBUG(dbgs() << "  Allocator " << Id << " set permissions on "<br>
-                   << LocalAddr << " to "<br>
-                   << (Flags & sys::Memory::MF_READ ? 'R' : '-')<br>
-                   << (Flags & sys::Memory::MF_WRITE ? 'W' : '-')<br>
-                   << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n");<br>
-      return Allocator.setProtections(LocalAddr, Flags);<br>
-    });<br>
-  }<br>
-<br>
-  std::error_code handleWriteMem() {<br>
-    return handle<WriteMem>(Channel, [&](TargetAddress RDst, uint64_t Size) {<br>
-      char *Dst = reinterpret_cast<char *>(static_cast<uintptr_t>(RDst));<br>
-      return Channel.readBytes(Dst, Size);<br>
-    });<br>
-  }<br>
-<br>
-  std::error_code handleWritePtr() {<br>
-    return handle<WritePtr>(<br>
-        Channel, [&](TargetAddress Addr, TargetAddress PtrVal) {<br>
-          uintptr_t *Ptr =<br>
-              reinterpret_cast<uintptr_t *>(static_cast<uintptr_t>(Addr));<br>
-          *Ptr = static_cast<uintptr_t>(PtrVal);<br>
-          return std::error_code();<br>
-        });<br>
+  std::error_code handleSetProtections(ResourceIdMgr::ResourceId Id,<br>
+                                       TargetAddress Addr, uint32_t Flags) {<br>
+    auto I = Allocators.find(Id);<br>
+    if (I == Allocators.end())<br>
+      return orcError(OrcErrorCode::RemoteAllocatorDoesNotExist);<br>
+    auto &Allocator = I->second;<br>
+    void *LocalAddr = reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));<br>
+    DEBUG(dbgs() << "  Allocator " << Id << " set permissions on " << LocalAddr<br>
+                 << " to " << (Flags & sys::Memory::MF_READ ? 'R' : '-')<br>
+                 << (Flags & sys::Memory::MF_WRITE ? 'W' : '-')<br>
+                 << (Flags & sys::Memory::MF_EXEC ? 'X' : '-') << "\n");<br>
+    return Allocator.setProtections(LocalAddr, Flags);<br>
+  }<br>
+<br>
+  std::error_code handleWriteMem(TargetAddress RDst, uint64_t Size) {<br>
+    char *Dst = reinterpret_cast<char *>(static_cast<uintptr_t>(RDst));<br>
+    return Channel.readBytes(Dst, Size);<br>
+  }<br>
+<br>
+  std::error_code handleWritePtr(TargetAddress Addr, TargetAddress PtrVal) {<br>
+    uintptr_t *Ptr =<br>
+        reinterpret_cast<uintptr_t *>(static_cast<uintptr_t>(Addr));<br>
+    *Ptr = static_cast<uintptr_t>(PtrVal);<br>
+    return std::error_code();<br>
   }<br>
<br>
   ChannelT &Channel;<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=257452&r1=257451&r2=257452&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h?rev=257452&r1=257451&r2=257452&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/RPCUtils.h Tue Jan 12 00:48:52 2016<br>
@@ -69,6 +69,20 @@ protected:<br>
     }<br>
   };<br>
<br>
+  template <typename ClassT, typename... ArgTs> class MemberFnWrapper {<br></blockquote><div><br></div><div>Might be able to use std::bind + std::mem_fn rather than writing your own wrapper</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+  public:<br>
+    typedef std::error_code (ClassT::*MethodT)(ArgTs...);<br>
+    MemberFnWrapper(ClassT &Instance, MethodT Method)<br>
+        : Instance(Instance), Method(Method) {}<br>
+    std::error_code operator()(ArgTs &... Args) {<br>
+      return (Instance.*Method)(Args...);<br>
+    }<br>
+<br>
+  private:<br>
+    ClassT &Instance;<br>
+    MethodT Method;<br>
+  };<br>
+<br>
   template <typename... ArgTs> class ReadArgs {<br>
   public:<br>
     std::error_code operator()() { return std::error_code(); }<br>
@@ -193,6 +207,15 @@ public:<br>
     return HandlerHelper<ChannelT, Proc>::handle(C, Handler);<br>
   }<br>
<br>
+  /// Helper version of 'handle' for calling member functions.<br>
+  template <typename Proc, typename ClassT, typename... ArgTs><br>
+  static std::error_code<br>
+  handle(ChannelT &C, ClassT &Instance,<br>
+         std::error_code (ClassT::*HandlerMethod)(ArgTs...)) {<br>
+    return handle<Proc>(<br>
+        C, MemberFnWrapper<ClassT, ArgTs...>(Instance, HandlerMethod));<br>
+  }<br>
+<br>
   /// Deserialize a ProcedureIdT from C and verify it matches the id for Proc.<br>
   /// If the id does match, deserialize the arguments and call the handler<br>
   /// (similarly to handle).<br>
@@ -208,6 +231,15 @@ public:<br>
     return handle<Proc>(C, Handler);<br>
   }<br>
<br>
+  /// Helper version of expect for calling member functions.<br>
+  template <typename Proc, typename ClassT, typename... ArgTs><br>
+  static std::error_code<br>
+  expect(ChannelT &C, ClassT &Instance,<br>
+         std::error_code (ClassT::*HandlerMethod)(ArgTs...)) {<br>
+    return expect<Proc>(<br>
+        C, MemberFnWrapper<ClassT, ArgTs...>(Instance, HandlerMethod));<br>
+  }<br>
+<br>
   /// Helper for handling setter procedures - this method returns a functor that<br>
   /// sets the variables referred to by Args... to values deserialized from the<br>
   /// channel.<br>
<br>
<br>
_______________________________________________<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/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>