LCOV - code coverage report
Current view: top level - include/llvm/ExecutionEngine/Orc - RPCSerialization.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 323 527 61.3 %
Date: 2018-10-20 13:21:21 Functions: 76 163 46.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/ExecutionEngine/Orc/RPCSerialization.h --------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
      11             : #define LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
      12             : 
      13             : #include "OrcError.h"
      14             : #include "llvm/Support/thread.h"
      15             : #include <map>
      16             : #include <mutex>
      17             : #include <set>
      18             : #include <sstream>
      19             : #include <string>
      20             : #include <vector>
      21             : 
      22             : namespace llvm {
      23             : namespace orc {
      24             : namespace rpc {
      25             : 
      26             : template <typename T>
      27             : class RPCTypeName;
      28             : 
      29             : /// TypeNameSequence is a utility for rendering sequences of types to a string
      30             : /// by rendering each type, separated by ", ".
      31             : template <typename... ArgTs> class RPCTypeNameSequence {};
      32             : 
      33             : /// Render an empty TypeNameSequence to an ostream.
      34             : template <typename OStream>
      35           0 : OStream &operator<<(OStream &OS, const RPCTypeNameSequence<> &V) {
      36           0 :   return OS;
      37             : }
      38             : 
      39             : /// Render a TypeNameSequence of a single type to an ostream.
      40             : template <typename OStream, typename ArgT>
      41           0 : OStream &operator<<(OStream &OS, const RPCTypeNameSequence<ArgT> &V) {
      42         464 :   OS << RPCTypeName<ArgT>::getName();
      43           0 :   return OS;
      44             : }
      45           0 : 
      46           0 : /// Render a TypeNameSequence of more than one type to an ostream.
      47           0 : template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
      48             : OStream&
      49           0 : operator<<(OStream &OS, const RPCTypeNameSequence<ArgT1, ArgT2, ArgTs...> &V) {
      50           0 :   OS << RPCTypeName<ArgT1>::getName() << ", "
      51           0 :      << RPCTypeNameSequence<ArgT2, ArgTs...>();
      52             :   return OS;
      53           0 : }
      54           0 : 
      55           0 : template <>
      56             : class RPCTypeName<void> {
      57           0 : public:
      58           0 :   static const char* getName() { return "void"; }
      59           0 : };
      60             : 
      61           0 : template <>
      62           0 : class RPCTypeName<int8_t> {
      63           0 : public:
      64             :   static const char* getName() { return "int8_t"; }
      65           0 : };
      66           0 : 
      67           0 : template <>
      68           0 : class RPCTypeName<uint8_t> {
      69           0 : public:
      70           0 :   static const char* getName() { return "uint8_t"; }
      71           0 : };
      72           0 : 
      73           0 : template <>
      74           0 : class RPCTypeName<int16_t> {
      75           0 : public:
      76           0 :   static const char* getName() { return "int16_t"; }
      77           0 : };
      78           0 : 
      79           0 : template <>
      80           0 : class RPCTypeName<uint16_t> {
      81           0 : public:
      82           0 :   static const char* getName() { return "uint16_t"; }
      83           0 : };
      84           0 : 
      85           0 : template <>
      86           0 : class RPCTypeName<int32_t> {
      87           0 : public:
      88           0 :   static const char* getName() { return "int32_t"; }
      89           0 : };
      90           0 : 
      91           0 : template <>
      92           0 : class RPCTypeName<uint32_t> {
      93           0 : public:
      94           0 :   static const char* getName() { return "uint32_t"; }
      95           0 : };
      96           0 : 
      97           0 : template <>
      98           0 : class RPCTypeName<int64_t> {
      99           0 : public:
     100           0 :   static const char* getName() { return "int64_t"; }
     101           0 : };
     102           0 : 
     103           0 : template <>
     104           0 : class RPCTypeName<uint64_t> {
     105           0 : public:
     106           0 :   static const char* getName() { return "uint64_t"; }
     107           0 : };
     108           0 : 
     109           0 : template <>
     110           0 : class RPCTypeName<bool> {
     111           0 : public:
     112           0 :   static const char* getName() { return "bool"; }
     113           0 : };
     114           0 : 
     115           0 : template <>
     116           0 : class RPCTypeName<std::string> {
     117             : public:
     118           0 :   static const char* getName() { return "std::string"; }
     119           0 : };
     120           0 : 
     121           0 : template <>
     122             : class RPCTypeName<Error> {
     123           0 : public:
     124           0 :   static const char* getName() { return "Error"; }
     125           0 : };
     126           0 : 
     127             : template <typename T>
     128           0 : class RPCTypeName<Expected<T>> {
     129           0 : public:
     130           0 :   static const char* getName() {
     131           0 :     std::lock_guard<std::mutex> Lock(NameMutex);
     132             :     if (Name.empty())
     133           0 :       raw_string_ostream(Name) << "Expected<"
     134           0 :                                << RPCTypeNameSequence<T>()
     135           0 :                                << ">";
     136           0 :     return Name.data();
     137             :   }
     138           0 : 
     139           0 : private:
     140           0 :   static std::mutex NameMutex;
     141           0 :   static std::string Name;
     142             : };
     143             : 
     144             : template <typename T>
     145             : std::mutex RPCTypeName<Expected<T>>::NameMutex;
     146             : 
     147             : template <typename T>
     148             : std::string RPCTypeName<Expected<T>>::Name;
     149             : 
     150             : template <typename T1, typename T2>
     151             : class RPCTypeName<std::pair<T1, T2>> {
     152             : public:
     153             :   static const char* getName() {
     154             :     std::lock_guard<std::mutex> Lock(NameMutex);
     155             :     if (Name.empty())
     156             :       raw_string_ostream(Name) << "std::pair<" << RPCTypeNameSequence<T1, T2>()
     157             :                                << ">";
     158             :     return Name.data();
     159             :   }
     160             : private:
     161             :   static std::mutex NameMutex;
     162             :   static std::string Name;
     163             : };
     164             : 
     165             : template <typename T1, typename T2>
     166             : std::mutex RPCTypeName<std::pair<T1, T2>>::NameMutex;
     167             : template <typename T1, typename T2>
     168             : std::string RPCTypeName<std::pair<T1, T2>>::Name;
     169             : 
     170          48 : template <typename... ArgTs>
     171             : class RPCTypeName<std::tuple<ArgTs...>> {
     172          48 : public:
     173             :   static const char* getName() {
     174          32 :     std::lock_guard<std::mutex> Lock(NameMutex);
     175          16 :     if (Name.empty())
     176          48 :       raw_string_ostream(Name) << "std::tuple<"
     177             :                                << RPCTypeNameSequence<ArgTs...>() << ">";
     178          16 :     return Name.data();
     179             :   }
     180          16 : private:
     181             :   static std::mutex NameMutex;
     182          16 :   static std::string Name;
     183           8 : };
     184          16 : 
     185             : template <typename... ArgTs>
     186          32 : std::mutex RPCTypeName<std::tuple<ArgTs...>>::NameMutex;
     187             : template <typename... ArgTs>
     188          32 : std::string RPCTypeName<std::tuple<ArgTs...>>::Name;
     189             : 
     190          16 : template <typename T>
     191           8 : class RPCTypeName<std::vector<T>> {
     192          32 : public:
     193             :   static const char*getName() {
     194             :     std::lock_guard<std::mutex> Lock(NameMutex);
     195             :     if (Name.empty())
     196             :       raw_string_ostream(Name) << "std::vector<" << RPCTypeName<T>::getName()
     197             :                                << ">";
     198             :     return Name.data();
     199             :   }
     200             : 
     201             : private:
     202             :   static std::mutex NameMutex;
     203             :   static std::string Name;
     204             : };
     205             : 
     206             : template <typename T>
     207             : std::mutex RPCTypeName<std::vector<T>>::NameMutex;
     208             : template <typename T>
     209           8 : std::string RPCTypeName<std::vector<T>>::Name;
     210             : 
     211           8 : template <typename T> class RPCTypeName<std::set<T>> {
     212          16 : public:
     213           8 :   static const char *getName() {
     214           8 :     std::lock_guard<std::mutex> Lock(NameMutex);
     215             :     if (Name.empty())
     216             :       raw_string_ostream(Name)
     217             :           << "std::set<" << RPCTypeName<T>::getName() << ">";
     218             :     return Name.data();
     219           2 :   }
     220             : 
     221           2 : private:
     222             :   static std::mutex NameMutex;
     223           4 :   static std::string Name;
     224          26 : };
     225           2 : 
     226          24 : template <typename T> std::mutex RPCTypeName<std::set<T>>::NameMutex;
     227             : template <typename T> std::string RPCTypeName<std::set<T>>::Name;
     228          24 : 
     229          24 : template <typename K, typename V> class RPCTypeName<std::map<K, V>> {
     230             : public:
     231           0 :   static const char *getName() {
     232             :     std::lock_guard<std::mutex> Lock(NameMutex);
     233          72 :     if (Name.empty())
     234             :       raw_string_ostream(Name)
     235          72 :           << "std::map<" << RPCTypeNameSequence<K, V>() << ">";
     236           0 :     return Name.data();
     237          72 :   }
     238          72 : 
     239             : private:
     240          24 :   static std::mutex NameMutex;
     241             :   static std::string Name;
     242          24 : };
     243           0 : 
     244          24 : template <typename K, typename V>
     245          48 : std::mutex RPCTypeName<std::map<K, V>>::NameMutex;
     246             : template <typename K, typename V> std::string RPCTypeName<std::map<K, V>>::Name;
     247          48 : 
     248             : /// The SerializationTraits<ChannelT, T> class describes how to serialize and
     249          48 : /// deserialize an instance of type T to/from an abstract channel of type
     250          24 : /// ChannelT. It also provides a representation of the type's name via the
     251          24 : /// getName method.
     252          24 : ///
     253             : /// Specializations of this class should provide the following functions:
     254          24 : ///
     255             : ///   @code{.cpp}
     256          24 : ///
     257             : ///   static const char* getName();
     258          24 : ///   static Error serialize(ChannelT&, const T&);
     259          24 : ///   static Error deserialize(ChannelT&, T&);
     260             : ///
     261             : ///   @endcode
     262             : ///
     263             : /// The third argument of SerializationTraits is intended to support SFINAE.
     264             : /// E.g.:
     265             : ///
     266             : ///   @code{.cpp}
     267             : ///
     268             : ///   class MyVirtualChannel { ... };
     269             : ///
     270             : ///   template <DerivedChannelT>
     271             : ///   class SerializationTraits<DerivedChannelT, bool,
     272             : ///         typename std::enable_if<
     273             : ///           std::is_base_of<VirtChannel, DerivedChannel>::value
     274          48 : ///         >::type> {
     275             : ///   public:
     276          48 : ///     static const char* getName() { ... };
     277          96 : ///   }
     278          48 : ///
     279          48 : ///   @endcode
     280             : template <typename ChannelT, typename WireType,
     281          24 :           typename ConcreteType = WireType, typename = void>
     282           2 : class SerializationTraits;
     283          24 : 
     284          50 : template <typename ChannelT>
     285          28 : class SequenceTraits {
     286          26 : public:
     287           2 :   static Error emitSeparator(ChannelT &C) { return Error::success(); }
     288          24 :   static Error consumeSeparator(ChannelT &C) { return Error::success(); }
     289             : };
     290          24 : 
     291          48 : /// Utility class for serializing sequences of values of varying types.
     292          24 : /// Specializations of this class contain 'serialize' and 'deserialize' methods
     293          24 : /// for the given channel. The ArgTs... list will determine the "over-the-wire"
     294             : /// types to be serialized. The serialize and deserialize methods take a list
     295             : /// CArgTs... ("caller arg types") which must be the same length as ArgTs...,
     296             : /// but may be different types from ArgTs, provided that for each CArgT there
     297             : /// is a SerializationTraits specialization
     298             : /// SerializeTraits<ChannelT, ArgT, CArgT> with methods that can serialize the
     299             : /// caller argument to over-the-wire value.
     300             : template <typename ChannelT, typename... ArgTs>
     301             : class SequenceSerialization;
     302           2 : 
     303             : template <typename ChannelT>
     304           2 : class SequenceSerialization<ChannelT> {
     305             : public:
     306           2 :   static Error serialize(ChannelT &C) { return Error::success(); }
     307           2 :   static Error deserialize(ChannelT &C) { return Error::success(); }
     308             : };
     309             : 
     310             : template <typename ChannelT, typename ArgT>
     311             : class SequenceSerialization<ChannelT, ArgT> {
     312             : public:
     313             : 
     314             :   template <typename CArgT>
     315             :   static Error serialize(ChannelT &C, CArgT &&CArg) {
     316             :     return SerializationTraits<ChannelT, ArgT,
     317             :                                typename std::decay<CArgT>::type>::
     318             :              serialize(C, std::forward<CArgT>(CArg));
     319             :   }
     320           2 : 
     321             :   template <typename CArgT>
     322           2 :   static Error deserialize(ChannelT &C, CArgT &CArg) {
     323             :     return SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg);
     324           2 :   }
     325           2 : };
     326             : 
     327             : template <typename ChannelT, typename ArgT, typename... ArgTs>
     328             : class SequenceSerialization<ChannelT, ArgT, ArgTs...> {
     329             : public:
     330             : 
     331             :   template <typename CArgT, typename... CArgTs>
     332             :   static Error serialize(ChannelT &C, CArgT &&CArg,
     333             :                          CArgTs &&... CArgs) {
     334             :     if (auto Err =
     335             :         SerializationTraits<ChannelT, ArgT, typename std::decay<CArgT>::type>::
     336             :           serialize(C, std::forward<CArgT>(CArg)))
     337             :       return Err;
     338             :     if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
     339             :       return Err;
     340             :     return SequenceSerialization<ChannelT, ArgTs...>::
     341             :              serialize(C, std::forward<CArgTs>(CArgs)...);
     342             :   }
     343           0 : 
     344           0 :   template <typename CArgT, typename... CArgTs>
     345             :   static Error deserialize(ChannelT &C, CArgT &CArg,
     346             :                            CArgTs &... CArgs) {
     347             :     if (auto Err =
     348             :         SerializationTraits<ChannelT, ArgT, CArgT>::deserialize(C, CArg))
     349             :       return Err;
     350             :     if (auto Err = SequenceTraits<ChannelT>::consumeSeparator(C))
     351             :       return Err;
     352             :     return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, CArgs...);
     353             :   }
     354             : };
     355             : 
     356             : template <typename ChannelT, typename... ArgTs>
     357             : Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
     358             :   return SequenceSerialization<ChannelT, typename std::decay<ArgTs>::type...>::
     359           0 :            serialize(C, std::forward<ArgTs>(Args)...);
     360           0 : }
     361             : 
     362           0 : template <typename ChannelT, typename... ArgTs>
     363           0 : Error deserializeSeq(ChannelT &C, ArgTs &... Args) {
     364             :   return SequenceSerialization<ChannelT, ArgTs...>::deserialize(C, Args...);
     365             : }
     366             : 
     367             : template <typename ChannelT>
     368             : class SerializationTraits<ChannelT, Error> {
     369             : public:
     370             : 
     371           0 :   using WrappedErrorSerializer =
     372             :     std::function<Error(ChannelT &C, const ErrorInfoBase&)>;
     373             : 
     374         286 :   using WrappedErrorDeserializer =
     375             :     std::function<Error(ChannelT &C, Error &Err)>;
     376           0 : 
     377           0 :   template <typename ErrorInfoT, typename SerializeFtor,
     378           0 :             typename DeserializeFtor>
     379           0 :   static void registerErrorType(std::string Name, SerializeFtor Serialize,
     380             :                                 DeserializeFtor Deserialize) {
     381           0 :     assert(!Name.empty() &&
     382           0 :            "The empty string is reserved for the Success value");
     383           0 : 
     384           0 :     const std::string *KeyName = nullptr;
     385             :     {
     386           0 :       // We're abusing the stability of std::map here: We take a reference to the
     387           0 :       // key of the deserializers map to save us from duplicating the string in
     388             :       // the serializer. This should be changed to use a stringpool if we switch
     389           0 :       // to a map type that may move keys in memory.
     390        1353 :       std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
     391           0 :       auto I =
     392           0 :         Deserializers.insert(Deserializers.begin(),
     393             :                              std::make_pair(std::move(Name),
     394           0 :                                             std::move(Deserialize)));
     395           0 :       KeyName = &I->first;
     396           0 :     }
     397           0 : 
     398             :     {
     399           0 :       assert(KeyName != nullptr && "No keyname pointer");
     400           0 :       std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
     401           0 :       // FIXME: Move capture Serialize once we have C++14.
     402           0 :       Serializers[ErrorInfoT::classID()] =
     403             :           [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
     404           0 :         assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
     405           0 :                "Serializer called for wrong error type");
     406           0 :         if (auto Err = serializeSeq(C, *KeyName))
     407          61 :           return Err;
     408             :         return Serialize(C, static_cast<const ErrorInfoT &>(EIB));
     409           0 :       };
     410           0 :     }
     411             :   }
     412           0 : 
     413         574 :   static Error serialize(ChannelT &C, Error &&Err) {
     414         169 :     std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
     415           0 : 
     416             :     if (!Err)
     417           0 :       return serializeSeq(C, std::string());
     418           0 : 
     419           0 :     return handleErrors(std::move(Err),
     420         574 :                         [&C](const ErrorInfoBase &EIB) {
     421             :                           auto SI = Serializers.find(EIB.dynamicClassID());
     422           0 :                           if (SI == Serializers.end())
     423         184 :                             return serializeAsStringError(C, EIB);
     424           0 :                           return (SI->second)(C, EIB);
     425         189 :                         });
     426             :   }
     427           0 : 
     428           0 :   static Error deserialize(ChannelT &C, Error &Err) {
     429         763 :     std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
     430           0 : 
     431         763 :     std::string Key;
     432         184 :     if (auto Err = deserializeSeq(C, Key))
     433           0 :       return Err;
     434           3 : 
     435           0 :     if (Key.empty()) {
     436           3 :       ErrorAsOutParameter EAO(&Err);
     437           0 :       Err = Error::success();
     438         763 :       return Error::success();
     439           0 :     }
     440         526 : 
     441             :     auto DI = Deserializers.find(Key);
     442         526 :     assert(DI != Deserializers.end() && "No deserializer for error type");
     443         999 :     return (DI->second)(C, Err);
     444           0 :   }
     445           0 : 
     446             : private:
     447           0 : 
     448             :   static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
     449         526 :     std::string ErrMsg;
     450             :     {
     451         116 :       raw_string_ostream ErrMsgStream(ErrMsg);
     452         622 :       EIB.log(ErrMsgStream);
     453         116 :     }
     454         622 :     return serialize(C, make_error<StringError>(std::move(ErrMsg),
     455             :                                                 inconvertibleErrorCode()));
     456           2 :   }
     457           0 : 
     458           2 :   static std::recursive_mutex SerializersMutex;
     459           0 :   static std::recursive_mutex DeserializersMutex;
     460         116 :   static std::map<const void*, WrappedErrorSerializer> Serializers;
     461         622 :   static std::map<std::string, WrappedErrorDeserializer> Deserializers;
     462           0 : };
     463          24 : 
     464           0 : template <typename ChannelT>
     465          26 : std::recursive_mutex SerializationTraits<ChannelT, Error>::SerializersMutex;
     466           0 : 
     467         109 : template <typename ChannelT>
     468             : std::recursive_mutex SerializationTraits<ChannelT, Error>::DeserializersMutex;
     469          10 : 
     470           0 : template <typename ChannelT>
     471           0 : std::map<const void*,
     472          24 :          typename SerializationTraits<ChannelT, Error>::WrappedErrorSerializer>
     473         121 : SerializationTraits<ChannelT, Error>::Serializers;
     474          24 : 
     475         121 : template <typename ChannelT>
     476          29 : std::map<std::string,
     477             :          typename SerializationTraits<ChannelT, Error>::WrappedErrorDeserializer>
     478         174 : SerializationTraits<ChannelT, Error>::Deserializers;
     479             : 
     480         174 : /// Registers a serializer and deserializer for the given error type on the
     481             : /// given channel type.
     482         133 : template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
     483          24 :           typename DeserializeFtor>
     484          16 : void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
     485          24 :                                 DeserializeFtor &&Deserialize) {
     486         622 :   SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
     487         198 :     std::move(Name),
     488        1244 :     std::forward<SerializeFtor>(Serialize),
     489             :     std::forward<DeserializeFtor>(Deserialize));
     490             : }
     491         123 : 
     492             : /// Registers serialization/deserialization for StringError.
     493         297 : template <typename ChannelT>
     494          24 : void registerStringError() {
     495          26 :   static bool AlreadyRegistered = false;
     496           0 :   if (!AlreadyRegistered) {
     497          48 :     registerErrorSerialization<ChannelT, StringError>(
     498           2 :       "StringError",
     499             :       [](ChannelT &C, const StringError &SE) {
     500           3 :         return serializeSeq(C, SE.getMessage());
     501             :       },
     502          30 :       [](ChannelT &C, Error &Err) -> Error {
     503             :         ErrorAsOutParameter EAO(&Err);
     504          25 :         std::string Msg;
     505           0 :         if (auto E2 = deserializeSeq(C, Msg))
     506          50 :           return E2;
     507           0 :         Err =
     508             :           make_error<StringError>(std::move(Msg),
     509           2 :                                   orcError(
     510             :                                     OrcErrorCode::UnknownErrorCodeFromRemote));
     511          28 :         return Error::success();
     512             :       });
     513          25 :     AlreadyRegistered = true;
     514             :   }
     515          49 : }
     516           2 : 
     517           2 : /// SerializationTraits for Expected<T1> from an Expected<T2>.
     518         555 : template <typename ChannelT, typename T1, typename T2>
     519             : class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
     520         584 : public:
     521             : 
     522           0 :   static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
     523             :     if (ValOrErr) {
     524           1 :       if (auto Err = serializeSeq(C, true))
     525             :         return Err;
     526           1 :       return SerializationTraits<ChannelT, T1, T2>::serialize(C, *ValOrErr);
     527         550 :     }
     528           2 :     if (auto Err = serializeSeq(C, false))
     529           0 :       return Err;
     530             :     return serializeSeq(C, ValOrErr.takeError());
     531         763 :   }
     532             : 
     533        1526 :   static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
     534             :     ExpectedAsOutParameter<T2> EAO(&ValOrErr);
     535           1 :     bool HasValue;
     536         102 :     if (auto Err = deserializeSeq(C, HasValue))
     537           1 :       return Err;
     538         320 :     if (HasValue)
     539           1 :       return SerializationTraits<ChannelT, T1, T2>::deserialize(C, *ValOrErr);
     540         671 :     Error Err = Error::success();
     541             :     if (auto E2 = deserializeSeq(C, Err))
     542        1342 :       return E2;
     543             :     ValOrErr = std::move(Err);
     544             :     return Error::success();
     545             :   }
     546           1 : };
     547             : 
     548           1 : /// SerializationTraits for Expected<T1> from a T2.
     549         116 : template <typename ChannelT, typename T1, typename T2>
     550         178 : class SerializationTraits<ChannelT, Expected<T1>, T2> {
     551         232 : public:
     552           0 : 
     553             :   static Error serialize(ChannelT &C, T2 &&Val) {
     554         526 :     return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
     555             :   }
     556         116 : };
     557           1 : 
     558           0 : /// SerializationTraits for Expected<T1> from an Error.
     559         551 : template <typename ChannelT, typename T>
     560           0 : class SerializationTraits<ChannelT, Expected<T>, Error> {
     561           1 : public:
     562             : 
     563         105 :   static Error serialize(ChannelT &C, Error &&Err) {
     564             :     return serializeSeq(C, Expected<T>(std::move(Err)));
     565             :   }
     566             : };
     567           0 : 
     568           1 : /// SerializationTraits default specialization for std::pair.
     569           0 : template <typename ChannelT, typename T1, typename T2, typename T3, typename T4>
     570           1 : class SerializationTraits<ChannelT, std::pair<T1, T2>, std::pair<T3, T4>> {
     571             : public:
     572           1 :   static Error serialize(ChannelT &C, const std::pair<T3, T4> &V) {
     573             :     if (auto Err = SerializationTraits<ChannelT, T1, T3>::serialize(C, V.first))
     574             :       return Err;
     575             :     return SerializationTraits<ChannelT, T2, T4>::serialize(C, V.second);
     576         526 :   }
     577             : 
     578        1060 :   static Error deserialize(ChannelT &C, std::pair<T3, T4> &V) {
     579           1 :     if (auto Err =
     580             :             SerializationTraits<ChannelT, T1, T3>::deserialize(C, V.first))
     581           1 :       return Err;
     582             :     return SerializationTraits<ChannelT, T2, T4>::deserialize(C, V.second);
     583           1 :   }
     584             : };
     585             : 
     586             : /// SerializationTraits default specialization for std::tuple.
     587             : template <typename ChannelT, typename... ArgTs>
     588           0 : class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
     589             : public:
     590         559 : 
     591             :   /// RPC channel serialization for std::tuple.
     592           1 :   static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
     593             :     return serializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
     594           9 :   }
     595             : 
     596           0 :   /// RPC channel deserialization for std::tuple.
     597             :   static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
     598           0 :     return deserializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
     599             :   }
     600             : 
     601           9 : private:
     602             :   // Serialization helper for std::tuple.
     603         527 :   template <size_t... Is>
     604             :   static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
     605           1 :                                     llvm::index_sequence<Is...> _) {
     606             :     return serializeSeq(C, std::get<Is>(V)...);
     607             :   }
     608             : 
     609             :   // Serialization helper for std::tuple.
     610           8 :   template <size_t... Is>
     611             :   static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
     612          12 :                                       llvm::index_sequence<Is...> _) {
     613             :     return deserializeSeq(C, std::get<Is>(V)...);
     614           0 :   }
     615          11 : };
     616           2 : 
     617             : /// SerializationTraits default specialization for std::vector.
     618             : template <typename ChannelT, typename T>
     619             : class SerializationTraits<ChannelT, std::vector<T>> {
     620             : public:
     621             : 
     622             :   /// Serialize a std::vector<T> from std::vector<T>.
     623           0 :   static Error serialize(ChannelT &C, const std::vector<T> &V) {
     624          27 :     if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
     625           1 :       return Err;
     626             : 
     627           8 :     for (const auto &E : V)
     628             :       if (auto Err = serializeSeq(C, E))
     629             :         return Err;
     630             : 
     631           7 :     return Error::success();
     632             :   }
     633             : 
     634           8 :   /// Deserialize a std::vector<T> to a std::vector<T>.
     635             :   static Error deserialize(ChannelT &C, std::vector<T> &V) {
     636             :     assert(V.empty() &&
     637             :            "Expected default-constructed vector to deserialize into");
     638          84 : 
     639             :     uint64_t Count = 0;
     640         168 :     if (auto Err = deserializeSeq(C, Count))
     641             :       return Err;
     642             : 
     643             :     V.resize(Count);
     644             :     for (auto &E : V)
     645          11 :       if (auto Err = deserializeSeq(C, E))
     646             :         return Err;
     647           5 : 
     648             :     return Error::success();
     649           2 :   }
     650           4 : };
     651           4 : 
     652             : template <typename ChannelT, typename T, typename T2>
     653             : class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
     654          12 : public:
     655             :   /// Serialize a std::set<T> from std::set<T2>.
     656           1 :   static Error serialize(ChannelT &C, const std::set<T2> &S) {
     657             :     if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
     658           2 :       return Err;
     659             : 
     660             :     for (const auto &E : S)
     661             :       if (auto Err = SerializationTraits<ChannelT, T, T2>::serialize(C, E))
     662             :         return Err;
     663           1 : 
     664             :     return Error::success();
     665           1 :   }
     666             : 
     667           2 :   /// Deserialize a std::set<T> to a std::set<T>.
     668             :   static Error deserialize(ChannelT &C, std::set<T2> &S) {
     669             :     assert(S.empty() && "Expected default-constructed set to deserialize into");
     670             : 
     671             :     uint64_t Count = 0;
     672           1 :     if (auto Err = deserializeSeq(C, Count))
     673             :       return Err;
     674           1 : 
     675             :     while (Count-- != 0) {
     676           2 :       T2 Val;
     677             :       if (auto Err = SerializationTraits<ChannelT, T, T2>::deserialize(C, Val))
     678             :         return Err;
     679             : 
     680             :       auto Added = S.insert(Val).second;
     681           1 :       if (!Added)
     682             :         return make_error<StringError>("Duplicate element in deserialized set",
     683           1 :                                        orcError(OrcErrorCode::UnknownORCError));
     684             :     }
     685           2 : 
     686             :     return Error::success();
     687             :   }
     688             : };
     689           0 : 
     690           1 : template <typename ChannelT, typename K, typename V, typename K2, typename V2>
     691             : class SerializationTraits<ChannelT, std::map<K, V>, std::map<K2, V2>> {
     692           1 : public:
     693           8 :   /// Serialize a std::map<K, V> from std::map<K2, V2>.
     694           2 :   static Error serialize(ChannelT &C, const std::map<K2, V2> &M) {
     695           8 :     if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
     696           8 :       return Err;
     697             : 
     698             :     for (const auto &E : M) {
     699           1 :       if (auto Err =
     700             :               SerializationTraits<ChannelT, K, K2>::serialize(C, E.first))
     701           1 :         return Err;
     702             :       if (auto Err =
     703           2 :               SerializationTraits<ChannelT, V, V2>::serialize(C, E.second))
     704             :         return Err;
     705             :     }
     706             : 
     707             :     return Error::success();
     708           1 :   }
     709             : 
     710           1 :   /// Deserialize a std::map<K, V> to a std::map<K, V>.
     711             :   static Error deserialize(ChannelT &C, std::map<K2, V2> &M) {
     712          10 :     assert(M.empty() && "Expected default-constructed map to deserialize into");
     713             : 
     714           8 :     uint64_t Count = 0;
     715             :     if (auto Err = deserializeSeq(C, Count))
     716             :       return Err;
     717           1 : 
     718             :     while (Count-- != 0) {
     719           1 :       std::pair<K2, V2> Val;
     720             :       if (auto Err =
     721          17 :               SerializationTraits<ChannelT, K, K2>::deserialize(C, Val.first))
     722          15 :         return Err;
     723          12 : 
     724             :       if (auto Err =
     725          12 :               SerializationTraits<ChannelT, V, V2>::deserialize(C, Val.second))
     726           1 :         return Err;
     727           3 : 
     728           1 :       auto Added = M.insert(Val).second;
     729           3 :       if (!Added)
     730           2 :         return make_error<StringError>("Duplicate element in deserialized map",
     731          10 :                                        orcError(OrcErrorCode::UnknownORCError));
     732          10 :     }
     733           9 : 
     734             :     return Error::success();
     735          10 :   }
     736             : };
     737           2 : 
     738             : } // end namespace rpc
     739           3 : } // end namespace orc
     740             : } // end namespace llvm
     741           5 : 
     742           5 : #endif // LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H

Generated by: LCOV version 1.13