[llvm] r257452 - [Orc] Add overloads of RPC::handle and RPC::expect that take member functions as

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 15 17:31:12 PST 2016


Hi Dave,

> Might be able to stamp this switch out with a macro/.def file too.

Yes. I'm on the fence here - I really dislike introducing macros in
headers, but there is a lot of redundancy in those switch cases. If the
server API grows much bigger (which is unlikely) I'll switch it over.

> Might be able to use std::bind + std::mem_fn rather than writing your own
wrapper

Unfortunately std::bind doesn't quite fit here: You need to know the number
of arguments of the thing you're binding ahead of time. My wrapper is just
intended to transform an arbitrary class member function and object pointer
into a functor. I haven't seen an STL (or LLVM) template that does that,
though I'd prefer to use one if it exists.

If other LLVM users have a use for this wrapper I'd be happy to tidy it up
and move it to STLExtras too. It seems like it might be a good fit there.

- Lang.

On Thu, Jan 14, 2016 at 4:14 PM, David Blaikie <dblaikie at gmail.com> wrote:

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


More information about the llvm-commits mailing list