LLVM  9.0.0svn
YAMLTraits.h
Go to the documentation of this file.
1 //===- llvm/Support/YAMLTraits.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_SUPPORT_YAMLTRAITS_H
10 #define LLVM_SUPPORT_YAMLTRAITS_H
11 
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringExtras.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 <iterator>
30 #include <map>
31 #include <memory>
32 #include <new>
33 #include <string>
34 #include <system_error>
35 #include <type_traits>
36 #include <vector>
37 
38 namespace llvm {
39 namespace yaml {
40 
41 enum class NodeKind : uint8_t {
42  Scalar,
43  Map,
44  Sequence,
45 };
46 
47 struct EmptyContext {};
48 
49 /// This class should be specialized by any type that needs to be converted
50 /// to/from a YAML mapping. For example:
51 ///
52 /// struct MappingTraits<MyStruct> {
53 /// static void mapping(IO &io, MyStruct &s) {
54 /// io.mapRequired("name", s.name);
55 /// io.mapRequired("size", s.size);
56 /// io.mapOptional("age", s.age);
57 /// }
58 /// };
59 template<class T>
60 struct MappingTraits {
61  // Must provide:
62  // static void mapping(IO &io, T &fields);
63  // Optionally may provide:
64  // static StringRef validate(IO &io, T &fields);
65  //
66  // The optional flow flag will cause generated YAML to use a flow mapping
67  // (e.g. { a: 0, b: 1 }):
68  // static const bool flow = true;
69 };
70 
71 /// This class is similar to MappingTraits<T> but allows you to pass in
72 /// additional context for each map operation. For example:
73 ///
74 /// struct MappingContextTraits<MyStruct, MyContext> {
75 /// static void mapping(IO &io, MyStruct &s, MyContext &c) {
76 /// io.mapRequired("name", s.name);
77 /// io.mapRequired("size", s.size);
78 /// io.mapOptional("age", s.age);
79 /// ++c.TimesMapped;
80 /// }
81 /// };
82 template <class T, class Context> struct MappingContextTraits {
83  // Must provide:
84  // static void mapping(IO &io, T &fields, Context &Ctx);
85  // Optionally may provide:
86  // static StringRef validate(IO &io, T &fields, Context &Ctx);
87  //
88  // The optional flow flag will cause generated YAML to use a flow mapping
89  // (e.g. { a: 0, b: 1 }):
90  // static const bool flow = true;
91 };
92 
93 /// This class should be specialized by any integral type that converts
94 /// to/from a YAML scalar where there is a one-to-one mapping between
95 /// in-memory values and a string in YAML. For example:
96 ///
97 /// struct ScalarEnumerationTraits<Colors> {
98 /// static void enumeration(IO &io, Colors &value) {
99 /// io.enumCase(value, "red", cRed);
100 /// io.enumCase(value, "blue", cBlue);
101 /// io.enumCase(value, "green", cGreen);
102 /// }
103 /// };
104 template<typename T>
105 struct ScalarEnumerationTraits {
106  // Must provide:
107  // static void enumeration(IO &io, T &value);
108 };
109 
110 /// This class should be specialized by any integer type that is a union
111 /// of bit values and the YAML representation is a flow sequence of
112 /// strings. For example:
113 ///
114 /// struct ScalarBitSetTraits<MyFlags> {
115 /// static void bitset(IO &io, MyFlags &value) {
116 /// io.bitSetCase(value, "big", flagBig);
117 /// io.bitSetCase(value, "flat", flagFlat);
118 /// io.bitSetCase(value, "round", flagRound);
119 /// }
120 /// };
121 template<typename T>
122 struct ScalarBitSetTraits {
123  // Must provide:
124  // static void bitset(IO &io, T &value);
125 };
126 
127 /// Describe which type of quotes should be used when quoting is necessary.
128 /// Some non-printable characters need to be double-quoted, while some others
129 /// are fine with simple-quoting, and some don't need any quoting.
130 enum class QuotingType { None, Single, Double };
131 
132 /// This class should be specialized by type that requires custom conversion
133 /// to/from a yaml scalar. For example:
134 ///
135 /// template<>
136 /// struct ScalarTraits<MyType> {
137 /// static void output(const MyType &val, void*, llvm::raw_ostream &out) {
138 /// // stream out custom formatting
139 /// out << llvm::format("%x", val);
140 /// }
141 /// static StringRef input(StringRef scalar, void*, MyType &value) {
142 /// // parse scalar and set `value`
143 /// // return empty string on success, or error string
144 /// return StringRef();
145 /// }
146 /// static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
147 /// };
148 template<typename T>
149 struct ScalarTraits {
150  // Must provide:
151  //
152  // Function to write the value as a string:
153  // static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
154  //
155  // Function to convert a string to a value. Returns the empty
156  // StringRef on success or an error string if string is malformed:
157  // static StringRef input(StringRef scalar, void *ctxt, T &value);
158  //
159  // Function to determine if the value should be quoted.
160  // static QuotingType mustQuote(StringRef);
161 };
162 
163 /// This class should be specialized by type that requires custom conversion
164 /// to/from a YAML literal block scalar. For example:
165 ///
166 /// template <>
167 /// struct BlockScalarTraits<MyType> {
168 /// static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
169 /// {
170 /// // stream out custom formatting
171 /// Out << Value;
172 /// }
173 /// static StringRef input(StringRef Scalar, void*, MyType &Value) {
174 /// // parse scalar and set `value`
175 /// // return empty string on success, or error string
176 /// return StringRef();
177 /// }
178 /// };
179 template <typename T>
180 struct BlockScalarTraits {
181  // Must provide:
182  //
183  // Function to write the value as a string:
184  // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
185  //
186  // Function to convert a string to a value. Returns the empty
187  // StringRef on success or an error string if string is malformed:
188  // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
189  //
190  // Optional:
191  // static StringRef inputTag(T &Val, std::string Tag)
192  // static void outputTag(const T &Val, raw_ostream &Out)
193 };
194 
195 /// This class should be specialized by type that requires custom conversion
196 /// to/from a YAML scalar with optional tags. For example:
197 ///
198 /// template <>
199 /// struct TaggedScalarTraits<MyType> {
200 /// static void output(const MyType &Value, void*, llvm::raw_ostream
201 /// &ScalarOut, llvm::raw_ostream &TagOut)
202 /// {
203 /// // stream out custom formatting including optional Tag
204 /// Out << Value;
205 /// }
206 /// static StringRef input(StringRef Scalar, StringRef Tag, void*, MyType
207 /// &Value) {
208 /// // parse scalar and set `value`
209 /// // return empty string on success, or error string
210 /// return StringRef();
211 /// }
212 /// static QuotingType mustQuote(const MyType &Value, StringRef) {
213 /// return QuotingType::Single;
214 /// }
215 /// };
216 template <typename T> struct TaggedScalarTraits {
217  // Must provide:
218  //
219  // Function to write the value and tag as strings:
220  // static void output(const T &Value, void *ctx, llvm::raw_ostream &ScalarOut,
221  // llvm::raw_ostream &TagOut);
222  //
223  // Function to convert a string to a value. Returns the empty
224  // StringRef on success or an error string if string is malformed:
225  // static StringRef input(StringRef Scalar, StringRef Tag, void *ctxt, T
226  // &Value);
227  //
228  // Function to determine if the value should be quoted.
229  // static QuotingType mustQuote(const T &Value, StringRef Scalar);
230 };
231 
232 /// This class should be specialized by any type that needs to be converted
233 /// to/from a YAML sequence. For example:
234 ///
235 /// template<>
236 /// struct SequenceTraits<MyContainer> {
237 /// static size_t size(IO &io, MyContainer &seq) {
238 /// return seq.size();
239 /// }
240 /// static MyType& element(IO &, MyContainer &seq, size_t index) {
241 /// if ( index >= seq.size() )
242 /// seq.resize(index+1);
243 /// return seq[index];
244 /// }
245 /// };
246 template<typename T, typename EnableIf = void>
247 struct SequenceTraits {
248  // Must provide:
249  // static size_t size(IO &io, T &seq);
250  // static T::value_type& element(IO &io, T &seq, size_t index);
251  //
252  // The following is option and will cause generated YAML to use
253  // a flow sequence (e.g. [a,b,c]).
254  // static const bool flow = true;
255 };
256 
257 /// This class should be specialized by any type for which vectors of that
258 /// type need to be converted to/from a YAML sequence.
259 template<typename T, typename EnableIf = void>
260 struct SequenceElementTraits {
261  // Must provide:
262  // static const bool flow;
263 };
264 
265 /// This class should be specialized by any type that needs to be converted
266 /// to/from a list of YAML documents.
267 template<typename T>
268 struct DocumentListTraits {
269  // Must provide:
270  // static size_t size(IO &io, T &seq);
271  // static T::value_type& element(IO &io, T &seq, size_t index);
272 };
273 
274 /// This class should be specialized by any type that needs to be converted
275 /// to/from a YAML mapping in the case where the names of the keys are not known
276 /// in advance, e.g. a string map.
277 template <typename T>
278 struct CustomMappingTraits {
279  // static void inputOne(IO &io, StringRef key, T &elem);
280  // static void output(IO &io, T &elem);
281 };
282 
283 /// This class should be specialized by any type that can be represented as
284 /// a scalar, map, or sequence, decided dynamically. For example:
285 ///
286 /// typedef std::unique_ptr<MyBase> MyPoly;
287 ///
288 /// template<>
289 /// struct PolymorphicTraits<MyPoly> {
290 /// static NodeKind getKind(const MyPoly &poly) {
291 /// return poly->getKind();
292 /// }
293 /// static MyScalar& getAsScalar(MyPoly &poly) {
294 /// if (!poly || !isa<MyScalar>(poly))
295 /// poly.reset(new MyScalar());
296 /// return *cast<MyScalar>(poly.get());
297 /// }
298 /// // ...
299 /// };
300 template <typename T> struct PolymorphicTraits {
301  // Must provide:
302  // static NodeKind getKind(const T &poly);
303  // static scalar_type &getAsScalar(T &poly);
304  // static map_type &getAsMap(T &poly);
305  // static sequence_type &getAsSequence(T &poly);
306 };
307 
308 // Only used for better diagnostics of missing traits
309 template <typename T>
310 struct MissingTrait;
311 
312 // Test if ScalarEnumerationTraits<T> is defined on type T.
313 template <class T>
314 struct has_ScalarEnumerationTraits
315 {
316  using Signature_enumeration = void (*)(class IO&, T&);
317 
318  template <typename U>
319  static char test(SameType<Signature_enumeration, &U::enumeration>*);
320 
321  template <typename U>
322  static double test(...);
323 
324  static bool const value =
325  (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
326 };
327 
328 // Test if ScalarBitSetTraits<T> is defined on type T.
329 template <class T>
330 struct has_ScalarBitSetTraits
331 {
332  using Signature_bitset = void (*)(class IO&, T&);
333 
334  template <typename U>
335  static char test(SameType<Signature_bitset, &U::bitset>*);
336 
337  template <typename U>
338  static double test(...);
339 
340  static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
341 };
342 
343 // Test if ScalarTraits<T> is defined on type T.
344 template <class T>
345 struct has_ScalarTraits
346 {
347  using Signature_input = StringRef (*)(StringRef, void*, T&);
348  using Signature_output = void (*)(const T&, void*, raw_ostream&);
349  using Signature_mustQuote = QuotingType (*)(StringRef);
350 
351  template <typename U>
352  static char test(SameType<Signature_input, &U::input> *,
353  SameType<Signature_output, &U::output> *,
354  SameType<Signature_mustQuote, &U::mustQuote> *);
355 
356  template <typename U>
357  static double test(...);
358 
359  static bool const value =
360  (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
361 };
362 
363 // Test if BlockScalarTraits<T> is defined on type T.
364 template <class T>
365 struct has_BlockScalarTraits
366 {
367  using Signature_input = StringRef (*)(StringRef, void *, T &);
368  using Signature_output = void (*)(const T &, void *, raw_ostream &);
369 
370  template <typename U>
371  static char test(SameType<Signature_input, &U::input> *,
372  SameType<Signature_output, &U::output> *);
373 
374  template <typename U>
375  static double test(...);
376 
377  static bool const value =
378  (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
379 };
380 
381 // Test if TaggedScalarTraits<T> is defined on type T.
382 template <class T> struct has_TaggedScalarTraits {
383  using Signature_input = StringRef (*)(StringRef, StringRef, void *, T &);
384  using Signature_output = void (*)(const T &, void *, raw_ostream &,
385  raw_ostream &);
386  using Signature_mustQuote = QuotingType (*)(const T &, StringRef);
387 
388  template <typename U>
389  static char test(SameType<Signature_input, &U::input> *,
390  SameType<Signature_output, &U::output> *,
391  SameType<Signature_mustQuote, &U::mustQuote> *);
392 
393  template <typename U> static double test(...);
394 
395  static bool const value =
396  (sizeof(test<TaggedScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
397 };
398 
399 // Test if MappingContextTraits<T> is defined on type T.
400 template <class T, class Context> struct has_MappingTraits {
401  using Signature_mapping = void (*)(class IO &, T &, Context &);
402 
403  template <typename U>
404  static char test(SameType<Signature_mapping, &U::mapping>*);
405 
406  template <typename U>
407  static double test(...);
408 
409  static bool const value =
410  (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
411 };
412 
413 // Test if MappingTraits<T> is defined on type T.
414 template <class T> struct has_MappingTraits<T, EmptyContext> {
415  using Signature_mapping = void (*)(class IO &, T &);
416 
417  template <typename U>
418  static char test(SameType<Signature_mapping, &U::mapping> *);
419 
420  template <typename U> static double test(...);
421 
422  static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
423 };
424 
425 // Test if MappingContextTraits<T>::validate() is defined on type T.
426 template <class T, class Context> struct has_MappingValidateTraits {
427  using Signature_validate = StringRef (*)(class IO &, T &, Context &);
428 
429  template <typename U>
430  static char test(SameType<Signature_validate, &U::validate>*);
431 
432  template <typename U>
433  static double test(...);
434 
435  static bool const value =
436  (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
437 };
438 
439 // Test if MappingTraits<T>::validate() is defined on type T.
440 template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
441  using Signature_validate = StringRef (*)(class IO &, T &);
442 
443  template <typename U>
444  static char test(SameType<Signature_validate, &U::validate> *);
445 
446  template <typename U> static double test(...);
447 
448  static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
449 };
450 
451 // Test if SequenceTraits<T> is defined on type T.
452 template <class T>
453 struct has_SequenceMethodTraits
454 {
455  using Signature_size = size_t (*)(class IO&, T&);
456 
457  template <typename U>
458  static char test(SameType<Signature_size, &U::size>*);
459 
460  template <typename U>
461  static double test(...);
462 
463  static bool const value = (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
464 };
465 
466 // Test if CustomMappingTraits<T> is defined on type T.
467 template <class T>
468 struct has_CustomMappingTraits
469 {
470  using Signature_input = void (*)(IO &io, StringRef key, T &v);
471 
472  template <typename U>
473  static char test(SameType<Signature_input, &U::inputOne>*);
474 
475  template <typename U>
476  static double test(...);
477 
478  static bool const value =
479  (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
480 };
481 
482 // has_FlowTraits<int> will cause an error with some compilers because
483 // it subclasses int. Using this wrapper only instantiates the
484 // real has_FlowTraits only if the template type is a class.
485 template <typename T, bool Enabled = std::is_class<T>::value>
486 class has_FlowTraits
487 {
488 public:
489  static const bool value = false;
490 };
491 
492 // Some older gcc compilers don't support straight forward tests
493 // for members, so test for ambiguity cause by the base and derived
494 // classes both defining the member.
495 template <class T>
496 struct has_FlowTraits<T, true>
497 {
498  struct Fallback { bool flow; };
499  struct Derived : T, Fallback { };
500 
501  template<typename C>
502  static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
503 
504  template<typename C>
505  static char (&f(...))[2];
506 
507  static bool const value = sizeof(f<Derived>(nullptr)) == 2;
508 };
509 
510 // Test if SequenceTraits<T> is defined on type T
511 template<typename T>
512 struct has_SequenceTraits : public std::integral_constant<bool,
513  has_SequenceMethodTraits<T>::value > { };
514 
515 // Test if DocumentListTraits<T> is defined on type T
516 template <class T>
517 struct has_DocumentListTraits
518 {
519  using Signature_size = size_t (*)(class IO &, T &);
520 
521  template <typename U>
522  static char test(SameType<Signature_size, &U::size>*);
523 
524  template <typename U>
525  static double test(...);
526 
527  static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
528 };
529 
530 template <class T> struct has_PolymorphicTraits {
531  using Signature_getKind = NodeKind (*)(const T &);
532 
533  template <typename U>
534  static char test(SameType<Signature_getKind, &U::getKind> *);
535 
536  template <typename U> static double test(...);
537 
538  static bool const value = (sizeof(test<PolymorphicTraits<T>>(nullptr)) == 1);
539 };
540 
541 inline bool isNumeric(StringRef S) {
542  const static auto skipDigits = [](StringRef Input) {
543  return Input.drop_front(
544  std::min(Input.find_first_not_of("0123456789"), Input.size()));
545  };
546 
547  // Make S.front() and S.drop_front().front() (if S.front() is [+-]) calls
548  // safe.
549  if (S.empty() || S.equals("+") || S.equals("-"))
550  return false;
551 
552  if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
553  return true;
554 
555  // Infinity and decimal numbers can be prefixed with sign.
556  StringRef Tail = (S.front() == '-' || S.front() == '+') ? S.drop_front() : S;
557 
558  // Check for infinity first, because checking for hex and oct numbers is more
559  // expensive.
560  if (Tail.equals(".inf") || Tail.equals(".Inf") || Tail.equals(".INF"))
561  return true;
562 
563  // Section 10.3.2 Tag Resolution
564  // YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
565  // [-+], so S should be used instead of Tail.
566  if (S.startswith("0o"))
567  return S.size() > 2 &&
568  S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;
569 
570  if (S.startswith("0x"))
571  return S.size() > 2 && S.drop_front(2).find_first_not_of(
572  "0123456789abcdefABCDEF") == StringRef::npos;
573 
574  // Parse float: [-+]? (\. [0-9]+ | [0-9]+ (\. [0-9]* )?) ([eE] [-+]? [0-9]+)?
575  S = Tail;
576 
577  // Handle cases when the number starts with '.' and hence needs at least one
578  // digit after dot (as opposed by number which has digits before the dot), but
579  // doesn't have one.
580  if (S.startswith(".") &&
581  (S.equals(".") ||
582  (S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
583  return false;
584 
585  if (S.startswith("E") || S.startswith("e"))
586  return false;
587 
588  enum ParseState {
589  Default,
590  FoundDot,
591  FoundExponent,
592  };
593  ParseState State = Default;
594 
595  S = skipDigits(S);
596 
597  // Accept decimal integer.
598  if (S.empty())
599  return true;
600 
601  if (S.front() == '.') {
602  State = FoundDot;
603  S = S.drop_front();
604  } else if (S.front() == 'e' || S.front() == 'E') {
605  State = FoundExponent;
606  S = S.drop_front();
607  } else {
608  return false;
609  }
610 
611  if (State == FoundDot) {
612  S = skipDigits(S);
613  if (S.empty())
614  return true;
615 
616  if (S.front() == 'e' || S.front() == 'E') {
617  State = FoundExponent;
618  S = S.drop_front();
619  } else {
620  return false;
621  }
622  }
623 
624  assert(State == FoundExponent && "Should have found exponent at this point.");
625  if (S.empty())
626  return false;
627 
628  if (S.front() == '+' || S.front() == '-') {
629  S = S.drop_front();
630  if (S.empty())
631  return false;
632  }
633 
634  return skipDigits(S).empty();
635 }
636 
637 inline bool isNull(StringRef S) {
638  return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
639  S.equals("~");
640 }
641 
642 inline bool isBool(StringRef S) {
643  return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
644  S.equals("false") || S.equals("False") || S.equals("FALSE");
645 }
646 
647 // 5.1. Character Set
648 // The allowed character range explicitly excludes the C0 control block #x0-#x1F
649 // (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
650 // control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
651 // block #xD800-#xDFFF, #xFFFE, and #xFFFF.
652 inline QuotingType needsQuotes(StringRef S) {
653  if (S.empty())
654  return QuotingType::Single;
655  if (isspace(S.front()) || isspace(S.back()))
656  return QuotingType::Single;
657  if (isNull(S))
658  return QuotingType::Single;
659  if (isBool(S))
660  return QuotingType::Single;
661  if (isNumeric(S))
662  return QuotingType::Single;
663 
664  // 7.3.3 Plain Style
665  // Plain scalars must not begin with most indicators, as this would cause
666  // ambiguity with other YAML constructs.
667  static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
668  if (S.find_first_of(Indicators) == 0)
669  return QuotingType::Single;
670 
671  QuotingType MaxQuotingNeeded = QuotingType::None;
672  for (unsigned char C : S) {
673  // Alphanum is safe.
674  if (isAlnum(C))
675  continue;
676 
677  switch (C) {
678  // Safe scalar characters.
679  case '_':
680  case '-':
681  case '^':
682  case '.':
683  case ',':
684  case ' ':
685  // TAB (0x9) is allowed in unquoted strings.
686  case 0x9:
687  continue;
688  // LF(0xA) and CR(0xD) may delimit values and so require at least single
689  // quotes.
690  case 0xA:
691  case 0xD:
692  MaxQuotingNeeded = QuotingType::Single;
693  continue;
694  // DEL (0x7F) are excluded from the allowed character range.
695  case 0x7F:
696  return QuotingType::Double;
697  // Forward slash is allowed to be unquoted, but we quote it anyway. We have
698  // many tests that use FileCheck against YAML output, and this output often
699  // contains paths. If we quote backslashes but not forward slashes then
700  // paths will come out either quoted or unquoted depending on which platform
701  // the test is run on, making FileCheck comparisons difficult.
702  case '/':
703  default: {
704  // C0 control block (0x0 - 0x1F) is excluded from the allowed character
705  // range.
706  if (C <= 0x1F)
707  return QuotingType::Double;
708 
709  // Always double quote UTF-8.
710  if ((C & 0x80) != 0)
711  return QuotingType::Double;
712 
713  // The character is not safe, at least simple quoting needed.
714  MaxQuotingNeeded = QuotingType::Single;
715  }
716  }
717  }
718 
719  return MaxQuotingNeeded;
720 }
721 
722 template <typename T, typename Context>
723 struct missingTraits
724  : public std::integral_constant<bool,
725  !has_ScalarEnumerationTraits<T>::value &&
726  !has_ScalarBitSetTraits<T>::value &&
727  !has_ScalarTraits<T>::value &&
728  !has_BlockScalarTraits<T>::value &&
729  !has_TaggedScalarTraits<T>::value &&
730  !has_MappingTraits<T, Context>::value &&
731  !has_SequenceTraits<T>::value &&
732  !has_CustomMappingTraits<T>::value &&
733  !has_DocumentListTraits<T>::value &&
734  !has_PolymorphicTraits<T>::value> {};
735 
736 template <typename T, typename Context>
737 struct validatedMappingTraits
738  : public std::integral_constant<
739  bool, has_MappingTraits<T, Context>::value &&
740  has_MappingValidateTraits<T, Context>::value> {};
741 
742 template <typename T, typename Context>
743 struct unvalidatedMappingTraits
744  : public std::integral_constant<
745  bool, has_MappingTraits<T, Context>::value &&
746  !has_MappingValidateTraits<T, Context>::value> {};
747 
748 // Base class for Input and Output.
749 class IO {
750 public:
751  IO(void *Ctxt = nullptr);
752  virtual ~IO();
753 
754  virtual bool outputting() = 0;
755 
756  virtual unsigned beginSequence() = 0;
757  virtual bool preflightElement(unsigned, void *&) = 0;
758  virtual void postflightElement(void*) = 0;
759  virtual void endSequence() = 0;
760  virtual bool canElideEmptySequence() = 0;
761 
762  virtual unsigned beginFlowSequence() = 0;
763  virtual bool preflightFlowElement(unsigned, void *&) = 0;
764  virtual void postflightFlowElement(void*) = 0;
765  virtual void endFlowSequence() = 0;
766 
767  virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
768  virtual void beginMapping() = 0;
769  virtual void endMapping() = 0;
770  virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
771  virtual void postflightKey(void*) = 0;
772  virtual std::vector<StringRef> keys() = 0;
773 
774  virtual void beginFlowMapping() = 0;
775  virtual void endFlowMapping() = 0;
776 
777  virtual void beginEnumScalar() = 0;
778  virtual bool matchEnumScalar(const char*, bool) = 0;
779  virtual bool matchEnumFallback() = 0;
780  virtual void endEnumScalar() = 0;
781 
782  virtual bool beginBitSetScalar(bool &) = 0;
783  virtual bool bitSetMatch(const char*, bool) = 0;
784  virtual void endBitSetScalar() = 0;
785 
786  virtual void scalarString(StringRef &, QuotingType) = 0;
787  virtual void blockScalarString(StringRef &) = 0;
788  virtual void scalarTag(std::string &) = 0;
789 
790  virtual NodeKind getNodeKind() = 0;
791 
792  virtual void setError(const Twine &) = 0;
793 
794  template <typename T>
795  void enumCase(T &Val, const char* Str, const T ConstVal) {
796  if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
797  Val = ConstVal;
798  }
799  }
800 
801  // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
802  template <typename T>
803  void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
804  if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
805  Val = ConstVal;
806  }
807  }
808 
809  template <typename FBT, typename T>
810  void enumFallback(T &Val) {
811  if (matchEnumFallback()) {
812  EmptyContext Context;
813  // FIXME: Force integral conversion to allow strong typedefs to convert.
814  FBT Res = static_cast<typename FBT::BaseType>(Val);
815  yamlize(*this, Res, true, Context);
816  Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
817  }
818  }
819 
820  template <typename T>
821  void bitSetCase(T &Val, const char* Str, const T ConstVal) {
822  if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
823  Val = static_cast<T>(Val | ConstVal);
824  }
825  }
826 
827  // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
828  template <typename T>
829  void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
830  if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
831  Val = static_cast<T>(Val | ConstVal);
832  }
833  }
834 
835  template <typename T>
836  void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
837  if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
838  Val = Val | ConstVal;
839  }
840 
841  template <typename T>
842  void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
843  uint32_t Mask) {
844  if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
845  Val = Val | ConstVal;
846  }
847 
848  void *getContext();
849  void setContext(void *);
850 
851  template <typename T> void mapRequired(const char *Key, T &Val) {
852  EmptyContext Ctx;
853  this->processKey(Key, Val, true, Ctx);
854  }
855 
856  template <typename T, typename Context>
857  void mapRequired(const char *Key, T &Val, Context &Ctx) {
858  this->processKey(Key, Val, true, Ctx);
859  }
860 
861  template <typename T> void mapOptional(const char *Key, T &Val) {
862  EmptyContext Ctx;
863  mapOptionalWithContext(Key, Val, Ctx);
864  }
865 
866  template <typename T>
867  void mapOptional(const char *Key, T &Val, const T &Default) {
868  EmptyContext Ctx;
869  mapOptionalWithContext(Key, Val, Default, Ctx);
870  }
871 
872  template <typename T, typename Context>
873  typename std::enable_if<has_SequenceTraits<T>::value, void>::type
874  mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
875  // omit key/value instead of outputting empty sequence
876  if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
877  return;
878  this->processKey(Key, Val, false, Ctx);
879  }
880 
881  template <typename T, typename Context>
882  void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
883  this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
884  Ctx);
885  }
886 
887  template <typename T, typename Context>
888  typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
889  mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
890  this->processKey(Key, Val, false, Ctx);
891  }
892 
893  template <typename T, typename Context>
894  void mapOptionalWithContext(const char *Key, T &Val, const T &Default,
895  Context &Ctx) {
896  this->processKeyWithDefault(Key, Val, Default, false, Ctx);
897  }
898 
899 private:
900  template <typename T, typename Context>
901  void processKeyWithDefault(const char *Key, Optional<T> &Val,
902  const Optional<T> &DefaultValue, bool Required,
903  Context &Ctx) {
904  assert(DefaultValue.hasValue() == false &&
905  "Optional<T> shouldn't have a value!");
906  void *SaveInfo;
907  bool UseDefault = true;
908  const bool sameAsDefault = outputting() && !Val.hasValue();
909  if (!outputting() && !Val.hasValue())
910  Val = T();
911  if (Val.hasValue() &&
912  this->preflightKey(Key, Required, sameAsDefault, UseDefault,
913  SaveInfo)) {
914  yamlize(*this, Val.getValue(), Required, Ctx);
915  this->postflightKey(SaveInfo);
916  } else {
917  if (UseDefault)
918  Val = DefaultValue;
919  }
920  }
921 
922  template <typename T, typename Context>
923  void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
924  bool Required, Context &Ctx) {
925  void *SaveInfo;
926  bool UseDefault;
927  const bool sameAsDefault = outputting() && Val == DefaultValue;
928  if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
929  SaveInfo) ) {
930  yamlize(*this, Val, Required, Ctx);
931  this->postflightKey(SaveInfo);
932  }
933  else {
934  if ( UseDefault )
935  Val = DefaultValue;
936  }
937  }
938 
939  template <typename T, typename Context>
940  void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
941  void *SaveInfo;
942  bool UseDefault;
943  if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
944  yamlize(*this, Val, Required, Ctx);
945  this->postflightKey(SaveInfo);
946  }
947  }
948 
949 private:
950  void *Ctxt;
951 };
952 
953 namespace detail {
954 
955 template <typename T, typename Context>
956 void doMapping(IO &io, T &Val, Context &Ctx) {
957  MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
958 }
959 
960 template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
961  MappingTraits<T>::mapping(io, Val);
962 }
963 
964 } // end namespace detail
965 
966 template <typename T>
967 typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
968 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
969  io.beginEnumScalar();
970  ScalarEnumerationTraits<T>::enumeration(io, Val);
971  io.endEnumScalar();
972 }
973 
974 template <typename T>
975 typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
976 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
977  bool DoClear;
978  if ( io.beginBitSetScalar(DoClear) ) {
979  if ( DoClear )
980  Val = static_cast<T>(0);
981  ScalarBitSetTraits<T>::bitset(io, Val);
982  io.endBitSetScalar();
983  }
984 }
985 
986 template <typename T>
987 typename std::enable_if<has_ScalarTraits<T>::value, void>::type
988 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
989  if ( io.outputting() ) {
990  std::string Storage;
991  raw_string_ostream Buffer(Storage);
992  ScalarTraits<T>::output(Val, io.getContext(), Buffer);
993  StringRef Str = Buffer.str();
994  io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
995  }
996  else {
997  StringRef Str;
998  io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
999  StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1000  if ( !Result.empty() ) {
1001  io.setError(Twine(Result));
1002  }
1003  }
1004 }
1005 
1006 template <typename T>
1007 typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
1008 yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
1009  if (YamlIO.outputting()) {
1010  std::string Storage;
1011  raw_string_ostream Buffer(Storage);
1012  BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1013  StringRef Str = Buffer.str();
1014  YamlIO.blockScalarString(Str);
1015  } else {
1016  StringRef Str;
1017  YamlIO.blockScalarString(Str);
1018  StringRef Result =
1019  BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1020  if (!Result.empty())
1021  YamlIO.setError(Twine(Result));
1022  }
1023 }
1024 
1025 template <typename T>
1026 typename std::enable_if<has_TaggedScalarTraits<T>::value, void>::type
1027 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1028  if (io.outputting()) {
1029  std::string ScalarStorage, TagStorage;
1030  raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1031  TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1032  TagBuffer);
1033  io.scalarTag(TagBuffer.str());
1034  StringRef ScalarStr = ScalarBuffer.str();
1035  io.scalarString(ScalarStr,
1036  TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1037  } else {
1038  std::string Tag;
1039  io.scalarTag(Tag);
1040  StringRef Str;
1041  io.scalarString(Str, QuotingType::None);
1042  StringRef Result =
1043  TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1044  if (!Result.empty()) {
1045  io.setError(Twine(Result));
1046  }
1047  }
1048 }
1049 
1050 template <typename T, typename Context>
1051 typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
1052 yamlize(IO &io, T &Val, bool, Context &Ctx) {
1053  if (has_FlowTraits<MappingTraits<T>>::value)
1054  io.beginFlowMapping();
1055  else
1056  io.beginMapping();
1057  if (io.outputting()) {
1058  StringRef Err = MappingTraits<T>::validate(io, Val);
1059  if (!Err.empty()) {
1060  errs() << Err << "\n";
1061  assert(Err.empty() && "invalid struct trying to be written as yaml");
1062  }
1063  }
1064  detail::doMapping(io, Val, Ctx);
1065  if (!io.outputting()) {
1066  StringRef Err = MappingTraits<T>::validate(io, Val);
1067  if (!Err.empty())
1068  io.setError(Err);
1069  }
1070  if (has_FlowTraits<MappingTraits<T>>::value)
1071  io.endFlowMapping();
1072  else
1073  io.endMapping();
1074 }
1075 
1076 template <typename T, typename Context>
1077 typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
1078 yamlize(IO &io, T &Val, bool, Context &Ctx) {
1079  if (has_FlowTraits<MappingTraits<T>>::value) {
1080  io.beginFlowMapping();
1081  detail::doMapping(io, Val, Ctx);
1082  io.endFlowMapping();
1083  } else {
1084  io.beginMapping();
1085  detail::doMapping(io, Val, Ctx);
1086  io.endMapping();
1087  }
1088 }
1089 
1090 template <typename T>
1091 typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
1092 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1093  if ( io.outputting() ) {
1094  io.beginMapping();
1095  CustomMappingTraits<T>::output(io, Val);
1096  io.endMapping();
1097  } else {
1098  io.beginMapping();
1099  for (StringRef key : io.keys())
1100  CustomMappingTraits<T>::inputOne(io, key, Val);
1101  io.endMapping();
1102  }
1103 }
1104 
1105 template <typename T>
1106 typename std::enable_if<has_PolymorphicTraits<T>::value, void>::type
1107 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1108  switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1109  : io.getNodeKind()) {
1110  case NodeKind::Scalar:
1111  return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val), true, Ctx);
1112  case NodeKind::Map:
1113  return yamlize(io, PolymorphicTraits<T>::getAsMap(Val), true, Ctx);
1114  case NodeKind::Sequence:
1115  return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val), true, Ctx);
1116  }
1117 }
1118 
1119 template <typename T>
1120 typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
1121 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1122  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1123 }
1124 
1125 template <typename T, typename Context>
1126 typename std::enable_if<has_SequenceTraits<T>::value, void>::type
1127 yamlize(IO &io, T &Seq, bool, Context &Ctx) {
1128  if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1129  unsigned incnt = io.beginFlowSequence();
1130  unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1131  for(unsigned i=0; i < count; ++i) {
1132  void *SaveInfo;
1133  if ( io.preflightFlowElement(i, SaveInfo) ) {
1134  yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1135  io.postflightFlowElement(SaveInfo);
1136  }
1137  }
1138  io.endFlowSequence();
1139  }
1140  else {
1141  unsigned incnt = io.beginSequence();
1142  unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1143  for(unsigned i=0; i < count; ++i) {
1144  void *SaveInfo;
1145  if ( io.preflightElement(i, SaveInfo) ) {
1146  yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1147  io.postflightElement(SaveInfo);
1148  }
1149  }
1150  io.endSequence();
1151  }
1152 }
1153 
1154 template<>
1155 struct ScalarTraits<bool> {
1156  static void output(const bool &, void* , raw_ostream &);
1157  static StringRef input(StringRef, void *, bool &);
1158  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1159 };
1160 
1161 template<>
1162 struct ScalarTraits<StringRef> {
1163  static void output(const StringRef &, void *, raw_ostream &);
1164  static StringRef input(StringRef, void *, StringRef &);
1165  static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1166 };
1167 
1168 template<>
1169 struct ScalarTraits<std::string> {
1170  static void output(const std::string &, void *, raw_ostream &);
1171  static StringRef input(StringRef, void *, std::string &);
1172  static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1173 };
1174 
1175 template<>
1176 struct ScalarTraits<uint8_t> {
1177  static void output(const uint8_t &, void *, raw_ostream &);
1178  static StringRef input(StringRef, void *, uint8_t &);
1179  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1180 };
1181 
1182 template<>
1183 struct ScalarTraits<uint16_t> {
1184  static void output(const uint16_t &, void *, raw_ostream &);
1185  static StringRef input(StringRef, void *, uint16_t &);
1186  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1187 };
1188 
1189 template<>
1190 struct ScalarTraits<uint32_t> {
1191  static void output(const uint32_t &, void *, raw_ostream &);
1192  static StringRef input(StringRef, void *, uint32_t &);
1193  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1194 };
1195 
1196 template<>
1197 struct ScalarTraits<uint64_t> {
1198  static void output(const uint64_t &, void *, raw_ostream &);
1199  static StringRef input(StringRef, void *, uint64_t &);
1200  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1201 };
1202 
1203 template<>
1204 struct ScalarTraits<int8_t> {
1205  static void output(const int8_t &, void *, raw_ostream &);
1206  static StringRef input(StringRef, void *, int8_t &);
1207  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1208 };
1209 
1210 template<>
1211 struct ScalarTraits<int16_t> {
1212  static void output(const int16_t &, void *, raw_ostream &);
1213  static StringRef input(StringRef, void *, int16_t &);
1214  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1215 };
1216 
1217 template<>
1218 struct ScalarTraits<int32_t> {
1219  static void output(const int32_t &, void *, raw_ostream &);
1220  static StringRef input(StringRef, void *, int32_t &);
1221  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1222 };
1223 
1224 template<>
1225 struct ScalarTraits<int64_t> {
1226  static void output(const int64_t &, void *, raw_ostream &);
1227  static StringRef input(StringRef, void *, int64_t &);
1228  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1229 };
1230 
1231 template<>
1232 struct ScalarTraits<float> {
1233  static void output(const float &, void *, raw_ostream &);
1234  static StringRef input(StringRef, void *, float &);
1235  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1236 };
1237 
1238 template<>
1239 struct ScalarTraits<double> {
1240  static void output(const double &, void *, raw_ostream &);
1241  static StringRef input(StringRef, void *, double &);
1242  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1243 };
1244 
1245 // For endian types, we just use the existing ScalarTraits for the underlying
1246 // type. This way endian aware types are supported whenever a ScalarTraits
1247 // is defined for the underlying type.
1248 template <typename value_type, support::endianness endian, size_t alignment>
1249 struct ScalarTraits<support::detail::packed_endian_specific_integral<
1250  value_type, endian, alignment>> {
1251  using endian_type =
1252  support::detail::packed_endian_specific_integral<value_type, endian,
1253  alignment>;
1254 
1255  static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1256  ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1257  }
1258 
1259  static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1260  value_type V;
1261  auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1262  E = static_cast<endian_type>(V);
1263  return R;
1264  }
1265 
1266  static QuotingType mustQuote(StringRef Str) {
1267  return ScalarTraits<value_type>::mustQuote(Str);
1268  }
1269 };
1270 
1271 // Utility for use within MappingTraits<>::mapping() method
1272 // to [de]normalize an object for use with YAML conversion.
1273 template <typename TNorm, typename TFinal>
1274 struct MappingNormalization {
1275  MappingNormalization(IO &i_o, TFinal &Obj)
1276  : io(i_o), BufPtr(nullptr), Result(Obj) {
1277  if ( io.outputting() ) {
1278  BufPtr = new (&Buffer) TNorm(io, Obj);
1279  }
1280  else {
1281  BufPtr = new (&Buffer) TNorm(io);
1282  }
1283  }
1284 
1285  ~MappingNormalization() {
1286  if ( ! io.outputting() ) {
1287  Result = BufPtr->denormalize(io);
1288  }
1289  BufPtr->~TNorm();
1290  }
1291 
1292  TNorm* operator->() { return BufPtr; }
1293 
1294 private:
1295  using Storage = AlignedCharArrayUnion<TNorm>;
1296 
1297  Storage Buffer;
1298  IO &io;
1299  TNorm *BufPtr;
1300  TFinal &Result;
1301 };
1302 
1303 // Utility for use within MappingTraits<>::mapping() method
1304 // to [de]normalize an object for use with YAML conversion.
1305 template <typename TNorm, typename TFinal>
1306 struct MappingNormalizationHeap {
1307  MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1308  : io(i_o), Result(Obj) {
1309  if ( io.outputting() ) {
1310  BufPtr = new (&Buffer) TNorm(io, Obj);
1311  }
1312  else if (allocator) {
1313  BufPtr = allocator->Allocate<TNorm>();
1314  new (BufPtr) TNorm(io);
1315  } else {
1316  BufPtr = new TNorm(io);
1317  }
1318  }
1319 
1320  ~MappingNormalizationHeap() {
1321  if ( io.outputting() ) {
1322  BufPtr->~TNorm();
1323  }
1324  else {
1325  Result = BufPtr->denormalize(io);
1326  }
1327  }
1328 
1329  TNorm* operator->() { return BufPtr; }
1330 
1331 private:
1332  using Storage = AlignedCharArrayUnion<TNorm>;
1333 
1334  Storage Buffer;
1335  IO &io;
1336  TNorm *BufPtr = nullptr;
1337  TFinal &Result;
1338 };
1339 
1340 ///
1341 /// The Input class is used to parse a yaml document into in-memory structs
1342 /// and vectors.
1343 ///
1344 /// It works by using YAMLParser to do a syntax parse of the entire yaml
1345 /// document, then the Input class builds a graph of HNodes which wraps
1346 /// each yaml Node. The extra layer is buffering. The low level yaml
1347 /// parser only lets you look at each node once. The buffering layer lets
1348 /// you search and interate multiple times. This is necessary because
1349 /// the mapRequired() method calls may not be in the same order
1350 /// as the keys in the document.
1351 ///
1352 class Input : public IO {
1353 public:
1354  // Construct a yaml Input object from a StringRef and optional
1355  // user-data. The DiagHandler can be specified to provide
1356  // alternative error reporting.
1357  Input(StringRef InputContent,
1358  void *Ctxt = nullptr,
1359  SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1360  void *DiagHandlerCtxt = nullptr);
1361  Input(MemoryBufferRef Input,
1362  void *Ctxt = nullptr,
1363  SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1364  void *DiagHandlerCtxt = nullptr);
1365  ~Input() override;
1366 
1367  // Check if there was an syntax or semantic error during parsing.
1368  std::error_code error();
1369 
1370 private:
1371  bool outputting() override;
1372  bool mapTag(StringRef, bool) override;
1373  void beginMapping() override;
1374  void endMapping() override;
1375  bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1376  void postflightKey(void *) override;
1377  std::vector<StringRef> keys() override;
1378  void beginFlowMapping() override;
1379  void endFlowMapping() override;
1380  unsigned beginSequence() override;
1381  void endSequence() override;
1382  bool preflightElement(unsigned index, void *&) override;
1383  void postflightElement(void *) override;
1384  unsigned beginFlowSequence() override;
1385  bool preflightFlowElement(unsigned , void *&) override;
1386  void postflightFlowElement(void *) override;
1387  void endFlowSequence() override;
1388  void beginEnumScalar() override;
1389  bool matchEnumScalar(const char*, bool) override;
1390  bool matchEnumFallback() override;
1391  void endEnumScalar() override;
1392  bool beginBitSetScalar(bool &) override;
1393  bool bitSetMatch(const char *, bool ) override;
1394  void endBitSetScalar() override;
1395  void scalarString(StringRef &, QuotingType) override;
1396  void blockScalarString(StringRef &) override;
1397  void scalarTag(std::string &) override;
1398  NodeKind getNodeKind() override;
1399  void setError(const Twine &message) override;
1400  bool canElideEmptySequence() override;
1401 
1402  class HNode {
1403  virtual void anchor();
1404 
1405  public:
1406  HNode(Node *n) : _node(n) { }
1407  virtual ~HNode() = default;
1408 
1409  static bool classof(const HNode *) { return true; }
1410 
1411  Node *_node;
1412  };
1413 
1414  class EmptyHNode : public HNode {
1415  void anchor() override;
1416 
1417  public:
1418  EmptyHNode(Node *n) : HNode(n) { }
1419 
1420  static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1421 
1422  static bool classof(const EmptyHNode *) { return true; }
1423  };
1424 
1425  class ScalarHNode : public HNode {
1426  void anchor() override;
1427 
1428  public:
1429  ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1430 
1431  StringRef value() const { return _value; }
1432 
1433  static bool classof(const HNode *n) {
1434  return ScalarNode::classof(n->_node) ||
1435  BlockScalarNode::classof(n->_node);
1436  }
1437 
1438  static bool classof(const ScalarHNode *) { return true; }
1439 
1440  protected:
1441  StringRef _value;
1442  };
1443 
1444  class MapHNode : public HNode {
1445  void anchor() override;
1446 
1447  public:
1448  MapHNode(Node *n) : HNode(n) { }
1449 
1450  static bool classof(const HNode *n) {
1451  return MappingNode::classof(n->_node);
1452  }
1453 
1454  static bool classof(const MapHNode *) { return true; }
1455 
1456  using NameToNode = StringMap<std::unique_ptr<HNode>>;
1457 
1458  NameToNode Mapping;
1459  SmallVector<std::string, 6> ValidKeys;
1460  };
1461 
1462  class SequenceHNode : public HNode {
1463  void anchor() override;
1464 
1465  public:
1466  SequenceHNode(Node *n) : HNode(n) { }
1467 
1468  static bool classof(const HNode *n) {
1469  return SequenceNode::classof(n->_node);
1470  }
1471 
1472  static bool classof(const SequenceHNode *) { return true; }
1473 
1474  std::vector<std::unique_ptr<HNode>> Entries;
1475  };
1476 
1477  std::unique_ptr<Input::HNode> createHNodes(Node *node);
1478  void setError(HNode *hnode, const Twine &message);
1479  void setError(Node *node, const Twine &message);
1480 
1481 public:
1482  // These are only used by operator>>. They could be private
1483  // if those templated things could be made friends.
1484  bool setCurrentDocument();
1485  bool nextDocument();
1486 
1487  /// Returns the current node that's being parsed by the YAML Parser.
1488  const Node *getCurrentNode() const;
1489 
1490 private:
1491  SourceMgr SrcMgr; // must be before Strm
1492  std::unique_ptr<llvm::yaml::Stream> Strm;
1493  std::unique_ptr<HNode> TopNode;
1494  std::error_code EC;
1495  BumpPtrAllocator StringAllocator;
1496  document_iterator DocIterator;
1497  std::vector<bool> BitValuesUsed;
1498  HNode *CurrentNode = nullptr;
1499  bool ScalarMatchFound;
1500 };
1501 
1502 ///
1503 /// The Output class is used to generate a yaml document from in-memory structs
1504 /// and vectors.
1505 ///
1506 class Output : public IO {
1507 public:
1508  Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1509  ~Output() override;
1510 
1511  /// Set whether or not to output optional values which are equal
1512  /// to the default value. By default, when outputting if you attempt
1513  /// to write a value that is equal to the default, the value gets ignored.
1514  /// Sometimes, it is useful to be able to see these in the resulting YAML
1515  /// anyway.
1516  void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1517 
1518  bool outputting() override;
1519  bool mapTag(StringRef, bool) override;
1520  void beginMapping() override;
1521  void endMapping() override;
1522  bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1523  void postflightKey(void *) override;
1524  std::vector<StringRef> keys() override;
1525  void beginFlowMapping() override;
1526  void endFlowMapping() override;
1527  unsigned beginSequence() override;
1528  void endSequence() override;
1529  bool preflightElement(unsigned, void *&) override;
1530  void postflightElement(void *) override;
1531  unsigned beginFlowSequence() override;
1532  bool preflightFlowElement(unsigned, void *&) override;
1533  void postflightFlowElement(void *) override;
1534  void endFlowSequence() override;
1535  void beginEnumScalar() override;
1536  bool matchEnumScalar(const char*, bool) override;
1537  bool matchEnumFallback() override;
1538  void endEnumScalar() override;
1539  bool beginBitSetScalar(bool &) override;
1540  bool bitSetMatch(const char *, bool ) override;
1541  void endBitSetScalar() override;
1542  void scalarString(StringRef &, QuotingType) override;
1543  void blockScalarString(StringRef &) override;
1544  void scalarTag(std::string &) override;
1545  NodeKind getNodeKind() override;
1546  void setError(const Twine &message) override;
1547  bool canElideEmptySequence() override;
1548 
1549  // These are only used by operator<<. They could be private
1550  // if that templated operator could be made a friend.
1551  void beginDocuments();
1552  bool preflightDocument(unsigned);
1553  void postflightDocument();
1554  void endDocuments();
1555 
1556 private:
1557  void output(StringRef s);
1558  void outputUpToEndOfLine(StringRef s);
1559  void newLineCheck();
1560  void outputNewLine();
1561  void paddedKey(StringRef key);
1562  void flowKey(StringRef Key);
1563 
1564  enum InState {
1565  inSeqFirstElement,
1566  inSeqOtherElement,
1567  inFlowSeqFirstElement,
1568  inFlowSeqOtherElement,
1569  inMapFirstKey,
1570  inMapOtherKey,
1571  inFlowMapFirstKey,
1572  inFlowMapOtherKey
1573  };
1574 
1575  static bool inSeqAnyElement(InState State);
1576  static bool inFlowSeqAnyElement(InState State);
1577  static bool inMapAnyKey(InState State);
1578  static bool inFlowMapAnyKey(InState State);
1579 
1580  raw_ostream &Out;
1581  int WrapColumn;
1582  SmallVector<InState, 8> StateStack;
1583  int Column = 0;
1584  int ColumnAtFlowStart = 0;
1585  int ColumnAtMapFlowStart = 0;
1586  bool NeedBitValueComma = false;
1587  bool NeedFlowSequenceComma = false;
1588  bool EnumerationMatchFound = false;
1589  bool NeedsNewLine = false;
1590  bool WriteDefaultValues = false;
1591 };
1592 
1593 /// YAML I/O does conversion based on types. But often native data types
1594 /// are just a typedef of built in intergral types (e.g. int). But the C++
1595 /// type matching system sees through the typedef and all the typedefed types
1596 /// look like a built in type. This will cause the generic YAML I/O conversion
1597 /// to be used. To provide better control over the YAML conversion, you can
1598 /// use this macro instead of typedef. It will create a class with one field
1599 /// and automatic conversion operators to and from the base type.
1600 /// Based on BOOST_STRONG_TYPEDEF
1601 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type) \
1602  struct _type { \
1603  _type() = default; \
1604  _type(const _base v) : value(v) {} \
1605  _type(const _type &v) = default; \
1606  _type &operator=(const _type &rhs) = default; \
1607  _type &operator=(const _base &rhs) { value = rhs; return *this; } \
1608  operator const _base & () const { return value; } \
1609  bool operator==(const _type &rhs) const { return value == rhs.value; } \
1610  bool operator==(const _base &rhs) const { return value == rhs; } \
1611  bool operator<(const _type &rhs) const { return value < rhs.value; } \
1612  _base value; \
1613  using BaseType = _base; \
1614  };
1615 
1616 ///
1617 /// Use these types instead of uintXX_t in any mapping to have
1618 /// its yaml output formatted as hexadecimal.
1619 ///
1620 LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
1621 LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
1622 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
1623 LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
1624 
1625 template<>
1626 struct ScalarTraits<Hex8> {
1627  static void output(const Hex8 &, void *, raw_ostream &);
1628  static StringRef input(StringRef, void *, Hex8 &);
1629  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1630 };
1631 
1632 template<>
1633 struct ScalarTraits<Hex16> {
1634  static void output(const Hex16 &, void *, raw_ostream &);
1635  static StringRef input(StringRef, void *, Hex16 &);
1636  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1637 };
1638 
1639 template<>
1640 struct ScalarTraits<Hex32> {
1641  static void output(const Hex32 &, void *, raw_ostream &);
1642  static StringRef input(StringRef, void *, Hex32 &);
1643  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1644 };
1645 
1646 template<>
1647 struct ScalarTraits<Hex64> {
1648  static void output(const Hex64 &, void *, raw_ostream &);
1649  static StringRef input(StringRef, void *, Hex64 &);
1650  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1651 };
1652 
1653 // Define non-member operator>> so that Input can stream in a document list.
1654 template <typename T>
1655 inline
1656 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1657 operator>>(Input &yin, T &docList) {
1658  int i = 0;
1659  EmptyContext Ctx;
1660  while ( yin.setCurrentDocument() ) {
1661  yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1662  if ( yin.error() )
1663  return yin;
1664  yin.nextDocument();
1665  ++i;
1666  }
1667  return yin;
1668 }
1669 
1670 // Define non-member operator>> so that Input can stream in a map as a document.
1671 template <typename T>
1672 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1673  Input &>::type
1674 operator>>(Input &yin, T &docMap) {
1675  EmptyContext Ctx;
1676  yin.setCurrentDocument();
1677  yamlize(yin, docMap, true, Ctx);
1678  return yin;
1679 }
1680 
1681 // Define non-member operator>> so that Input can stream in a sequence as
1682 // a document.
1683 template <typename T>
1684 inline
1685 typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1686 operator>>(Input &yin, T &docSeq) {
1687  EmptyContext Ctx;
1688  if (yin.setCurrentDocument())
1689  yamlize(yin, docSeq, true, Ctx);
1690  return yin;
1691 }
1692 
1693 // Define non-member operator>> so that Input can stream in a block scalar.
1694 template <typename T>
1695 inline
1696 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1697 operator>>(Input &In, T &Val) {
1698  EmptyContext Ctx;
1699  if (In.setCurrentDocument())
1700  yamlize(In, Val, true, Ctx);
1701  return In;
1702 }
1703 
1704 // Define non-member operator>> so that Input can stream in a string map.
1705 template <typename T>
1706 inline
1707 typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
1708 operator>>(Input &In, T &Val) {
1709  EmptyContext Ctx;
1710  if (In.setCurrentDocument())
1711  yamlize(In, Val, true, Ctx);
1712  return In;
1713 }
1714 
1715 // Define non-member operator>> so that Input can stream in a polymorphic type.
1716 template <typename T>
1717 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Input &>::type
1718 operator>>(Input &In, T &Val) {
1719  EmptyContext Ctx;
1720  if (In.setCurrentDocument())
1721  yamlize(In, Val, true, Ctx);
1722  return In;
1723 }
1724 
1725 // Provide better error message about types missing a trait specialization
1726 template <typename T>
1727 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1728  Input &>::type
1729 operator>>(Input &yin, T &docSeq) {
1730  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1731  return yin;
1732 }
1733 
1734 // Define non-member operator<< so that Output can stream out document list.
1735 template <typename T>
1736 inline
1737 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1738 operator<<(Output &yout, T &docList) {
1739  EmptyContext Ctx;
1740  yout.beginDocuments();
1741  const size_t count = DocumentListTraits<T>::size(yout, docList);
1742  for(size_t i=0; i < count; ++i) {
1743  if ( yout.preflightDocument(i) ) {
1744  yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1745  Ctx);
1746  yout.postflightDocument();
1747  }
1748  }
1749  yout.endDocuments();
1750  return yout;
1751 }
1752 
1753 // Define non-member operator<< so that Output can stream out a map.
1754 template <typename T>
1755 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1756  Output &>::type
1757 operator<<(Output &yout, T &map) {
1758  EmptyContext Ctx;
1759  yout.beginDocuments();
1760  if ( yout.preflightDocument(0) ) {
1761  yamlize(yout, map, true, Ctx);
1762  yout.postflightDocument();
1763  }
1764  yout.endDocuments();
1765  return yout;
1766 }
1767 
1768 // Define non-member operator<< so that Output can stream out a sequence.
1769 template <typename T>
1770 inline
1771 typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1772 operator<<(Output &yout, T &seq) {
1773  EmptyContext Ctx;
1774  yout.beginDocuments();
1775  if ( yout.preflightDocument(0) ) {
1776  yamlize(yout, seq, true, Ctx);
1777  yout.postflightDocument();
1778  }
1779  yout.endDocuments();
1780  return yout;
1781 }
1782 
1783 // Define non-member operator<< so that Output can stream out a block scalar.
1784 template <typename T>
1785 inline
1786 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1787 operator<<(Output &Out, T &Val) {
1788  EmptyContext Ctx;
1789  Out.beginDocuments();
1790  if (Out.preflightDocument(0)) {
1791  yamlize(Out, Val, true, Ctx);
1792  Out.postflightDocument();
1793  }
1794  Out.endDocuments();
1795  return Out;
1796 }
1797 
1798 // Define non-member operator<< so that Output can stream out a string map.
1799 template <typename T>
1800 inline
1801 typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
1802 operator<<(Output &Out, T &Val) {
1803  EmptyContext Ctx;
1804  Out.beginDocuments();
1805  if (Out.preflightDocument(0)) {
1806  yamlize(Out, Val, true, Ctx);
1807  Out.postflightDocument();
1808  }
1809  Out.endDocuments();
1810  return Out;
1811 }
1812 
1813 // Define non-member operator<< so that Output can stream out a polymorphic
1814 // type.
1815 template <typename T>
1816 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Output &>::type
1817 operator<<(Output &Out, T &Val) {
1818  EmptyContext Ctx;
1819  Out.beginDocuments();
1820  if (Out.preflightDocument(0)) {
1821  // FIXME: The parser does not support explicit documents terminated with a
1822  // plain scalar; the end-marker is included as part of the scalar token.
1823  assert(PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && "plain scalar documents are not supported");
1824  yamlize(Out, Val, true, Ctx);
1825  Out.postflightDocument();
1826  }
1827  Out.endDocuments();
1828  return Out;
1829 }
1830 
1831 // Provide better error message about types missing a trait specialization
1832 template <typename T>
1833 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1834  Output &>::type
1835 operator<<(Output &yout, T &seq) {
1836  char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1837  return yout;
1838 }
1839 
1840 template <bool B> struct IsFlowSequenceBase {};
1841 template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1842 
1843 template <typename T, bool Flow>
1844 struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1845 private:
1846  using type = typename T::value_type;
1847 
1848 public:
1849  static size_t size(IO &io, T &seq) { return seq.size(); }
1850 
1851  static type &element(IO &io, T &seq, size_t index) {
1852  if (index >= seq.size())
1853  seq.resize(index + 1);
1854  return seq[index];
1855  }
1856 };
1857 
1858 // Simple helper to check an expression can be used as a bool-valued template
1859 // argument.
1860 template <bool> struct CheckIsBool { static const bool value = true; };
1861 
1862 // If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1863 // SequenceTraits that do the obvious thing.
1864 template <typename T>
1865 struct SequenceTraits<std::vector<T>,
1866  typename std::enable_if<CheckIsBool<
1867  SequenceElementTraits<T>::flow>::value>::type>
1868  : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1869 template <typename T, unsigned N>
1870 struct SequenceTraits<SmallVector<T, N>,
1871  typename std::enable_if<CheckIsBool<
1872  SequenceElementTraits<T>::flow>::value>::type>
1873  : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1874 
1875 // Sequences of fundamental types use flow formatting.
1876 template <typename T>
1877 struct SequenceElementTraits<
1878  T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
1879  static const bool flow = true;
1880 };
1881 
1882 // Sequences of strings use block formatting.
1883 template<> struct SequenceElementTraits<std::string> {
1884  static const bool flow = false;
1885 };
1886 template<> struct SequenceElementTraits<StringRef> {
1887  static const bool flow = false;
1888 };
1889 template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1890  static const bool flow = false;
1891 };
1892 
1893 /// Implementation of CustomMappingTraits for std::map<std::string, T>.
1894 template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1895  using map_type = std::map<std::string, T>;
1896 
1897  static void inputOne(IO &io, StringRef key, map_type &v) {
1898  io.mapRequired(key.str().c_str(), v[key]);
1899  }
1900 
1901  static void output(IO &io, map_type &v) {
1902  for (auto &p : v)
1903  io.mapRequired(p.first.c_str(), p.second);
1904  }
1905 };
1906 
1907 } // end namespace yaml
1908 } // end namespace llvm
1909 
1910 #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW) \
1911  namespace llvm { \
1912  namespace yaml { \
1913  static_assert( \
1914  !std::is_fundamental<TYPE>::value && \
1915  !std::is_same<TYPE, std::string>::value && \
1916  !std::is_same<TYPE, llvm::StringRef>::value, \
1917  "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control"); \
1918  template <> struct SequenceElementTraits<TYPE> { \
1919  static const bool flow = FLOW; \
1920  }; \
1921  } \
1922  }
1923 
1924 /// Utility for declaring that a std::vector of a particular type
1925 /// should be considered a YAML sequence.
1926 #define LLVM_YAML_IS_SEQUENCE_VECTOR(type) \
1927  LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
1928 
1929 /// Utility for declaring that a std::vector of a particular type
1930 /// should be considered a YAML flow sequence.
1931 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type) \
1932  LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
1933 
1934 #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type) \
1935  namespace llvm { \
1936  namespace yaml { \
1937  template <> struct MappingTraits<Type> { \
1938  static void mapping(IO &IO, Type &Obj); \
1939  }; \
1940  } \
1941  }
1942 
1943 #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type) \
1944  namespace llvm { \
1945  namespace yaml { \
1946  template <> struct ScalarEnumerationTraits<Type> { \
1947  static void enumeration(IO &io, Type &Value); \
1948  }; \
1949  } \
1950  }
1951 
1952 #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type) \
1953  namespace llvm { \
1954  namespace yaml { \
1955  template <> struct ScalarBitSetTraits<Type> { \
1956  static void bitset(IO &IO, Type &Options); \
1957  }; \
1958  } \
1959  }
1960 
1961 #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote) \
1962  namespace llvm { \
1963  namespace yaml { \
1964  template <> struct ScalarTraits<Type> { \
1965  static void output(const Type &Value, void *ctx, raw_ostream &Out); \
1966  static StringRef input(StringRef Scalar, void *ctxt, Type &Value); \
1967  static QuotingType mustQuote(StringRef) { return MustQuote; } \
1968  }; \
1969  } \
1970  }
1971 
1972 /// Utility for declaring that a std::vector of a particular type
1973 /// should be considered a YAML document list.
1974 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type) \
1975  namespace llvm { \
1976  namespace yaml { \
1977  template <unsigned N> \
1978  struct DocumentListTraits<SmallVector<_type, N>> \
1979  : public SequenceTraitsImpl<SmallVector<_type, N>, false> {}; \
1980  template <> \
1981  struct DocumentListTraits<std::vector<_type>> \
1982  : public SequenceTraitsImpl<std::vector<_type>, false> {}; \
1983  } \
1984  }
1985 
1986 /// Utility for declaring that std::map<std::string, _type> should be considered
1987 /// a YAML map.
1988 #define LLVM_YAML_IS_STRING_MAP(_type) \
1989  namespace llvm { \
1990  namespace yaml { \
1991  template <> \
1992  struct CustomMappingTraits<std::map<std::string, _type>> \
1993  : public StdMapStringCustomMappingTraitsImpl<_type> {}; \
1994  } \
1995  }
1996 
1997 #endif // LLVM_SUPPORT_YAMLTRAITS_H
static bool classof(const Node *N)
Definition: YAMLParser.h:431
const NoneType None
Definition: None.h:23
uint64_t CallInst * C
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
SourceMgr SrcMgr
Definition: Error.cpp:23
#define error(X)
block Block Frequency true
static bool classof(const Node *N)
Definition: YAMLParser.h:488
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
Definition: BitVector.h:937
bool isAlnum(char C)
Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...
Definition: StringExtras.h:88
static bool classof(const Node *N)
Definition: YAMLParser.h:264
Key
PAL metadata keys.
#define T
static bool classof(const Node *N)
Definition: YAMLParser.h:230
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(adl_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:1251
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition: Allocator.h:434
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Determine the kind of a node from its type.
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
Definition: SourceMgr.h:53
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1166
iterator_range< detail::value_sequence_iterator< ValueT > > seq(ValueT Begin, ValueT End)
Definition: Sequence.h:75
static bool classof(const Node *N)
Definition: YAMLParser.h:198
static const size_t npos
Definition: StringRef.h:50
#define N
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
Definition: PtrState.h:40
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:2038
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
ScaledNumber< DigitsT > operator>>(const ScaledNumber< DigitsT > &L, int16_t Shift)
Definition: ScaledNumber.h:736