LLVM  4.0.0
YAMLTraits.h
Go to the documentation of this file.
1 //===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
2 //
3 // The LLVM Linker
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_SUPPORT_YAMLTRAITS_H
11 #define LLVM_SUPPORT_YAMLTRAITS_H
12 
13 #include "llvm/ADT/Optional.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringMap.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/Twine.h"
18 #include "llvm/Support/AlignOf.h"
19 #include "llvm/Support/Allocator.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/Regex.h"
22 #include "llvm/Support/SourceMgr.h"
25 #include <cassert>
26 #include <cctype>
27 #include <cstddef>
28 #include <cstdint>
29 #include <memory>
30 #include <new>
31 #include <string>
32 #include <system_error>
33 #include <type_traits>
34 #include <vector>
35 
36 namespace llvm {
37 namespace yaml {
38 
39 struct EmptyContext {};
40 
41 /// This class should be specialized by any type that needs to be converted
42 /// to/from a YAML mapping. For example:
43 ///
44 /// struct MappingTraits<MyStruct> {
45 /// static void mapping(IO &io, MyStruct &s) {
46 /// io.mapRequired("name", s.name);
47 /// io.mapRequired("size", s.size);
48 /// io.mapOptional("age", s.age);
49 /// }
50 /// };
51 template<class T>
52 struct MappingTraits {
53  // Must provide:
54  // static void mapping(IO &io, T &fields);
55  // Optionally may provide:
56  // static StringRef validate(IO &io, T &fields);
57  //
58  // The optional flow flag will cause generated YAML to use a flow mapping
59  // (e.g. { a: 0, b: 1 }):
60  // static const bool flow = true;
61 };
62 
63 /// This class is similar to MappingTraits<T> but allows you to pass in
64 /// additional context for each map operation. For example:
65 ///
66 /// struct MappingContextTraits<MyStruct, MyContext> {
67 /// static void mapping(IO &io, MyStruct &s, MyContext &c) {
68 /// io.mapRequired("name", s.name);
69 /// io.mapRequired("size", s.size);
70 /// io.mapOptional("age", s.age);
71 /// ++c.TimesMapped;
72 /// }
73 /// };
74 template <class T, class Context> struct MappingContextTraits {
75  // Must provide:
76  // static void mapping(IO &io, T &fields, Context &Ctx);
77  // Optionally may provide:
78  // static StringRef validate(IO &io, T &fields, Context &Ctx);
79  //
80  // The optional flow flag will cause generated YAML to use a flow mapping
81  // (e.g. { a: 0, b: 1 }):
82  // static const bool flow = true;
83 };
84 
85 /// This class should be specialized by any integral type that converts
86 /// to/from a YAML scalar where there is a one-to-one mapping between
87 /// in-memory values and a string in YAML. For example:
88 ///
89 /// struct ScalarEnumerationTraits<Colors> {
90 /// static void enumeration(IO &io, Colors &value) {
91 /// io.enumCase(value, "red", cRed);
92 /// io.enumCase(value, "blue", cBlue);
93 /// io.enumCase(value, "green", cGreen);
94 /// }
95 /// };
96 template<typename T>
98  // Must provide:
99  // static void enumeration(IO &io, T &value);
100 };
101 
102 /// This class should be specialized by any integer type that is a union
103 /// of bit values and the YAML representation is a flow sequence of
104 /// strings. For example:
105 ///
106 /// struct ScalarBitSetTraits<MyFlags> {
107 /// static void bitset(IO &io, MyFlags &value) {
108 /// io.bitSetCase(value, "big", flagBig);
109 /// io.bitSetCase(value, "flat", flagFlat);
110 /// io.bitSetCase(value, "round", flagRound);
111 /// }
112 /// };
113 template<typename T>
115  // Must provide:
116  // static void bitset(IO &io, T &value);
117 };
118 
119 /// This class should be specialized by type that requires custom conversion
120 /// to/from a yaml scalar. For example:
121 ///
122 /// template<>
123 /// struct ScalarTraits<MyType> {
124 /// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
125 /// // stream out custom formatting
126 /// out << llvm::format("%x", val);
127 /// }
128 /// static StringRef input(StringRef scalar, void*, MyType &value) {
129 /// // parse scalar and set `value`
130 /// // return empty string on success, or error string
131 /// return StringRef();
132 /// }
133 /// static bool mustQuote(StringRef) { return true; }
134 /// };
135 template<typename T>
136 struct ScalarTraits {
137  // Must provide:
138  //
139  // Function to write the value as a string:
140  //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
141  //
142  // Function to convert a string to a value. Returns the empty
143  // StringRef on success or an error string if string is malformed:
144  //static StringRef input(StringRef scalar, void *ctxt, T &value);
145  //
146  // Function to determine if the value should be quoted.
147  //static bool mustQuote(StringRef);
148 };
149 
150 /// This class should be specialized by type that requires custom conversion
151 /// to/from a YAML literal block scalar. For example:
152 ///
153 /// template <>
154 /// struct BlockScalarTraits<MyType> {
155 /// static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
156 /// {
157 /// // stream out custom formatting
158 /// Out << Val;
159 /// }
160 /// static StringRef input(StringRef Scalar, void*, MyType &Value) {
161 /// // parse scalar and set `value`
162 /// // return empty string on success, or error string
163 /// return StringRef();
164 /// }
165 /// };
166 template <typename T>
168  // Must provide:
169  //
170  // Function to write the value as a string:
171  // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
172  //
173  // Function to convert a string to a value. Returns the empty
174  // StringRef on success or an error string if string is malformed:
175  // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
176 };
177 
178 /// This class should be specialized by any type that needs to be converted
179 /// to/from a YAML sequence. For example:
180 ///
181 /// template<>
182 /// struct SequenceTraits< std::vector<MyType>> {
183 /// static size_t size(IO &io, std::vector<MyType> &seq) {
184 /// return seq.size();
185 /// }
186 /// static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
187 /// if ( index >= seq.size() )
188 /// seq.resize(index+1);
189 /// return seq[index];
190 /// }
191 /// };
192 template<typename T>
194  // Must provide:
195  // static size_t size(IO &io, T &seq);
196  // static T::value_type& element(IO &io, T &seq, size_t index);
197  //
198  // The following is option and will cause generated YAML to use
199  // a flow sequence (e.g. [a,b,c]).
200  // static const bool flow = true;
201 };
202 
203 /// This class should be specialized by any type that needs to be converted
204 /// to/from a list of YAML documents.
205 template<typename T>
207  // Must provide:
208  // static size_t size(IO &io, T &seq);
209  // static T::value_type& element(IO &io, T &seq, size_t index);
210 };
211 
212 /// This class should be specialized by any type that needs to be converted
213 /// to/from a YAML mapping in the case where the names of the keys are not known
214 /// in advance, e.g. a string map.
215 template <typename T>
217  // static void inputOne(IO &io, StringRef key, T &elem);
218  // static void output(IO &io, T &elem);
219 };
220 
221 // Only used for better diagnostics of missing traits
222 template <typename T>
224 
225 // Test if ScalarEnumerationTraits<T> is defined on type T.
226 template <class T>
228 {
229  typedef void (*Signature_enumeration)(class IO&, T&);
230 
231  template <typename U>
233 
234  template <typename U>
235  static double test(...);
236 
237 public:
238  static bool const value =
239  (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
240 };
241 
242 // Test if ScalarBitSetTraits<T> is defined on type T.
243 template <class T>
245 {
246  typedef void (*Signature_bitset)(class IO&, T&);
247 
248  template <typename U>
250 
251  template <typename U>
252  static double test(...);
253 
254 public:
255  static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
256 };
257 
258 // Test if ScalarTraits<T> is defined on type T.
259 template <class T>
261 {
262  typedef StringRef (*Signature_input)(StringRef, void*, T&);
263  typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
265 
266  template <typename U>
270 
271  template <typename U>
272  static double test(...);
273 
274 public:
275  static bool const value =
276  (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
277 };
278 
279 // Test if BlockScalarTraits<T> is defined on type T.
280 template <class T>
282 {
283  typedef StringRef (*Signature_input)(StringRef, void *, T &);
284  typedef void (*Signature_output)(const T &, void *, llvm::raw_ostream &);
285 
286  template <typename U>
289 
290  template <typename U>
291  static double test(...);
292 
293 public:
294  static bool const value =
295  (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
296 };
297 
298 // Test if MappingContextTraits<T> is defined on type T.
299 template <class T, class Context> struct has_MappingTraits {
300  typedef void (*Signature_mapping)(class IO &, T &, Context &);
301 
302  template <typename U>
304 
305  template <typename U>
306  static double test(...);
307 
308 public:
309  static bool const value =
310  (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
311 };
312 
313 // Test if MappingTraits<T> is defined on type T.
314 template <class T> struct has_MappingTraits<T, EmptyContext> {
315  typedef void (*Signature_mapping)(class IO &, T &);
316 
317  template <typename U>
319 
320  template <typename U> static double test(...);
321 
322 public:
323  static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
324 };
325 
326 // Test if MappingContextTraits<T>::validate() is defined on type T.
327 template <class T, class Context> struct has_MappingValidateTraits {
328  typedef StringRef (*Signature_validate)(class IO &, T &, Context &);
329 
330  template <typename U>
332 
333  template <typename U>
334  static double test(...);
335 
336 public:
337  static bool const value =
338  (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
339 };
340 
341 // Test if MappingTraits<T>::validate() is defined on type T.
342 template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
343  typedef StringRef (*Signature_validate)(class IO &, T &);
344 
345  template <typename U>
347 
348  template <typename U> static double test(...);
349 
350 public:
351  static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
352 };
353 
354 // Test if SequenceTraits<T> is defined on type T.
355 template <class T>
357 {
358  typedef size_t (*Signature_size)(class IO&, T&);
359 
360  template <typename U>
362 
363  template <typename U>
364  static double test(...);
365 
366 public:
367  static bool const value = (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
368 };
369 
370 // Test if CustomMappingTraits<T> is defined on type T.
371 template <class T>
373 {
374  typedef void (*Signature_input)(IO &io, StringRef key, T &v);
375 
376  template <typename U>
378 
379  template <typename U>
380  static double test(...);
381 
382 public:
383  static bool const value =
384  (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
385 };
386 
387 // has_FlowTraits<int> will cause an error with some compilers because
388 // it subclasses int. Using this wrapper only instantiates the
389 // real has_FlowTraits only if the template type is a class.
390 template <typename T, bool Enabled = std::is_class<T>::value>
392 {
393 public:
394  static const bool value = false;
395 };
396 
397 // Some older gcc compilers don't support straight forward tests
398 // for members, so test for ambiguity cause by the base and derived
399 // classes both defining the member.
400 template <class T>
402 {
403  struct Fallback { bool flow; };
404  struct Derived : T, Fallback { };
405 
406  template<typename C>
407  static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
408 
409  template<typename C>
410  static char (&f(...))[2];
411 
412 public:
413  static bool const value = sizeof(f<Derived>(nullptr)) == 2;
414 };
415 
416 // Test if SequenceTraits<T> is defined on type T
417 template<typename T>
418 struct has_SequenceTraits : public std::integral_constant<bool,
419  has_SequenceMethodTraits<T>::value > { };
420 
421 // Test if DocumentListTraits<T> is defined on type T
422 template <class T>
424 {
425  typedef size_t (*Signature_size)(class IO&, T&);
426 
427  template <typename U>
429 
430  template <typename U>
431  static double test(...);
432 
433 public:
434  static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
435 };
436 
437 inline bool isNumber(StringRef S) {
438  static const char OctalChars[] = "01234567";
439  if (S.startswith("0") &&
440  S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
441  return true;
442 
443  if (S.startswith("0o") &&
444  S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
445  return true;
446 
447  static const char HexChars[] = "0123456789abcdefABCDEF";
448  if (S.startswith("0x") &&
449  S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
450  return true;
451 
452  static const char DecChars[] = "0123456789";
453  if (S.find_first_not_of(DecChars) == StringRef::npos)
454  return true;
455 
456  if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
457  return true;
458 
459  Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
460  if (FloatMatcher.match(S))
461  return true;
462 
463  return false;
464 }
465 
466 inline bool isNumeric(StringRef S) {
467  if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
468  return true;
469 
470  if (isNumber(S))
471  return true;
472 
473  if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
474  return true;
475 
476  return false;
477 }
478 
479 inline bool isNull(StringRef S) {
480  return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
481  S.equals("~");
482 }
483 
484 inline bool isBool(StringRef S) {
485  return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
486  S.equals("false") || S.equals("False") || S.equals("FALSE");
487 }
488 
489 inline bool needsQuotes(StringRef S) {
490  if (S.empty())
491  return true;
492  if (isspace(S.front()) || isspace(S.back()))
493  return true;
494  if (S.front() == ',')
495  return true;
496 
497  static const char ScalarSafeChars[] =
498  "abcdefghijklmnopqrstuvwxyz"
499  "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
500  if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
501  return true;
502 
503  if (isNull(S))
504  return true;
505  if (isBool(S))
506  return true;
507  if (isNumeric(S))
508  return true;
509 
510  return false;
511 }
512 
513 template <typename T, typename Context>
515  : public std::integral_constant<bool,
516  !has_ScalarEnumerationTraits<T>::value &&
517  !has_ScalarBitSetTraits<T>::value &&
518  !has_ScalarTraits<T>::value &&
519  !has_BlockScalarTraits<T>::value &&
520  !has_MappingTraits<T, Context>::value &&
521  !has_SequenceTraits<T>::value &&
522  !has_CustomMappingTraits<T>::value &&
523  !has_DocumentListTraits<T>::value> {};
524 
525 template <typename T, typename Context>
527  : public std::integral_constant<
528  bool, has_MappingTraits<T, Context>::value &&
529  has_MappingValidateTraits<T, Context>::value> {};
530 
531 template <typename T, typename Context>
533  : public std::integral_constant<
534  bool, has_MappingTraits<T, Context>::value &&
535  !has_MappingValidateTraits<T, Context>::value> {};
536 
537 // Base class for Input and Output.
538 class IO {
539 public:
540  IO(void *Ctxt=nullptr);
541  virtual ~IO();
542 
543  virtual bool outputting() = 0;
544 
545  virtual unsigned beginSequence() = 0;
546  virtual bool preflightElement(unsigned, void *&) = 0;
547  virtual void postflightElement(void*) = 0;
548  virtual void endSequence() = 0;
549  virtual bool canElideEmptySequence() = 0;
550 
551  virtual unsigned beginFlowSequence() = 0;
552  virtual bool preflightFlowElement(unsigned, void *&) = 0;
553  virtual void postflightFlowElement(void*) = 0;
554  virtual void endFlowSequence() = 0;
555 
556  virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
557  virtual void beginMapping() = 0;
558  virtual void endMapping() = 0;
559  virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
560  virtual void postflightKey(void*) = 0;
561  virtual std::vector<StringRef> keys() = 0;
562 
563  virtual void beginFlowMapping() = 0;
564  virtual void endFlowMapping() = 0;
565 
566  virtual void beginEnumScalar() = 0;
567  virtual bool matchEnumScalar(const char*, bool) = 0;
568  virtual bool matchEnumFallback() = 0;
569  virtual void endEnumScalar() = 0;
570 
571  virtual bool beginBitSetScalar(bool &) = 0;
572  virtual bool bitSetMatch(const char*, bool) = 0;
573  virtual void endBitSetScalar() = 0;
574 
575  virtual void scalarString(StringRef &, bool) = 0;
576  virtual void blockScalarString(StringRef &) = 0;
577 
578  virtual void setError(const Twine &) = 0;
579 
580  template <typename T>
581  void enumCase(T &Val, const char* Str, const T ConstVal) {
582  if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
583  Val = ConstVal;
584  }
585  }
586 
587  // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
588  template <typename T>
589  void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
590  if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
591  Val = ConstVal;
592  }
593  }
594 
595  template <typename FBT, typename T>
596  void enumFallback(T &Val) {
597  if (matchEnumFallback()) {
599  // FIXME: Force integral conversion to allow strong typedefs to convert.
600  FBT Res = static_cast<typename FBT::BaseType>(Val);
601  yamlize(*this, Res, true, Context);
602  Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
603  }
604  }
605 
606  template <typename T>
607  void bitSetCase(T &Val, const char* Str, const T ConstVal) {
608  if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
609  Val = Val | ConstVal;
610  }
611  }
612 
613  // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
614  template <typename T>
615  void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
616  if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
617  Val = Val | ConstVal;
618  }
619  }
620 
621  template <typename T>
622  void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
623  if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
624  Val = Val | ConstVal;
625  }
626 
627  template <typename T>
628  void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
629  uint32_t Mask) {
630  if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
631  Val = Val | ConstVal;
632  }
633 
634  void *getContext();
635  void setContext(void *);
636 
637  template <typename T> void mapRequired(const char *Key, T &Val) {
638  EmptyContext Ctx;
639  this->processKey(Key, Val, true, Ctx);
640  }
641  template <typename T, typename Context>
642  void mapRequired(const char *Key, T &Val, Context &Ctx) {
643  this->processKey(Key, Val, true, Ctx);
644  }
645 
646  template <typename T> void mapOptional(const char *Key, T &Val) {
647  EmptyContext Ctx;
648  mapOptionalWithContext(Key, Val, Ctx);
649  }
650 
651  template <typename T>
652  void mapOptional(const char *Key, T &Val, const T &Default) {
653  EmptyContext Ctx;
654  mapOptionalWithContext(Key, Val, Default, Ctx);
655  }
656 
657  template <typename T, typename Context>
658  typename std::enable_if<has_SequenceTraits<T>::value, void>::type
659  mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
660  // omit key/value instead of outputting empty sequence
661  if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
662  return;
663  this->processKey(Key, Val, false, Ctx);
664  }
665 
666  template <typename T, typename Context>
667  void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
668  this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
669  Ctx);
670  }
671 
672  template <typename T, typename Context>
673  typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
674  mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
675  this->processKey(Key, Val, false, Ctx);
676  }
677 
678  template <typename T, typename Context>
679  void mapOptionalWithContext(const char *Key, T &Val, const T &Default,
680  Context &Ctx) {
681  this->processKeyWithDefault(Key, Val, Default, false, Ctx);
682  }
683 
684 private:
685  template <typename T, typename Context>
686  void processKeyWithDefault(const char *Key, Optional<T> &Val,
687  const Optional<T> &DefaultValue, bool Required,
688  Context &Ctx) {
689  assert(DefaultValue.hasValue() == false &&
690  "Optional<T> shouldn't have a value!");
691  void *SaveInfo;
692  bool UseDefault;
693  const bool sameAsDefault = outputting() && !Val.hasValue();
694  if (!outputting() && !Val.hasValue())
695  Val = T();
696  if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
697  SaveInfo)) {
698  yamlize(*this, Val.getValue(), Required, Ctx);
699  this->postflightKey(SaveInfo);
700  } else {
701  if (UseDefault)
702  Val = DefaultValue;
703  }
704  }
705 
706  template <typename T, typename Context>
707  void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
708  bool Required, Context &Ctx) {
709  void *SaveInfo;
710  bool UseDefault;
711  const bool sameAsDefault = outputting() && Val == DefaultValue;
712  if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
713  SaveInfo) ) {
714  yamlize(*this, Val, Required, Ctx);
715  this->postflightKey(SaveInfo);
716  }
717  else {
718  if ( UseDefault )
719  Val = DefaultValue;
720  }
721  }
722 
723  template <typename T, typename Context>
724  void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
725  void *SaveInfo;
726  bool UseDefault;
727  if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
728  yamlize(*this, Val, Required, Ctx);
729  this->postflightKey(SaveInfo);
730  }
731  }
732 
733 private:
734  void *Ctxt;
735 };
736 
737 namespace detail {
738 
739 template <typename T, typename Context>
740 void doMapping(IO &io, T &Val, Context &Ctx) {
742 }
743 
744 template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
745  MappingTraits<T>::mapping(io, Val);
746 }
747 
748 } // end namespace detail
749 
750 template <typename T>
751 typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
752 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
753  io.beginEnumScalar();
755  io.endEnumScalar();
756 }
757 
758 template <typename T>
759 typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
760 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
761  bool DoClear;
762  if ( io.beginBitSetScalar(DoClear) ) {
763  if ( DoClear )
764  Val = static_cast<T>(0);
766  io.endBitSetScalar();
767  }
768 }
769 
770 template <typename T>
771 typename std::enable_if<has_ScalarTraits<T>::value, void>::type
772 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
773  if ( io.outputting() ) {
774  std::string Storage;
775  llvm::raw_string_ostream Buffer(Storage);
776  ScalarTraits<T>::output(Val, io.getContext(), Buffer);
777  StringRef Str = Buffer.str();
779  }
780  else {
781  StringRef Str;
783  StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
784  if ( !Result.empty() ) {
785  io.setError(llvm::Twine(Result));
786  }
787  }
788 }
789 
790 template <typename T>
791 typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
792 yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
793  if (YamlIO.outputting()) {
794  std::string Storage;
795  llvm::raw_string_ostream Buffer(Storage);
796  BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
797  StringRef Str = Buffer.str();
798  YamlIO.blockScalarString(Str);
799  } else {
800  StringRef Str;
801  YamlIO.blockScalarString(Str);
802  StringRef Result =
803  BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
804  if (!Result.empty())
805  YamlIO.setError(llvm::Twine(Result));
806  }
807 }
808 
809 template <typename T, typename Context>
810 typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
811 yamlize(IO &io, T &Val, bool, Context &Ctx) {
812  if (has_FlowTraits<MappingTraits<T>>::value)
813  io.beginFlowMapping();
814  else
815  io.beginMapping();
816  if (io.outputting()) {
817  StringRef Err = MappingTraits<T>::validate(io, Val);
818  if (!Err.empty()) {
819  llvm::errs() << Err << "\n";
820  assert(Err.empty() && "invalid struct trying to be written as yaml");
821  }
822  }
823  detail::doMapping(io, Val, Ctx);
824  if (!io.outputting()) {
825  StringRef Err = MappingTraits<T>::validate(io, Val);
826  if (!Err.empty())
827  io.setError(Err);
828  }
829  if (has_FlowTraits<MappingTraits<T>>::value)
830  io.endFlowMapping();
831  else
832  io.endMapping();
833 }
834 
835 template <typename T, typename Context>
836 typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
837 yamlize(IO &io, T &Val, bool, Context &Ctx) {
838  if (has_FlowTraits<MappingTraits<T>>::value) {
839  io.beginFlowMapping();
840  detail::doMapping(io, Val, Ctx);
841  io.endFlowMapping();
842  } else {
843  io.beginMapping();
844  detail::doMapping(io, Val, Ctx);
845  io.endMapping();
846  }
847 }
848 
849 template <typename T>
850 typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
851 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
852  if ( io.outputting() ) {
853  io.beginMapping();
855  io.endMapping();
856  } else {
857  io.beginMapping();
858  for (StringRef key : io.keys())
859  CustomMappingTraits<T>::inputOne(io, key, Val);
860  io.endMapping();
861  }
862 }
863 
864 template <typename T>
865 typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
866 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
867  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
868 }
869 
870 template <typename T, typename Context>
871 typename std::enable_if<has_SequenceTraits<T>::value, void>::type
872 yamlize(IO &io, T &Seq, bool, Context &Ctx) {
873  if ( has_FlowTraits< SequenceTraits<T> >::value ) {
874  unsigned incnt = io.beginFlowSequence();
875  unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
876  for(unsigned i=0; i < count; ++i) {
877  void *SaveInfo;
878  if ( io.preflightFlowElement(i, SaveInfo) ) {
879  yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
880  io.postflightFlowElement(SaveInfo);
881  }
882  }
883  io.endFlowSequence();
884  }
885  else {
886  unsigned incnt = io.beginSequence();
887  unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
888  for(unsigned i=0; i < count; ++i) {
889  void *SaveInfo;
890  if ( io.preflightElement(i, SaveInfo) ) {
891  yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
892  io.postflightElement(SaveInfo);
893  }
894  }
895  io.endSequence();
896  }
897 }
898 
899 template<>
901  static void output(const bool &, void*, llvm::raw_ostream &);
902  static StringRef input(StringRef, void*, bool &);
903  static bool mustQuote(StringRef) { return false; }
904 };
905 
906 template<>
908  static void output(const StringRef &, void*, llvm::raw_ostream &);
909  static StringRef input(StringRef, void*, StringRef &);
910  static bool mustQuote(StringRef S) { return needsQuotes(S); }
911 };
912 
913 template<>
914 struct ScalarTraits<std::string> {
915  static void output(const std::string &, void*, llvm::raw_ostream &);
916  static StringRef input(StringRef, void*, std::string &);
917  static bool mustQuote(StringRef S) { return needsQuotes(S); }
918 };
919 
920 template<>
921 struct ScalarTraits<uint8_t> {
922  static void output(const uint8_t &, void*, llvm::raw_ostream &);
923  static StringRef input(StringRef, void*, uint8_t &);
924  static bool mustQuote(StringRef) { return false; }
925 };
926 
927 template<>
928 struct ScalarTraits<uint16_t> {
929  static void output(const uint16_t &, void*, llvm::raw_ostream &);
930  static StringRef input(StringRef, void*, uint16_t &);
931  static bool mustQuote(StringRef) { return false; }
932 };
933 
934 template<>
936  static void output(const uint32_t &, void*, llvm::raw_ostream &);
937  static StringRef input(StringRef, void*, uint32_t &);
938  static bool mustQuote(StringRef) { return false; }
939 };
940 
941 template<>
942 struct ScalarTraits<uint64_t> {
943  static void output(const uint64_t &, void*, llvm::raw_ostream &);
944  static StringRef input(StringRef, void*, uint64_t &);
945  static bool mustQuote(StringRef) { return false; }
946 };
947 
948 template<>
949 struct ScalarTraits<int8_t> {
950  static void output(const int8_t &, void*, llvm::raw_ostream &);
951  static StringRef input(StringRef, void*, int8_t &);
952  static bool mustQuote(StringRef) { return false; }
953 };
954 
955 template<>
956 struct ScalarTraits<int16_t> {
957  static void output(const int16_t &, void*, llvm::raw_ostream &);
958  static StringRef input(StringRef, void*, int16_t &);
959  static bool mustQuote(StringRef) { return false; }
960 };
961 
962 template<>
963 struct ScalarTraits<int32_t> {
964  static void output(const int32_t &, void*, llvm::raw_ostream &);
965  static StringRef input(StringRef, void*, int32_t &);
966  static bool mustQuote(StringRef) { return false; }
967 };
968 
969 template<>
970 struct ScalarTraits<int64_t> {
971  static void output(const int64_t &, void*, llvm::raw_ostream &);
972  static StringRef input(StringRef, void*, int64_t &);
973  static bool mustQuote(StringRef) { return false; }
974 };
975 
976 template<>
977 struct ScalarTraits<float> {
978  static void output(const float &, void*, llvm::raw_ostream &);
979  static StringRef input(StringRef, void*, float &);
980  static bool mustQuote(StringRef) { return false; }
981 };
982 
983 template<>
984 struct ScalarTraits<double> {
985  static void output(const double &, void*, llvm::raw_ostream &);
986  static StringRef input(StringRef, void*, double &);
987  static bool mustQuote(StringRef) { return false; }
988 };
989 
990 // For endian types, we just use the existing ScalarTraits for the underlying
991 // type. This way endian aware types are supported whenever a ScalarTraits
992 // is defined for the underlying type.
993 template <typename value_type, support::endianness endian, size_t alignment>
994 struct ScalarTraits<support::detail::packed_endian_specific_integral<
995  value_type, endian, alignment>> {
996  typedef support::detail::packed_endian_specific_integral<value_type, endian,
997  alignment>
999 
1000  static void output(const endian_type &E, void *Ctx,
1002  ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1003  }
1004 
1005  static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1006  value_type V;
1007  auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1008  E = static_cast<endian_type>(V);
1009  return R;
1010  }
1011 
1012  static bool mustQuote(StringRef Str) {
1014  }
1015 };
1016 
1017 // Utility for use within MappingTraits<>::mapping() method
1018 // to [de]normalize an object for use with YAML conversion.
1019 template <typename TNorm, typename TFinal>
1021  MappingNormalization(IO &i_o, TFinal &Obj)
1022  : io(i_o), BufPtr(nullptr), Result(Obj) {
1023  if ( io.outputting() ) {
1024  BufPtr = new (&Buffer) TNorm(io, Obj);
1025  }
1026  else {
1027  BufPtr = new (&Buffer) TNorm(io);
1028  }
1029  }
1030 
1032  if ( ! io.outputting() ) {
1033  Result = BufPtr->denormalize(io);
1034  }
1035  BufPtr->~TNorm();
1036  }
1037 
1038  TNorm* operator->() { return BufPtr; }
1039 
1040 private:
1041  typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
1042 
1043  Storage Buffer;
1044  IO &io;
1045  TNorm *BufPtr;
1046  TFinal &Result;
1047 };
1048 
1049 // Utility for use within MappingTraits<>::mapping() method
1050 // to [de]normalize an object for use with YAML conversion.
1051 template <typename TNorm, typename TFinal>
1053  MappingNormalizationHeap(IO &i_o, TFinal &Obj,
1054  llvm::BumpPtrAllocator *allocator)
1055  : io(i_o), BufPtr(nullptr), Result(Obj) {
1056  if ( io.outputting() ) {
1057  BufPtr = new (&Buffer) TNorm(io, Obj);
1058  }
1059  else if (allocator) {
1060  BufPtr = allocator->Allocate<TNorm>();
1061  new (BufPtr) TNorm(io);
1062  } else {
1063  BufPtr = new TNorm(io);
1064  }
1065  }
1066 
1068  if ( io.outputting() ) {
1069  BufPtr->~TNorm();
1070  }
1071  else {
1072  Result = BufPtr->denormalize(io);
1073  }
1074  }
1075 
1076  TNorm* operator->() { return BufPtr; }
1077 
1078 private:
1079  typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
1080 
1081  Storage Buffer;
1082  IO &io;
1083  TNorm *BufPtr;
1084  TFinal &Result;
1085 };
1086 
1087 ///
1088 /// The Input class is used to parse a yaml document into in-memory structs
1089 /// and vectors.
1090 ///
1091 /// It works by using YAMLParser to do a syntax parse of the entire yaml
1092 /// document, then the Input class builds a graph of HNodes which wraps
1093 /// each yaml Node. The extra layer is buffering. The low level yaml
1094 /// parser only lets you look at each node once. The buffering layer lets
1095 /// you search and interate multiple times. This is necessary because
1096 /// the mapRequired() method calls may not be in the same order
1097 /// as the keys in the document.
1098 ///
1099 class Input : public IO {
1100 public:
1101  // Construct a yaml Input object from a StringRef and optional
1102  // user-data. The DiagHandler can be specified to provide
1103  // alternative error reporting.
1104  Input(StringRef InputContent,
1105  void *Ctxt = nullptr,
1106  SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1107  void *DiagHandlerCtxt = nullptr);
1108  ~Input() override;
1109 
1110  // Check if there was an syntax or semantic error during parsing.
1111  std::error_code error();
1112 
1113 private:
1114  bool outputting() override;
1115  bool mapTag(StringRef, bool) override;
1116  void beginMapping() override;
1117  void endMapping() override;
1118  bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1119  void postflightKey(void *) override;
1120  std::vector<StringRef> keys() override;
1121  void beginFlowMapping() override;
1122  void endFlowMapping() override;
1123  unsigned beginSequence() override;
1124  void endSequence() override;
1125  bool preflightElement(unsigned index, void *&) override;
1126  void postflightElement(void *) override;
1127  unsigned beginFlowSequence() override;
1128  bool preflightFlowElement(unsigned , void *&) override;
1129  void postflightFlowElement(void *) override;
1130  void endFlowSequence() override;
1131  void beginEnumScalar() override;
1132  bool matchEnumScalar(const char*, bool) override;
1133  bool matchEnumFallback() override;
1134  void endEnumScalar() override;
1135  bool beginBitSetScalar(bool &) override;
1136  bool bitSetMatch(const char *, bool ) override;
1137  void endBitSetScalar() override;
1138  void scalarString(StringRef &, bool) override;
1139  void blockScalarString(StringRef &) override;
1140  void setError(const Twine &message) override;
1141  bool canElideEmptySequence() override;
1142 
1143  class HNode {
1144  virtual void anchor();
1145 
1146  public:
1147  HNode(Node *n) : _node(n) { }
1148  virtual ~HNode() = default;
1149 
1150  static inline bool classof(const HNode *) { return true; }
1151 
1152  Node *_node;
1153  };
1154 
1155  class EmptyHNode : public HNode {
1156  void anchor() override;
1157 
1158  public:
1159  EmptyHNode(Node *n) : HNode(n) { }
1160 
1161  static inline bool classof(const HNode *n) {
1162  return NullNode::classof(n->_node);
1163  }
1164 
1165  static inline bool classof(const EmptyHNode *) { return true; }
1166  };
1167 
1168  class ScalarHNode : public HNode {
1169  void anchor() override;
1170 
1171  public:
1172  ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1173 
1174  StringRef value() const { return _value; }
1175 
1176  static inline bool classof(const HNode *n) {
1177  return ScalarNode::classof(n->_node) ||
1178  BlockScalarNode::classof(n->_node);
1179  }
1180 
1181  static inline bool classof(const ScalarHNode *) { return true; }
1182 
1183  protected:
1184  StringRef _value;
1185  };
1186 
1187  class MapHNode : public HNode {
1188  void anchor() override;
1189 
1190  public:
1191  MapHNode(Node *n) : HNode(n) { }
1192 
1193  static inline bool classof(const HNode *n) {
1194  return MappingNode::classof(n->_node);
1195  }
1196 
1197  static inline bool classof(const MapHNode *) { return true; }
1198 
1199  typedef llvm::StringMap<std::unique_ptr<HNode>> NameToNode;
1200 
1201  NameToNode Mapping;
1203  };
1204 
1205  class SequenceHNode : public HNode {
1206  void anchor() override;
1207 
1208  public:
1209  SequenceHNode(Node *n) : HNode(n) { }
1210 
1211  static inline bool classof(const HNode *n) {
1212  return SequenceNode::classof(n->_node);
1213  }
1214 
1215  static inline bool classof(const SequenceHNode *) { return true; }
1216 
1217  std::vector<std::unique_ptr<HNode>> Entries;
1218  };
1219 
1220  std::unique_ptr<Input::HNode> createHNodes(Node *node);
1221  void setError(HNode *hnode, const Twine &message);
1222  void setError(Node *node, const Twine &message);
1223 
1224 public:
1225  // These are only used by operator>>. They could be private
1226  // if those templated things could be made friends.
1227  bool setCurrentDocument();
1228  bool nextDocument();
1229 
1230  /// Returns the current node that's being parsed by the YAML Parser.
1231  const Node *getCurrentNode() const;
1232 
1233 private:
1234  llvm::SourceMgr SrcMgr; // must be before Strm
1235  std::unique_ptr<llvm::yaml::Stream> Strm;
1236  std::unique_ptr<HNode> TopNode;
1237  std::error_code EC;
1238  llvm::BumpPtrAllocator StringAllocator;
1239  llvm::yaml::document_iterator DocIterator;
1240  std::vector<bool> BitValuesUsed;
1241  HNode *CurrentNode;
1242  bool ScalarMatchFound;
1243 };
1244 
1245 ///
1246 /// The Output class is used to generate a yaml document from in-memory structs
1247 /// and vectors.
1248 ///
1249 class Output : public IO {
1250 public:
1251  Output(llvm::raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1252  ~Output() override;
1253 
1254  bool outputting() override;
1255  bool mapTag(StringRef, bool) override;
1256  void beginMapping() override;
1257  void endMapping() override;
1258  bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1259  void postflightKey(void *) override;
1260  std::vector<StringRef> keys() override;
1261  void beginFlowMapping() override;
1262  void endFlowMapping() override;
1263  unsigned beginSequence() override;
1264  void endSequence() override;
1265  bool preflightElement(unsigned, void *&) override;
1266  void postflightElement(void *) override;
1267  unsigned beginFlowSequence() override;
1268  bool preflightFlowElement(unsigned, void *&) override;
1269  void postflightFlowElement(void *) override;
1270  void endFlowSequence() override;
1271  void beginEnumScalar() override;
1272  bool matchEnumScalar(const char*, bool) override;
1273  bool matchEnumFallback() override;
1274  void endEnumScalar() override;
1275  bool beginBitSetScalar(bool &) override;
1276  bool bitSetMatch(const char *, bool ) override;
1277  void endBitSetScalar() override;
1278  void scalarString(StringRef &, bool) override;
1279  void blockScalarString(StringRef &) override;
1280  void setError(const Twine &message) override;
1281  bool canElideEmptySequence() override;
1282 
1283  // These are only used by operator<<. They could be private
1284  // if that templated operator could be made a friend.
1285  void beginDocuments();
1286  bool preflightDocument(unsigned);
1287  void postflightDocument();
1288  void endDocuments();
1289 
1290 private:
1291  void output(StringRef s);
1292  void outputUpToEndOfLine(StringRef s);
1293  void newLineCheck();
1294  void outputNewLine();
1295  void paddedKey(StringRef key);
1296  void flowKey(StringRef Key);
1297 
1298  enum InState {
1299  inSeq,
1300  inFlowSeq,
1301  inMapFirstKey,
1302  inMapOtherKey,
1303  inFlowMapFirstKey,
1304  inFlowMapOtherKey
1305  };
1306 
1307  llvm::raw_ostream &Out;
1308  int WrapColumn;
1309  SmallVector<InState, 8> StateStack;
1310  int Column;
1311  int ColumnAtFlowStart;
1312  int ColumnAtMapFlowStart;
1313  bool NeedBitValueComma;
1314  bool NeedFlowSequenceComma;
1315  bool EnumerationMatchFound;
1316  bool NeedsNewLine;
1317 };
1318 
1319 /// YAML I/O does conversion based on types. But often native data types
1320 /// are just a typedef of built in intergral types (e.g. int). But the C++
1321 /// type matching system sees through the typedef and all the typedefed types
1322 /// look like a built in type. This will cause the generic YAML I/O conversion
1323 /// to be used. To provide better control over the YAML conversion, you can
1324 /// use this macro instead of typedef. It will create a class with one field
1325 /// and automatic conversion operators to and from the base type.
1326 /// Based on BOOST_STRONG_TYPEDEF
1327 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \
1328  struct _type { \
1329  _type() = default; \
1330  _type(const _base v) : value(v) {} \
1331  _type(const _type &v) = default; \
1332  _type &operator=(const _type &rhs) = default; \
1333  _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1334  operator const _base & () const { return value; } \
1335  bool operator==(const _type &rhs) const { return value == rhs.value; } \
1336  bool operator==(const _base &rhs) const { return value == rhs; } \
1337  bool operator<(const _type &rhs) const { return value < rhs.value; } \
1338  _base value; \
1339  typedef _base BaseType; \
1340  };
1341 
1342 ///
1343 /// Use these types instead of uintXX_t in any mapping to have
1344 /// its yaml output formatted as hexadecimal.
1345 ///
1346 LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
1347 LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
1349 LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
1350 
1351 template<>
1352 struct ScalarTraits<Hex8> {
1353  static void output(const Hex8 &, void*, llvm::raw_ostream &);
1354  static StringRef input(StringRef, void*, Hex8 &);
1355  static bool mustQuote(StringRef) { return false; }
1356 };
1357 
1358 template<>
1359 struct ScalarTraits<Hex16> {
1360  static void output(const Hex16 &, void*, llvm::raw_ostream &);
1361  static StringRef input(StringRef, void*, Hex16 &);
1362  static bool mustQuote(StringRef) { return false; }
1363 };
1364 
1365 template<>
1366 struct ScalarTraits<Hex32> {
1367  static void output(const Hex32 &, void*, llvm::raw_ostream &);
1368  static StringRef input(StringRef, void*, Hex32 &);
1369  static bool mustQuote(StringRef) { return false; }
1370 };
1371 
1372 template<>
1373 struct ScalarTraits<Hex64> {
1374  static void output(const Hex64 &, void*, llvm::raw_ostream &);
1375  static StringRef input(StringRef, void*, Hex64 &);
1376  static bool mustQuote(StringRef) { return false; }
1377 };
1378 
1379 // Define non-member operator>> so that Input can stream in a document list.
1380 template <typename T>
1381 inline
1382 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1383 operator>>(Input &yin, T &docList) {
1384  int i = 0;
1385  EmptyContext Ctx;
1386  while ( yin.setCurrentDocument() ) {
1387  yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1388  if ( yin.error() )
1389  return yin;
1390  yin.nextDocument();
1391  ++i;
1392  }
1393  return yin;
1394 }
1395 
1396 // Define non-member operator>> so that Input can stream in a map as a document.
1397 template <typename T>
1398 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1399  Input &>::type
1400 operator>>(Input &yin, T &docMap) {
1401  EmptyContext Ctx;
1402  yin.setCurrentDocument();
1403  yamlize(yin, docMap, true, Ctx);
1404  return yin;
1405 }
1406 
1407 // Define non-member operator>> so that Input can stream in a sequence as
1408 // a document.
1409 template <typename T>
1410 inline
1411 typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1412 operator>>(Input &yin, T &docSeq) {
1413  EmptyContext Ctx;
1414  if (yin.setCurrentDocument())
1415  yamlize(yin, docSeq, true, Ctx);
1416  return yin;
1417 }
1418 
1419 // Define non-member operator>> so that Input can stream in a block scalar.
1420 template <typename T>
1421 inline
1422 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1424  EmptyContext Ctx;
1425  if (In.setCurrentDocument())
1426  yamlize(In, Val, true, Ctx);
1427  return In;
1428 }
1429 
1430 // Define non-member operator>> so that Input can stream in a string map.
1431 template <typename T>
1432 inline
1433 typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
1435  EmptyContext Ctx;
1436  if (In.setCurrentDocument())
1437  yamlize(In, Val, true, Ctx);
1438  return In;
1439 }
1440 
1441 // Provide better error message about types missing a trait specialization
1442 template <typename T>
1443 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1444  Input &>::type
1445 operator>>(Input &yin, T &docSeq) {
1446  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1447  return yin;
1448 }
1449 
1450 // Define non-member operator<< so that Output can stream out document list.
1451 template <typename T>
1452 inline
1453 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1454 operator<<(Output &yout, T &docList) {
1455  EmptyContext Ctx;
1456  yout.beginDocuments();
1457  const size_t count = DocumentListTraits<T>::size(yout, docList);
1458  for(size_t i=0; i < count; ++i) {
1459  if ( yout.preflightDocument(i) ) {
1460  yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1461  Ctx);
1462  yout.postflightDocument();
1463  }
1464  }
1465  yout.endDocuments();
1466  return yout;
1467 }
1468 
1469 // Define non-member operator<< so that Output can stream out a map.
1470 template <typename T>
1471 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1472  Output &>::type
1473 operator<<(Output &yout, T &map) {
1474  EmptyContext Ctx;
1475  yout.beginDocuments();
1476  if ( yout.preflightDocument(0) ) {
1477  yamlize(yout, map, true, Ctx);
1478  yout.postflightDocument();
1479  }
1480  yout.endDocuments();
1481  return yout;
1482 }
1483 
1484 // Define non-member operator<< so that Output can stream out a sequence.
1485 template <typename T>
1486 inline
1487 typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1489  EmptyContext Ctx;
1490  yout.beginDocuments();
1491  if ( yout.preflightDocument(0) ) {
1492  yamlize(yout, seq, true, Ctx);
1493  yout.postflightDocument();
1494  }
1495  yout.endDocuments();
1496  return yout;
1497 }
1498 
1499 // Define non-member operator<< so that Output can stream out a block scalar.
1500 template <typename T>
1501 inline
1502 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1503 operator<<(Output &Out, T &Val) {
1504  EmptyContext Ctx;
1505  Out.beginDocuments();
1506  if (Out.preflightDocument(0)) {
1507  yamlize(Out, Val, true, Ctx);
1508  Out.postflightDocument();
1509  }
1510  Out.endDocuments();
1511  return Out;
1512 }
1513 
1514 // Define non-member operator<< so that Output can stream out a string map.
1515 template <typename T>
1516 inline
1517 typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
1518 operator<<(Output &Out, T &Val) {
1519  EmptyContext Ctx;
1520  Out.beginDocuments();
1521  if (Out.preflightDocument(0)) {
1522  yamlize(Out, Val, true, Ctx);
1523  Out.postflightDocument();
1524  }
1525  Out.endDocuments();
1526  return Out;
1527 }
1528 
1529 // Provide better error message about types missing a trait specialization
1530 template <typename T>
1531 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1532  Output &>::type
1534  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1535  return yout;
1536 }
1537 
1538 template <typename T> struct SequenceTraitsImpl {
1539  typedef typename T::value_type _type;
1540  static size_t size(IO &io, T &seq) { return seq.size(); }
1541  static _type &element(IO &io, T &seq, size_t index) {
1542  if (index >= seq.size())
1543  seq.resize(index + 1);
1544  return seq[index];
1545  }
1546 };
1547 
1548 /// Implementation of CustomMappingTraits for std::map<std::string, T>.
1549 template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1550  typedef std::map<std::string, T> map_type;
1551  static void inputOne(IO &io, StringRef key, map_type &v) {
1552  io.mapRequired(key.str().c_str(), v[key]);
1553  }
1554  static void output(IO &io, map_type &v) {
1555  for (auto &p : v)
1556  io.mapRequired(p.first.c_str(), p.second);
1557  }
1558 };
1559 
1560 } // end namespace yaml
1561 } // end namespace llvm
1562 
1563 /// Utility for declaring that a std::vector of a particular type
1564 /// should be considered a YAML sequence.
1565 #define LLVM_YAML_IS_SEQUENCE_VECTOR(_type) \
1566  namespace llvm { \
1567  namespace yaml { \
1568  template <> \
1569  struct SequenceTraits<std::vector<_type>> \
1570  : public SequenceTraitsImpl<std::vector<_type>> {}; \
1571  template <unsigned N> \
1572  struct SequenceTraits<SmallVector<_type, N>> \
1573  : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \
1574  } \
1575  }
1576 
1577 /// Utility for declaring that a std::vector of a particular type
1578 /// should be considered a YAML flow sequence.
1579 /// We need to do a partial specialization on the vector version, not a full.
1580 /// If this is a full specialization, the compiler is a bit too "smart" and
1581 /// decides to warn on -Wunused-const-variable. This workaround can be
1582 /// removed and we can do a full specialization on std::vector<T> once
1583 /// PR28878 is fixed.
1584 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type) \
1585  namespace llvm { \
1586  namespace yaml { \
1587  template <unsigned N> \
1588  struct SequenceTraits<SmallVector<_type, N>> \
1589  : public SequenceTraitsImpl<SmallVector<_type, N>> { \
1590  static const bool flow = true; \
1591  }; \
1592  template <typename Allocator> \
1593  struct SequenceTraits<std::vector<_type, Allocator>> \
1594  : public SequenceTraitsImpl<std::vector<_type, Allocator>> { \
1595  static const bool flow = true; \
1596  }; \
1597  } \
1598  }
1599 
1600 /// Utility for declaring that a std::vector of a particular type
1601 /// should be considered a YAML document list.
1602 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \
1603  namespace llvm { \
1604  namespace yaml { \
1605  template <unsigned N> \
1606  struct DocumentListTraits<SmallVector<_type, N>> \
1607  : public SequenceTraitsImpl<SmallVector<_type, N>> {}; \
1608  template <> \
1609  struct DocumentListTraits<std::vector<_type>> \
1610  : public SequenceTraitsImpl<std::vector<_type>> {}; \
1611  } \
1612  }
1613 
1614 /// Utility for declaring that std::map<std::string, _type> should be considered
1615 /// a YAML map.
1616 #define LLVM_YAML_IS_STRING_MAP(_type) \
1617  namespace llvm { \
1618  namespace yaml { \
1619  template <> \
1620  struct CustomMappingTraits<std::map<std::string, _type>> \
1621  : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
1622  } \
1623  }
1624 
1625 #endif // LLVM_SUPPORT_YAMLTRAITS_H
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:634
static bool classof(const Node *N)
Definition: YAMLParser.h:416
void setError(const Twine &message) override
Definition: YAMLTraits.cpp:661
static char test(SameType< Signature_input,&U::input > *, SameType< Signature_output,&U::output > *)
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:903
static void output(IO &io, map_type &v)
Definition: YAMLTraits.h:1554
static bool const value
Definition: YAMLTraits.h:275
static char test(SameType< Signature_enumeration,&U::enumeration > *)
std::error_code error()
Definition: YAMLTraits.cpp:59
void bitSetCase(T &Val, const char *Str, const T ConstVal)
Definition: YAMLTraits.h:607
bool preflightElement(unsigned, void *&) override
Definition: YAMLTraits.cpp:527
bool preflightDocument(unsigned)
Definition: YAMLTraits.cpp:504
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static bool mustQuote(StringRef S)
Definition: YAMLTraits.h:917
void mapOptional(const char *Key, T &Val)
Definition: YAMLTraits.h:646
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:952
~Output() override
Definition: YAMLTraits.cpp:413
LLVMContext & Context
virtual bool beginBitSetScalar(bool &)=0
bool hasValue() const
Definition: Optional.h:125
size_t i
void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask)
Definition: YAMLTraits.h:622
static char test(SameType< Signature_input,&U::input > *, SameType< Signature_output,&U::output > *, SameType< Signature_mustQuote,&U::mustQuote > *)
static _type & element(IO &io, T &seq, size_t index)
Definition: YAMLTraits.h:1541
virtual bool preflightFlowElement(unsigned, void *&)=0
void(* Signature_input)(IO &io, StringRef key, T &v)
Definition: YAMLTraits.h:374
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:931
static size_t size(IO &io, T &seq)
Definition: YAMLTraits.h:1540
void beginMapping() override
Definition: YAMLTraits.cpp:420
virtual void endFlowMapping()=0
void(* Signature_enumeration)(class IO &, T &)
Definition: YAMLTraits.h:229
virtual void scalarString(StringRef &, bool)=0
void endFlowMapping() override
Definition: YAMLTraits.cpp:495
void * getContext()
Definition: YAMLTraits.cpp:35
void endSequence() override
Definition: YAMLTraits.cpp:523
void enumCase(T &Val, const char *Str, const uint32_t ConstVal)
Definition: YAMLTraits.h:589
virtual void endEnumScalar()=0
static char test(SameType< Signature_size,&U::size > *)
bool isBool(StringRef S)
Definition: YAMLTraits.h:484
bool needsQuotes(StringRef S)
Definition: YAMLTraits.h:489
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:1369
static bool classof(const Node *N)
Definition: YAMLParser.h:474
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:146
static char test(SameType< Signature_validate,&U::validate > *)
virtual void setError(const Twine &)=0
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
virtual bool matchEnumFallback()=0
virtual void postflightElement(void *)=0
virtual unsigned beginSequence()=0
StringRef(* Signature_validate)(class IO &, T &, Context &)
Definition: YAMLTraits.h:328
This class should be specialized by any type that needs to be converted to/from a YAML sequence...
Definition: YAMLTraits.h:193
void beginFlowMapping() override
Definition: YAMLTraits.cpp:488
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:980
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void postflightElement(void *) override
Definition: YAMLTraits.cpp:531
void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal, uint32_t Mask)
Definition: YAMLTraits.h:628
static bool classof(const Node *N)
Definition: YAMLParser.h:251
bool matchEnumScalar(const char *, bool) override
Definition: YAMLTraits.cpp:569
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:166
Output(llvm::raw_ostream &, void *Ctxt=nullptr, int WrapColumn=70)
Definition: YAMLTraits.cpp:400
std::enable_if< has_SequenceTraits< T >::value, void >::type mapOptionalWithContext(const char *Key, T &Val, Context &Ctx)
Definition: YAMLTraits.h:659
virtual bool preflightElement(unsigned, void *&)=0
void scalarString(StringRef &, bool) override
Definition: YAMLTraits.cpp:612
bool matchEnumFallback() override
Definition: YAMLTraits.cpp:578
void(* Signature_mapping)(class IO &, T &, Context &)
Definition: YAMLTraits.h:300
void enumFallback(T &Val)
Definition: YAMLTraits.h:596
bool beginBitSetScalar(bool &) override
Definition: YAMLTraits.cpp:590
The Input class is used to parse a yaml document into in-memory structs and vectors.
Definition: YAMLTraits.h:1099
This class should be specialized by any type that needs to be converted to/from a YAML mapping...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
#define T
const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:121
static const bool value
Definition: YAMLTraits.h:394
bool outputting() override
Definition: YAMLTraits.cpp:416
StringRef(* Signature_input)(StringRef, void *, T &)
Definition: YAMLTraits.h:262
void bitSetCase(T &Val, const char *Str, const uint32_t ConstVal)
Definition: YAMLTraits.h:615
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:791
bool(* Signature_mustQuote)(StringRef)
Definition: YAMLTraits.h:264
static void output(const endian_type &E, void *Ctx, llvm::raw_ostream &Stream)
Definition: YAMLTraits.h:1000
LLVM_NODISCARD char front() const
front - Get the first character in the string.
Definition: StringRef.h:139
std::vector< StringRef > keys() override
Definition: YAMLTraits.cpp:458
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:1362
std::enable_if< has_DocumentListTraits< T >::value, Output & >::type operator<<(Output &yout, T &docList)
Definition: YAMLTraits.h:1454
virtual bool mapTag(StringRef Tag, bool Default=false)=0
static bool const value
Definition: YAMLTraits.h:309
bool mapTag(StringRef, bool) override
Definition: YAMLTraits.cpp:425
static bool classof(const Node *N)
Definition: YAMLParser.h:217
void(* Signature_output)(const T &, void *, llvm::raw_ostream &)
Definition: YAMLTraits.h:284
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:966
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
std::enable_if< has_DocumentListTraits< T >::value, Input & >::type operator>>(Input &yin, T &docList)
Definition: YAMLTraits.h:1383
void endMapping() override
Definition: YAMLTraits.cpp:454
void enumCase(T &Val, const char *Str, const T ConstVal)
Definition: YAMLTraits.h:581
const Node * getCurrentNode() const
Returns the current node that's being parsed by the YAML Parser.
Definition: YAMLTraits.cpp:97
virtual void endFlowSequence()=0
size_t(* Signature_size)(class IO &, T &)
Definition: YAMLTraits.h:425
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:138
virtual void beginEnumScalar()=0
void postflightFlowElement(void *) override
Definition: YAMLTraits.cpp:561
This class should be specialized by any type that needs to be converted to/from a list of YAML docume...
Definition: YAMLTraits.h:206
static char test(SameType< Signature_input,&U::inputOne > *)
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:1355
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:212
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
Definition: SourceMgr.h:46
This class is similar to MappingTraits<T> but allows you to pass in additional context for each map o...
Definition: YAMLTraits.h:74
This class should be specialized by any type that needs to be converted to/from a YAML mapping in the...
Definition: YAMLTraits.h:216
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:987
virtual bool preflightKey(const char *, bool, bool, bool &, void *&)=0
virtual bool canElideEmptySequence()=0
static char test(SameType< Signature_mapping,&U::mapping > *)
void doMapping(IO &io, T &Val, Context &Ctx)
Definition: YAMLTraits.h:740
virtual void blockScalarString(StringRef &)=0
bool setCurrentDocument()
Definition: YAMLTraits.cpp:72
virtual void endBitSetScalar()=0
support::detail::packed_endian_specific_integral< value_type, endian, alignment > endian_type
Definition: YAMLTraits.h:998
void endFlowSequence() override
Definition: YAMLTraits.cpp:543
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
Definition: SourceMgr.h:35
bool preflightKey(const char *key, bool, bool, bool &, void *&) override
Definition: YAMLTraits.cpp:462
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:225
The Output class is used to generate a yaml document from in-memory structs and vectors.
Definition: YAMLTraits.h:1249
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition: StringRef.cpp:264
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
Definition: raw_ostream.h:479
void mapOptionalWithContext(const char *Key, T &Val, const T &Default, Context &Ctx)
Definition: YAMLTraits.h:679
virtual void beginMapping()=0
MappingNormalizationHeap(IO &i_o, TFinal &Obj, llvm::BumpPtrAllocator *allocator)
Definition: YAMLTraits.h:1053
MappingNormalization(IO &i_o, TFinal &Obj)
Definition: YAMLTraits.h:1021
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:959
This class should be specialized by any integral type that converts to/from a YAML scalar where there...
Definition: YAMLTraits.h:97
#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)
YAML I/O does conversion based on types.
Definition: YAMLTraits.h:1327
bool preflightFlowElement(unsigned, void *&) override
Definition: YAMLTraits.cpp:548
virtual std::vector< StringRef > keys()=0
virtual ~IO()
Definition: YAMLTraits.cpp:32
static void inputOne(IO &io, StringRef key, map_type &v)
Definition: YAMLTraits.h:1551
This class represents a YAML stream potentially containing multiple documents.
Definition: YAMLParser.h:76
virtual bool bitSetMatch(const char *, bool)=0
This class should be specialized by type that requires custom conversion to/from a yaml scalar...
Definition: YAMLTraits.h:136
void endBitSetScalar() override
Definition: YAMLTraits.cpp:608
bool bitSetMatch(const char *, bool) override
Definition: YAMLTraits.cpp:598
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:924
iterator_range< detail::value_sequence_iterator< ValueT > > seq(ValueT Begin, ValueT End)
Definition: Sequence.h:71
virtual void postflightKey(void *)=0
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:223
virtual void beginFlowMapping()=0
void setContext(void *)
Definition: YAMLTraits.cpp:39
static bool mustQuote(StringRef S)
Definition: YAMLTraits.h:910
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
virtual unsigned beginFlowSequence()=0
unsigned beginFlowSequence() override
Definition: YAMLTraits.cpp:534
static char test(SameType< Signature_bitset,&U::bitset > *)
Basic Alias true
bool isNumber(StringRef S)
Definition: YAMLTraits.h:437
void(* Signature_bitset)(class IO &, T &)
Definition: YAMLTraits.h:246
static bool classof(const Node *N)
Definition: YAMLParser.h:185
static const size_t npos
Definition: StringRef.h:51
This class should be specialized by type that requires custom conversion to/from a YAML literal block...
Definition: YAMLTraits.h:167
IO(void *Ctxt=nullptr)
Definition: YAMLTraits.cpp:29
size_t(* Signature_size)(class IO &, T &)
Definition: YAMLTraits.h:358
virtual void endMapping()=0
virtual void postflightFlowElement(void *)=0
std::enable_if< has_ScalarEnumerationTraits< T >::value, void >::type yamlize(IO &io, T &Val, bool, EmptyContext &Ctx)
Definition: YAMLTraits.h:752
virtual bool matchEnumScalar(const char *, bool)=0
void mapOptionalWithContext(const char *Key, Optional< T > &Val, Context &Ctx)
Definition: YAMLTraits.h:667
virtual bool outputting()=0
This class should be specialized by any integer type that is a union of bit values and the YAML repre...
Definition: YAMLTraits.h:114
Iterator abstraction for Documents over a Stream.
Definition: YAMLParser.h:565
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:938
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:945
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:1376
void mapOptional(const char *Key, T &Val, const T &Default)
Definition: YAMLTraits.h:652
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:463
bool isNull(StringRef S)
Definition: YAMLTraits.h:479
virtual void endSequence()=0
Input(StringRef InputContent, void *Ctxt=nullptr, SourceMgr::DiagHandlerTy DiagHandler=nullptr, void *DiagHandlerCtxt=nullptr)
Definition: YAMLTraits.cpp:47
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:81
void beginEnumScalar() override
Definition: YAMLTraits.cpp:565
unsigned beginSequence() override
Definition: YAMLTraits.cpp:517
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
Implementation of CustomMappingTraits for std::map<std::string, T>.
Definition: YAMLTraits.h:1549
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr)
matches - Match the regex against a given String.
Definition: Regex.cpp:68
void mapRequired(const char *Key, T &Val, Context &Ctx)
Definition: YAMLTraits.h:642
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
void mapRequired(const char *Key, T &Val)
Definition: YAMLTraits.h:637
std::enable_if<!has_SequenceTraits< T >::value, void >::type mapOptionalWithContext(const char *Key, T &Val, Context &Ctx)
Definition: YAMLTraits.h:674
void endEnumScalar() override
Definition: YAMLTraits.cpp:585
void(* Signature_output)(const T &, void *, llvm::raw_ostream &)
Definition: YAMLTraits.h:263
static bool mustQuote(StringRef)
Definition: YAMLTraits.h:973
void postflightKey(void *) override
Definition: YAMLTraits.cpp:478
void blockScalarString(StringRef &) override
Definition: YAMLTraits.cpp:643
static char test(SameType< Signature_size,&U::size > *)
StringRef(* Signature_input)(StringRef, void *, T &)
Definition: YAMLTraits.h:283
bool canElideEmptySequence() override
Definition: YAMLTraits.cpp:664
~Input() override
Definition: YAMLTraits.cpp:56
bool isNumeric(StringRef S)
Definition: YAMLTraits.h:466
Abstract base class for all Nodes.
Definition: YAMLParser.h:105