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