LLVM  8.0.0svn
RPCSerialization.h
Go to the documentation of this file.
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>
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 OStream &operator<<(OStream &OS, const RPCTypeNameSequence<> &V) {
36  return OS;
37 }
38 
39 /// Render a TypeNameSequence of a single type to an ostream.
40 template <typename OStream, typename ArgT>
41 OStream &operator<<(OStream &OS, const RPCTypeNameSequence<ArgT> &V) {
43  return OS;
44 }
45 
46 /// Render a TypeNameSequence of more than one type to an ostream.
47 template <typename OStream, typename ArgT1, typename ArgT2, typename... ArgTs>
48 OStream&
52  return OS;
53 }
54 
55 template <>
56 class RPCTypeName<void> {
57 public:
58  static const char* getName() { return "void"; }
59 };
60 
61 template <>
62 class RPCTypeName<int8_t> {
63 public:
64  static const char* getName() { return "int8_t"; }
65 };
66 
67 template <>
68 class RPCTypeName<uint8_t> {
69 public:
70  static const char* getName() { return "uint8_t"; }
71 };
72 
73 template <>
74 class RPCTypeName<int16_t> {
75 public:
76  static const char* getName() { return "int16_t"; }
77 };
78 
79 template <>
80 class RPCTypeName<uint16_t> {
81 public:
82  static const char* getName() { return "uint16_t"; }
83 };
84 
85 template <>
86 class RPCTypeName<int32_t> {
87 public:
88  static const char* getName() { return "int32_t"; }
89 };
90 
91 template <>
93 public:
94  static const char* getName() { return "uint32_t"; }
95 };
96 
97 template <>
98 class RPCTypeName<int64_t> {
99 public:
100  static const char* getName() { return "int64_t"; }
101 };
102 
103 template <>
104 class RPCTypeName<uint64_t> {
105 public:
106  static const char* getName() { return "uint64_t"; }
107 };
108 
109 template <>
111 public:
112  static const char* getName() { return "bool"; }
113 };
114 
115 template <>
116 class RPCTypeName<std::string> {
117 public:
118  static const char* getName() { return "std::string"; }
119 };
120 
121 template <>
123 public:
124  static const char* getName() { return "Error"; }
125 };
126 
127 template <typename T>
129 public:
130  static const char* getName() {
131  std::lock_guard<std::mutex> Lock(NameMutex);
132  if (Name.empty())
133  raw_string_ostream(Name) << "Expected<"
135  << ">";
136  return Name.data();
137  }
138 
139 private:
140  static std::mutex NameMutex;
141  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())
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>
169 
170 template <typename... ArgTs>
171 class RPCTypeName<std::tuple<ArgTs...>> {
172 public:
173  static const char* getName() {
174  std::lock_guard<std::mutex> Lock(NameMutex);
175  if (Name.empty())
176  raw_string_ostream(Name) << "std::tuple<"
177  << RPCTypeNameSequence<ArgTs...>() << ">";
178  return Name.data();
179  }
180 private:
181  static std::mutex NameMutex;
182  static std::string Name;
183 };
184 
185 template <typename... ArgTs>
186 std::mutex RPCTypeName<std::tuple<ArgTs...>>::NameMutex;
187 template <typename... ArgTs>
188 std::string RPCTypeName<std::tuple<ArgTs...>>::Name;
189 
190 template <typename T>
191 class RPCTypeName<std::vector<T>> {
192 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>
210 
211 template <typename T> class RPCTypeName<std::set<T>> {
212 public:
213  static const char *getName() {
214  std::lock_guard<std::mutex> Lock(NameMutex);
215  if (Name.empty())
217  << "std::set<" << RPCTypeName<T>::getName() << ">";
218  return Name.data();
219  }
220 
221 private:
222  static std::mutex NameMutex;
223  static std::string Name;
224 };
225 
226 template <typename T> std::mutex RPCTypeName<std::set<T>>::NameMutex;
227 template <typename T> std::string RPCTypeName<std::set<T>>::Name;
228 
229 template <typename K, typename V> class RPCTypeName<std::map<K, V>> {
230 public:
231  static const char *getName() {
232  std::lock_guard<std::mutex> Lock(NameMutex);
233  if (Name.empty())
235  << "std::map<" << RPCTypeNameSequence<K, V>() << ">";
236  return Name.data();
237  }
238 
239 private:
240  static std::mutex NameMutex;
241  static std::string Name;
242 };
243 
244 template <typename K, typename V>
245 std::mutex RPCTypeName<std::map<K, V>>::NameMutex;
246 template <typename K, typename V> std::string RPCTypeName<std::map<K, V>>::Name;
247 
248 /// The SerializationTraits<ChannelT, T> class describes how to serialize and
249 /// deserialize an instance of type T to/from an abstract channel of type
250 /// ChannelT. It also provides a representation of the type's name via the
251 /// getName method.
252 ///
253 /// Specializations of this class should provide the following functions:
254 ///
255 /// @code{.cpp}
256 ///
257 /// static const char* getName();
258 /// static Error serialize(ChannelT&, const T&);
259 /// 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 /// >::type> {
275 /// public:
276 /// static const char* getName() { ... };
277 /// }
278 ///
279 /// @endcode
280 template <typename ChannelT, typename WireType,
281  typename ConcreteType = WireType, typename = void>
283 
284 template <typename ChannelT>
286 public:
287  static Error emitSeparator(ChannelT &C) { return Error::success(); }
288  static Error consumeSeparator(ChannelT &C) { return Error::success(); }
289 };
290 
291 /// Utility class for serializing sequences of values of varying types.
292 /// Specializations of this class contain 'serialize' and 'deserialize' methods
293 /// 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>
302 
303 template <typename ChannelT>
304 class SequenceSerialization<ChannelT> {
305 public:
306  static Error serialize(ChannelT &C) { return Error::success(); }
307  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 
321  template <typename CArgT>
322  static Error deserialize(ChannelT &C, CArgT &CArg) {
324  }
325 };
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;
341  serialize(C, std::forward<CArgTs>(CArgs)...);
342  }
343 
344  template <typename CArgT, typename... CArgTs>
345  static Error deserialize(ChannelT &C, CArgT &CArg,
346  CArgTs &... CArgs) {
347  if (auto Err =
349  return Err;
351  return Err;
353  }
354 };
355 
356 template <typename ChannelT, typename... ArgTs>
357 Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
359  serialize(C, std::forward<ArgTs>(Args)...);
360 }
361 
362 template <typename ChannelT, typename... ArgTs>
363 Error deserializeSeq(ChannelT &C, ArgTs &... Args) {
365 }
366 
367 template <typename ChannelT>
368 class SerializationTraits<ChannelT, Error> {
369 public:
370 
371  using WrappedErrorSerializer =
372  std::function<Error(ChannelT &C, const ErrorInfoBase&)>;
373 
375  std::function<Error(ChannelT &C, Error &Err)>;
376 
377  template <typename ErrorInfoT, typename SerializeFtor,
378  typename DeserializeFtor>
379  static void registerErrorType(std::string Name, SerializeFtor Serialize,
380  DeserializeFtor Deserialize) {
381  assert(!Name.empty() &&
382  "The empty string is reserved for the Success value");
383 
384  const std::string *KeyName = nullptr;
385  {
386  // We're abusing the stability of std::map here: We take a reference to the
387  // 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  // to a map type that may move keys in memory.
390  std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
391  auto I =
392  Deserializers.insert(Deserializers.begin(),
393  std::make_pair(std::move(Name),
394  std::move(Deserialize)));
395  KeyName = &I->first;
396  }
397 
398  {
399  assert(KeyName != nullptr && "No keyname pointer");
400  std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
401  // FIXME: Move capture Serialize once we have C++14.
402  Serializers[ErrorInfoT::classID()] =
403  [KeyName, Serialize](ChannelT &C, const ErrorInfoBase &EIB) -> Error {
404  assert(EIB.dynamicClassID() == ErrorInfoT::classID() &&
405  "Serializer called for wrong error type");
406  if (auto Err = serializeSeq(C, *KeyName))
407  return Err;
408  return Serialize(C, static_cast<const ErrorInfoT &>(EIB));
409  };
410  }
411  }
412 
413  static Error serialize(ChannelT &C, Error &&Err) {
414  std::lock_guard<std::recursive_mutex> Lock(SerializersMutex);
415 
416  if (!Err)
417  return serializeSeq(C, std::string());
418 
419  return handleErrors(std::move(Err),
420  [&C](const ErrorInfoBase &EIB) {
421  auto SI = Serializers.find(EIB.dynamicClassID());
422  if (SI == Serializers.end())
423  return serializeAsStringError(C, EIB);
424  return (SI->second)(C, EIB);
425  });
426  }
427 
428  static Error deserialize(ChannelT &C, Error &Err) {
429  std::lock_guard<std::recursive_mutex> Lock(DeserializersMutex);
430 
431  std::string Key;
432  if (auto Err = deserializeSeq(C, Key))
433  return Err;
434 
435  if (Key.empty()) {
436  ErrorAsOutParameter EAO(&Err);
437  Err = Error::success();
438  return Error::success();
439  }
440 
441  auto DI = Deserializers.find(Key);
442  assert(DI != Deserializers.end() && "No deserializer for error type");
443  return (DI->second)(C, Err);
444  }
445 
446 private:
447 
448  static Error serializeAsStringError(ChannelT &C, const ErrorInfoBase &EIB) {
449  std::string ErrMsg;
450  {
451  raw_string_ostream ErrMsgStream(ErrMsg);
452  EIB.log(ErrMsgStream);
453  }
454  return serialize(C, make_error<StringError>(std::move(ErrMsg),
456  }
457 
458  static std::recursive_mutex SerializersMutex;
459  static std::recursive_mutex DeserializersMutex;
460  static std::map<const void*, WrappedErrorSerializer> Serializers;
461  static std::map<std::string, WrappedErrorDeserializer> Deserializers;
462 };
463 
464 template <typename ChannelT>
466 
467 template <typename ChannelT>
469 
470 template <typename ChannelT>
471 std::map<const void*,
474 
475 template <typename ChannelT>
476 std::map<std::string,
479 
480 /// Registers a serializer and deserializer for the given error type on the
481 /// given channel type.
482 template <typename ChannelT, typename ErrorInfoT, typename SerializeFtor,
483  typename DeserializeFtor>
484 void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize,
485  DeserializeFtor &&Deserialize) {
486  SerializationTraits<ChannelT, Error>::template registerErrorType<ErrorInfoT>(
487  std::move(Name),
488  std::forward<SerializeFtor>(Serialize),
489  std::forward<DeserializeFtor>(Deserialize));
490 }
491 
492 /// Registers serialization/deserialization for StringError.
493 template <typename ChannelT>
495  static bool AlreadyRegistered = false;
496  if (!AlreadyRegistered) {
497  registerErrorSerialization<ChannelT, StringError>(
498  "StringError",
499  [](ChannelT &C, const StringError &SE) {
500  return serializeSeq(C, SE.getMessage());
501  },
502  [](ChannelT &C, Error &Err) -> Error {
503  ErrorAsOutParameter EAO(&Err);
504  std::string Msg;
505  if (auto E2 = deserializeSeq(C, Msg))
506  return E2;
507  Err =
508  make_error<StringError>(std::move(Msg),
509  orcError(
511  return Error::success();
512  });
513  AlreadyRegistered = true;
514  }
515 }
516 
517 /// SerializationTraits for Expected<T1> from an Expected<T2>.
518 template <typename ChannelT, typename T1, typename T2>
519 class SerializationTraits<ChannelT, Expected<T1>, Expected<T2>> {
520 public:
521 
522  static Error serialize(ChannelT &C, Expected<T2> &&ValOrErr) {
523  if (ValOrErr) {
524  if (auto Err = serializeSeq(C, true))
525  return Err;
527  }
528  if (auto Err = serializeSeq(C, false))
529  return Err;
530  return serializeSeq(C, ValOrErr.takeError());
531  }
532 
533  static Error deserialize(ChannelT &C, Expected<T2> &ValOrErr) {
534  ExpectedAsOutParameter<T2> EAO(&ValOrErr);
535  bool HasValue;
536  if (auto Err = deserializeSeq(C, HasValue))
537  return Err;
538  if (HasValue)
540  Error Err = Error::success();
541  if (auto E2 = deserializeSeq(C, Err))
542  return E2;
543  ValOrErr = std::move(Err);
544  return Error::success();
545  }
546 };
547 
548 /// SerializationTraits for Expected<T1> from a T2.
549 template <typename ChannelT, typename T1, typename T2>
550 class SerializationTraits<ChannelT, Expected<T1>, T2> {
551 public:
552 
553  static Error serialize(ChannelT &C, T2 &&Val) {
554  return serializeSeq(C, Expected<T2>(std::forward<T2>(Val)));
555  }
556 };
557 
558 /// SerializationTraits for Expected<T1> from an Error.
559 template <typename ChannelT, typename T>
560 class SerializationTraits<ChannelT, Expected<T>, Error> {
561 public:
562 
563  static Error serialize(ChannelT &C, Error &&Err) {
564  return serializeSeq(C, Expected<T>(std::move(Err)));
565  }
566 };
567 
568 /// SerializationTraits default specialization for std::pair.
569 template <typename ChannelT, typename T1, typename T2, typename T3, typename T4>
570 class SerializationTraits<ChannelT, std::pair<T1, T2>, std::pair<T3, T4>> {
571 public:
572  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;
576  }
577 
578  static Error deserialize(ChannelT &C, std::pair<T3, T4> &V) {
579  if (auto Err =
581  return Err;
583  }
584 };
585 
586 /// SerializationTraits default specialization for std::tuple.
587 template <typename ChannelT, typename... ArgTs>
588 class SerializationTraits<ChannelT, std::tuple<ArgTs...>> {
589 public:
590 
591  /// RPC channel serialization for std::tuple.
592  static Error serialize(ChannelT &C, const std::tuple<ArgTs...> &V) {
593  return serializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
594  }
595 
596  /// RPC channel deserialization for std::tuple.
597  static Error deserialize(ChannelT &C, std::tuple<ArgTs...> &V) {
598  return deserializeTupleHelper(C, V, llvm::index_sequence_for<ArgTs...>());
599  }
600 
601 private:
602  // Serialization helper for std::tuple.
603  template <size_t... Is>
604  static Error serializeTupleHelper(ChannelT &C, const std::tuple<ArgTs...> &V,
606  return serializeSeq(C, std::get<Is>(V)...);
607  }
608 
609  // Serialization helper for std::tuple.
610  template <size_t... Is>
611  static Error deserializeTupleHelper(ChannelT &C, std::tuple<ArgTs...> &V,
613  return deserializeSeq(C, std::get<Is>(V)...);
614  }
615 };
616 
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  static Error serialize(ChannelT &C, const std::vector<T> &V) {
624  if (auto Err = serializeSeq(C, static_cast<uint64_t>(V.size())))
625  return Err;
626 
627  for (const auto &E : V)
628  if (auto Err = serializeSeq(C, E))
629  return Err;
630 
631  return Error::success();
632  }
633 
634  /// 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 
639  uint64_t Count = 0;
640  if (auto Err = deserializeSeq(C, Count))
641  return Err;
642 
643  V.resize(Count);
644  for (auto &E : V)
645  if (auto Err = deserializeSeq(C, E))
646  return Err;
647 
648  return Error::success();
649  }
650 };
651 
652 template <typename ChannelT, typename T, typename T2>
653 class SerializationTraits<ChannelT, std::set<T>, std::set<T2>> {
654 public:
655  /// Serialize a std::set<T> from std::set<T2>.
656  static Error serialize(ChannelT &C, const std::set<T2> &S) {
657  if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
658  return Err;
659 
660  for (const auto &E : S)
662  return Err;
663 
664  return Error::success();
665  }
666 
667  /// 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  if (auto Err = deserializeSeq(C, Count))
673  return Err;
674 
675  while (Count-- != 0) {
676  T2 Val;
678  return Err;
679 
680  auto Added = S.insert(Val).second;
681  if (!Added)
682  return make_error<StringError>("Duplicate element in deserialized set",
684  }
685 
686  return Error::success();
687  }
688 };
689 
690 template <typename ChannelT, typename K, typename V, typename K2, typename V2>
691 class SerializationTraits<ChannelT, std::map<K, V>, std::map<K2, V2>> {
692 public:
693  /// Serialize a std::map<K, V> from std::map<K2, V2>.
694  static Error serialize(ChannelT &C, const std::map<K2, V2> &M) {
695  if (auto Err = serializeSeq(C, static_cast<uint64_t>(M.size())))
696  return Err;
697 
698  for (const auto &E : M) {
699  if (auto Err =
701  return Err;
702  if (auto Err =
704  return Err;
705  }
706 
707  return Error::success();
708  }
709 
710  /// Deserialize a std::map<K, V> to a std::map<K, V>.
711  static Error deserialize(ChannelT &C, std::map<K2, V2> &M) {
712  assert(M.empty() && "Expected default-constructed map to deserialize into");
713 
714  uint64_t Count = 0;
715  if (auto Err = deserializeSeq(C, Count))
716  return Err;
717 
718  while (Count-- != 0) {
719  std::pair<K2, V2> Val;
720  if (auto Err =
722  return Err;
723 
724  if (auto Err =
726  return Err;
727 
728  auto Added = M.insert(Val).second;
729  if (!Added)
730  return make_error<StringError>("Duplicate element in deserialized map",
732  }
733 
734  return Error::success();
735  }
736 };
737 
738 } // end namespace rpc
739 } // end namespace orc
740 } // end namespace llvm
741 
742 #endif // LLVM_EXECUTIONENGINE_ORC_RPCSERIALIZATION_H
uint64_t CallInst * C
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
static Error deserialize(ChannelT &C, std::vector< T > &V)
Deserialize a std::vector<T> to a std::vector<T>.
Helper for Expected<T>s used as out-parameters.
Definition: Error.h:1040
detail::ValueMatchesPoly< M > HasValue(M Matcher)
Definition: Error.h:159
static sys::Mutex Lock
Base class for error info classes.
Definition: Error.h:49
std::function< Error(ChannelT &C, Error &Err)> WrappedErrorDeserializer
Definition: BitVector.h:938
std::error_code orcError(OrcErrorCode ErrCode)
Definition: OrcError.cpp:77
virtual void log(raw_ostream &OS) const =0
Print an error message to an output stream.
static StringRef getName(Value *V)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
Alias for the common case of a sequence of size_ts.
Definition: STLExtras.h:509
Error serializeSeq(ChannelT &C, ArgTs &&... Args)
Key
PAL metadata keys.
static Error serialize(ChannelT &C, CArgT &&CArg, CArgTs &&... CArgs)
static Error emitSeparator(ChannelT &C)
void registerStringError()
Registers serialization/deserialization for StringError.
virtual const void * dynamicClassID() const =0
void registerErrorSerialization(std::string Name, SerializeFtor &&Serialize, DeserializeFtor &&Deserialize)
Registers a serializer and deserializer for the given error type on the given channel type...
static Error serialize(ChannelT &C, const std::map< K2, V2 > &M)
Serialize a std::map<K, V> from std::map<K2, V2>.
The SerializationTraits<ChannelT, T> class describes how to serialize and deserialize an instance of ...
static Error deserialize(ChannelT &C, std::tuple< ArgTs... > &V)
RPC channel deserialization for std::tuple.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Error deserialize(ChannelT &C, std::set< T2 > &S)
Deserialize a std::set<T> to a std::set<T>.
static Error deserialize(ChannelT &C, std::map< K2, V2 > &M)
Deserialize a std::map<K, V> to a std::map<K, V>.
static Error serialize(ChannelT &C, const std::set< T2 > &S)
Serialize a std::set<T> from std::set<T2>.
OStream & operator<<(OStream &OS, const RPCTypeNameSequence<> &V)
Render an empty TypeNameSequence to an ostream.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
static void registerErrorType(std::string Name, SerializeFtor Serialize, DeserializeFtor Deserialize)
Creates a compile-time integer sequence for a parameter pack.
Definition: STLExtras.h:511
Helper for Errors used as out-parameters.
Definition: Error.h:1018
static Error deserialize(ChannelT &C, Error &Err)
This class wraps a string in an Error.
Definition: Error.h:1135
#define I(x, y, z)
Definition: MD5.cpp:58
Error deserializeSeq(ChannelT &C, ArgTs &... Args)
static Error serialize(ChannelT &C, const std::vector< T > &V)
Serialize a std::vector<T> from std::vector<T>.
TypeNameSequence is a utility for rendering sequences of types to a string by rendering each type...
std::function< Error(ChannelT &C, const ErrorInfoBase &)> WrappedErrorSerializer
static Error serialize(ChannelT &C, Error &&Err)
Utility class for serializing sequences of values of varying types.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static Error deserialize(ChannelT &C, CArgT &CArg, CArgTs &... CArgs)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
static Error deserialize(ChannelT &C, CArgT &CArg)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
static Error serialize(ChannelT &C, CArgT &&CArg)
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:882
static Error serialize(ChannelT &C, const std::tuple< ArgTs... > &V)
RPC channel serialization for std::tuple.
#define _
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
#define T1
static Error consumeSeparator(ChannelT &C)
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77