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