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"
23 #include "llvm/Support/YAMLParser.h"
24 #include "llvm/Support/raw_ostream.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, typename Enable = void> struct ScalarEnumerationTraits {
105   // Must provide:
106   // static void enumeration(IO &io, T &value);
107 };
108 
109 /// This class should be specialized by any integer type that is a union
110 /// of bit values and the YAML representation is a flow sequence of
111 /// strings.  For example:
112 ///
113 ///      struct ScalarBitSetTraits<MyFlags> {
114 ///        static void bitset(IO &io, MyFlags &value) {
115 ///          io.bitSetCase(value, "big",   flagBig);
116 ///          io.bitSetCase(value, "flat",  flagFlat);
117 ///          io.bitSetCase(value, "round", flagRound);
118 ///        }
119 ///      };
120 template <typename T, typename Enable = void> struct ScalarBitSetTraits {
121   // Must provide:
122   // static void bitset(IO &io, T &value);
123 };
124 
125 /// Describe which type of quotes should be used when quoting is necessary.
126 /// Some non-printable characters need to be double-quoted, while some others
127 /// are fine with simple-quoting, and some don't need any quoting.
128 enum class QuotingType { None, Single, Double };
129 
130 /// This class should be specialized by type that requires custom conversion
131 /// to/from a yaml scalar.  For example:
132 ///
133 ///    template<>
134 ///    struct ScalarTraits<MyType> {
135 ///      static void output(const MyType &val, void*, llvm::raw_ostream &out) {
136 ///        // stream out custom formatting
137 ///        out << llvm::format("%x", val);
138 ///      }
139 ///      static StringRef input(StringRef scalar, void*, MyType &value) {
140 ///        // parse scalar and set `value`
141 ///        // return empty string on success, or error string
142 ///        return StringRef();
143 ///      }
144 ///      static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
145 ///    };
146 template <typename T, typename Enable = void> struct ScalarTraits {
147   // Must provide:
148   //
149   // Function to write the value as a string:
150   // static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
151   //
152   // Function to convert a string to a value.  Returns the empty
153   // StringRef on success or an error string if string is malformed:
154   // static StringRef input(StringRef scalar, void *ctxt, T &value);
155   //
156   // Function to determine if the value should be quoted.
157   // static QuotingType mustQuote(StringRef);
158 };
159 
160 /// This class should be specialized by type that requires custom conversion
161 /// to/from a YAML literal block scalar. For example:
162 ///
163 ///    template <>
164 ///    struct BlockScalarTraits<MyType> {
165 ///      static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
166 ///      {
167 ///        // stream out custom formatting
168 ///        Out << Value;
169 ///      }
170 ///      static StringRef input(StringRef Scalar, void*, MyType &Value) {
171 ///        // parse scalar and set `value`
172 ///        // return empty string on success, or error string
173 ///        return StringRef();
174 ///      }
175 ///    };
176 template <typename T>
177 struct BlockScalarTraits {
178   // Must provide:
179   //
180   // Function to write the value as a string:
181   // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
182   //
183   // Function to convert a string to a value.  Returns the empty
184   // StringRef on success or an error string if string is malformed:
185   // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
186   //
187   // Optional:
188   // static StringRef inputTag(T &Val, std::string Tag)
189   // static void outputTag(const T &Val, raw_ostream &Out)
190 };
191 
192 /// This class should be specialized by type that requires custom conversion
193 /// to/from a YAML scalar with optional tags. For example:
194 ///
195 ///    template <>
196 ///    struct TaggedScalarTraits<MyType> {
197 ///      static void output(const MyType &Value, void*, llvm::raw_ostream
198 ///      &ScalarOut, llvm::raw_ostream &TagOut)
199 ///      {
200 ///        // stream out custom formatting including optional Tag
201 ///        Out << Value;
202 ///      }
203 ///      static StringRef input(StringRef Scalar, StringRef Tag, void*, MyType
204 ///      &Value) {
205 ///        // parse scalar and set `value`
206 ///        // return empty string on success, or error string
207 ///        return StringRef();
208 ///      }
209 ///      static QuotingType mustQuote(const MyType &Value, StringRef) {
210 ///        return QuotingType::Single;
211 ///      }
212 ///    };
213 template <typename T> struct TaggedScalarTraits {
214   // Must provide:
215   //
216   // Function to write the value and tag as strings:
217   // static void output(const T &Value, void *ctx, llvm::raw_ostream &ScalarOut,
218   // llvm::raw_ostream &TagOut);
219   //
220   // Function to convert a string to a value.  Returns the empty
221   // StringRef on success or an error string if string is malformed:
222   // static StringRef input(StringRef Scalar, StringRef Tag, void *ctxt, T
223   // &Value);
224   //
225   // Function to determine if the value should be quoted.
226   // static QuotingType mustQuote(const T &Value, StringRef Scalar);
227 };
228 
229 /// This class should be specialized by any type that needs to be converted
230 /// to/from a YAML sequence.  For example:
231 ///
232 ///    template<>
233 ///    struct SequenceTraits<MyContainer> {
234 ///      static size_t size(IO &io, MyContainer &seq) {
235 ///        return seq.size();
236 ///      }
237 ///      static MyType& element(IO &, MyContainer &seq, size_t index) {
238 ///        if ( index >= seq.size() )
239 ///          seq.resize(index+1);
240 ///        return seq[index];
241 ///      }
242 ///    };
243 template<typename T, typename EnableIf = void>
244 struct SequenceTraits {
245   // Must provide:
246   // static size_t size(IO &io, T &seq);
247   // static T::value_type& element(IO &io, T &seq, size_t index);
248   //
249   // The following is option and will cause generated YAML to use
250   // a flow sequence (e.g. [a,b,c]).
251   // static const bool flow = true;
252 };
253 
254 /// This class should be specialized by any type for which vectors of that
255 /// type need to be converted to/from a YAML sequence.
256 template<typename T, typename EnableIf = void>
257 struct SequenceElementTraits {
258   // Must provide:
259   // static const bool flow;
260 };
261 
262 /// This class should be specialized by any type that needs to be converted
263 /// to/from a list of YAML documents.
264 template<typename T>
265 struct DocumentListTraits {
266   // Must provide:
267   // static size_t size(IO &io, T &seq);
268   // static T::value_type& element(IO &io, T &seq, size_t index);
269 };
270 
271 /// This class should be specialized by any type that needs to be converted
272 /// to/from a YAML mapping in the case where the names of the keys are not known
273 /// in advance, e.g. a string map.
274 template <typename T>
275 struct CustomMappingTraits {
276   // static void inputOne(IO &io, StringRef key, T &elem);
277   // static void output(IO &io, T &elem);
278 };
279 
280 /// This class should be specialized by any type that can be represented as
281 /// a scalar, map, or sequence, decided dynamically. For example:
282 ///
283 ///    typedef std::unique_ptr<MyBase> MyPoly;
284 ///
285 ///    template<>
286 ///    struct PolymorphicTraits<MyPoly> {
287 ///      static NodeKind getKind(const MyPoly &poly) {
288 ///        return poly->getKind();
289 ///      }
290 ///      static MyScalar& getAsScalar(MyPoly &poly) {
291 ///        if (!poly || !isa<MyScalar>(poly))
292 ///          poly.reset(new MyScalar());
293 ///        return *cast<MyScalar>(poly.get());
294 ///      }
295 ///      // ...
296 ///    };
297 template <typename T> struct PolymorphicTraits {
298   // Must provide:
299   // static NodeKind getKind(const T &poly);
300   // static scalar_type &getAsScalar(T &poly);
301   // static map_type &getAsMap(T &poly);
302   // static sequence_type &getAsSequence(T &poly);
303 };
304 
305 // Only used for better diagnostics of missing traits
306 template <typename T>
307 struct MissingTrait;
308 
309 // Test if ScalarEnumerationTraits<T> is defined on type T.
310 template <class T>
311 struct has_ScalarEnumerationTraits
312 {
313   using Signature_enumeration = void (*)(class IO&, T&);
314 
315   template <typename U>
316   static char test(SameType<Signature_enumeration, &U::enumeration>*);
317 
318   template <typename U>
319   static double test(...);
320 
321   static bool const value =
322     (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
323 };
324 
325 // Test if ScalarBitSetTraits<T> is defined on type T.
326 template <class T>
327 struct has_ScalarBitSetTraits
328 {
329   using Signature_bitset = void (*)(class IO&, T&);
330 
331   template <typename U>
332   static char test(SameType<Signature_bitset, &U::bitset>*);
333 
334   template <typename U>
335   static double test(...);
336 
337   static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
338 };
339 
340 // Test if ScalarTraits<T> is defined on type T.
341 template <class T>
342 struct has_ScalarTraits
343 {
344   using Signature_input = StringRef (*)(StringRef, void*, T&);
345   using Signature_output = void (*)(const T&, void*, raw_ostream&);
346   using Signature_mustQuote = QuotingType (*)(StringRef);
347 
348   template <typename U>
349   static char test(SameType<Signature_input, &U::input> *,
350                    SameType<Signature_output, &U::output> *,
351                    SameType<Signature_mustQuote, &U::mustQuote> *);
352 
353   template <typename U>
354   static double test(...);
355 
356   static bool const value =
357       (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
358 };
359 
360 // Test if BlockScalarTraits<T> is defined on type T.
361 template <class T>
362 struct has_BlockScalarTraits
363 {
364   using Signature_input = StringRef (*)(StringRef, void *, T &);
365   using Signature_output = void (*)(const T &, void *, raw_ostream &);
366 
367   template <typename U>
368   static char test(SameType<Signature_input, &U::input> *,
369                    SameType<Signature_output, &U::output> *);
370 
371   template <typename U>
372   static double test(...);
373 
374   static bool const value =
375       (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
376 };
377 
378 // Test if TaggedScalarTraits<T> is defined on type T.
379 template <class T> struct has_TaggedScalarTraits {
380   using Signature_input = StringRef (*)(StringRef, StringRef, void *, T &);
381   using Signature_output = void (*)(const T &, void *, raw_ostream &,
382                                     raw_ostream &);
383   using Signature_mustQuote = QuotingType (*)(const T &, StringRef);
384 
385   template <typename U>
386   static char test(SameType<Signature_input, &U::input> *,
387                    SameType<Signature_output, &U::output> *,
388                    SameType<Signature_mustQuote, &U::mustQuote> *);
389 
390   template <typename U> static double test(...);
391 
392   static bool const value =
393       (sizeof(test<TaggedScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
394 };
395 
396 // Test if MappingContextTraits<T> is defined on type T.
397 template <class T, class Context> struct has_MappingTraits {
398   using Signature_mapping = void (*)(class IO &, T &, Context &);
399 
400   template <typename U>
401   static char test(SameType<Signature_mapping, &U::mapping>*);
402 
403   template <typename U>
404   static double test(...);
405 
406   static bool const value =
407       (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
408 };
409 
410 // Test if MappingTraits<T> is defined on type T.
411 template <class T> struct has_MappingTraits<T, EmptyContext> {
412   using Signature_mapping = void (*)(class IO &, T &);
413 
414   template <typename U>
415   static char test(SameType<Signature_mapping, &U::mapping> *);
416 
417   template <typename U> static double test(...);
418 
419   static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
420 };
421 
422 // Test if MappingContextTraits<T>::validate() is defined on type T.
423 template <class T, class Context> struct has_MappingValidateTraits {
424   using Signature_validate = StringRef (*)(class IO &, T &, Context &);
425 
426   template <typename U>
427   static char test(SameType<Signature_validate, &U::validate>*);
428 
429   template <typename U>
430   static double test(...);
431 
432   static bool const value =
433       (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
434 };
435 
436 // Test if MappingTraits<T>::validate() is defined on type T.
437 template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
438   using Signature_validate = StringRef (*)(class IO &, T &);
439 
440   template <typename U>
441   static char test(SameType<Signature_validate, &U::validate> *);
442 
443   template <typename U> static double test(...);
444 
445   static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
446 };
447 
448 // Test if SequenceTraits<T> is defined on type T.
449 template <class T>
450 struct has_SequenceMethodTraits
451 {
452   using Signature_size = size_t (*)(class IO&, T&);
453 
454   template <typename U>
455   static char test(SameType<Signature_size, &U::size>*);
456 
457   template <typename U>
458   static double test(...);
459 
460   static bool const value =  (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
461 };
462 
463 // Test if CustomMappingTraits<T> is defined on type T.
464 template <class T>
465 struct has_CustomMappingTraits
466 {
467   using Signature_input = void (*)(IO &io, StringRef key, T &v);
468 
469   template <typename U>
470   static char test(SameType<Signature_input, &U::inputOne>*);
471 
472   template <typename U>
473   static double test(...);
474 
475   static bool const value =
476       (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
477 };
478 
479 // has_FlowTraits<int> will cause an error with some compilers because
480 // it subclasses int.  Using this wrapper only instantiates the
481 // real has_FlowTraits only if the template type is a class.
482 template <typename T, bool Enabled = std::is_class<T>::value>
483 class has_FlowTraits
484 {
485 public:
486    static const bool value = false;
487 };
488 
489 // Some older gcc compilers don't support straight forward tests
490 // for members, so test for ambiguity cause by the base and derived
491 // classes both defining the member.
492 template <class T>
493 struct has_FlowTraits<T, true>
494 {
495   struct Fallback { bool flow; };
496   struct Derived : T, Fallback { };
497 
498   template<typename C>
499   static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
500 
501   template<typename C>
502   static char (&f(...))[2];
503 
504   static bool const value = sizeof(f<Derived>(nullptr)) == 2;
505 };
506 
507 // Test if SequenceTraits<T> is defined on type T
508 template<typename T>
509 struct has_SequenceTraits : public std::integral_constant<bool,
510                                       has_SequenceMethodTraits<T>::value > { };
511 
512 // Test if DocumentListTraits<T> is defined on type T
513 template <class T>
514 struct has_DocumentListTraits
515 {
516   using Signature_size = size_t (*)(class IO &, T &);
517 
518   template <typename U>
519   static char test(SameType<Signature_size, &U::size>*);
520 
521   template <typename U>
522   static double test(...);
523 
524   static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
525 };
526 
527 template <class T> struct has_PolymorphicTraits {
528   using Signature_getKind = NodeKind (*)(const T &);
529 
530   template <typename U>
531   static char test(SameType<Signature_getKind, &U::getKind> *);
532 
533   template <typename U> static double test(...);
534 
535   static bool const value = (sizeof(test<PolymorphicTraits<T>>(nullptr)) == 1);
536 };
537 
538 inline bool isNumeric(StringRef S) {
539   const static auto skipDigits = [](StringRef Input) {
540     return Input.drop_front(
541         std::min(Input.find_first_not_of("0123456789"), Input.size()));
542   };
543 
544   // Make S.front() and S.drop_front().front() (if S.front() is [+-]) calls
545   // safe.
546   if (S.empty() || S.equals("+") || S.equals("-"))
547     return false;
548 
549   if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
550     return true;
551 
552   // Infinity and decimal numbers can be prefixed with sign.
553   StringRef Tail = (S.front() == '-' || S.front() == '+') ? S.drop_front() : S;
554 
555   // Check for infinity first, because checking for hex and oct numbers is more
556   // expensive.
557   if (Tail.equals(".inf") || Tail.equals(".Inf") || Tail.equals(".INF"))
558     return true;
559 
560   // Section 10.3.2 Tag Resolution
561   // YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
562   // [-+], so S should be used instead of Tail.
563   if (S.startswith("0o"))
564     return S.size() > 2 &&
565            S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;
566 
567   if (S.startswith("0x"))
568     return S.size() > 2 && S.drop_front(2).find_first_not_of(
569                                "0123456789abcdefABCDEF") == StringRef::npos;
570 
571   // Parse float: [-+]? (\. [0-9]+ | [0-9]+ (\. [0-9]* )?) ([eE] [-+]? [0-9]+)?
572   S = Tail;
573 
574   // Handle cases when the number starts with '.' and hence needs at least one
575   // digit after dot (as opposed by number which has digits before the dot), but
576   // doesn't have one.
577   if (S.startswith(".") &&
578       (S.equals(".") ||
579        (S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
580     return false;
581 
582   if (S.startswith("E") || S.startswith("e"))
583     return false;
584 
585   enum ParseState {
586     Default,
587     FoundDot,
588     FoundExponent,
589   };
590   ParseState State = Default;
591 
592   S = skipDigits(S);
593 
594   // Accept decimal integer.
595   if (S.empty())
596     return true;
597 
598   if (S.front() == '.') {
599     State = FoundDot;
600     S = S.drop_front();
601   } else if (S.front() == 'e' || S.front() == 'E') {
602     State = FoundExponent;
603     S = S.drop_front();
604   } else {
605     return false;
606   }
607 
608   if (State == FoundDot) {
609     S = skipDigits(S);
610     if (S.empty())
611       return true;
612 
613     if (S.front() == 'e' || S.front() == 'E') {
614       State = FoundExponent;
615       S = S.drop_front();
616     } else {
617       return false;
618     }
619   }
620 
621   assert(State == FoundExponent && "Should have found exponent at this point.");
622   if (S.empty())
623     return false;
624 
625   if (S.front() == '+' || S.front() == '-') {
626     S = S.drop_front();
627     if (S.empty())
628       return false;
629   }
630 
631   return skipDigits(S).empty();
632 }
633 
634 inline bool isNull(StringRef S) {
635   return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
636          S.equals("~");
637 }
638 
639 inline bool isBool(StringRef S) {
640   return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
641          S.equals("false") || S.equals("False") || S.equals("FALSE");
642 }
643 
644 // 5.1. Character Set
645 // The allowed character range explicitly excludes the C0 control block #x0-#x1F
646 // (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
647 // control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
648 // block #xD800-#xDFFF, #xFFFE, and #xFFFF.
649 inline QuotingType needsQuotes(StringRef S) {
650   if (S.empty())
651     return QuotingType::Single;
652   if (isspace(S.front()) || isspace(S.back()))
653     return QuotingType::Single;
654   if (isNull(S))
655     return QuotingType::Single;
656   if (isBool(S))
657     return QuotingType::Single;
658   if (isNumeric(S))
659     return QuotingType::Single;
660 
661   // 7.3.3 Plain Style
662   // Plain scalars must not begin with most indicators, as this would cause
663   // ambiguity with other YAML constructs.
664   static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
665   if (S.find_first_of(Indicators) == 0)
666     return QuotingType::Single;
667 
668   QuotingType MaxQuotingNeeded = QuotingType::None;
669   for (unsigned char C : S) {
670     // Alphanum is safe.
671     if (isAlnum(C))
672       continue;
673 
674     switch (C) {
675     // Safe scalar characters.
676     case '_':
677     case '-':
678     case '^':
679     case '.':
680     case ',':
681     case ' ':
682     // TAB (0x9) is allowed in unquoted strings.
683     case 0x9:
684       continue;
685     // LF(0xA) and CR(0xD) may delimit values and so require at least single
686     // quotes.
687     case 0xA:
688     case 0xD:
689       MaxQuotingNeeded = QuotingType::Single;
690       continue;
691     // DEL (0x7F) are excluded from the allowed character range.
692     case 0x7F:
693       return QuotingType::Double;
694     // Forward slash is allowed to be unquoted, but we quote it anyway.  We have
695     // many tests that use FileCheck against YAML output, and this output often
696     // contains paths.  If we quote backslashes but not forward slashes then
697     // paths will come out either quoted or unquoted depending on which platform
698     // the test is run on, making FileCheck comparisons difficult.
699     case '/':
700     default: {
701       // C0 control block (0x0 - 0x1F) is excluded from the allowed character
702       // range.
703       if (C <= 0x1F)
704         return QuotingType::Double;
705 
706       // Always double quote UTF-8.
707       if ((C & 0x80) != 0)
708         return QuotingType::Double;
709 
710       // The character is not safe, at least simple quoting needed.
711       MaxQuotingNeeded = QuotingType::Single;
712     }
713     }
714   }
715 
716   return MaxQuotingNeeded;
717 }
718 
719 template <typename T, typename Context>
720 struct missingTraits
721     : public std::integral_constant<bool,
722                                     !has_ScalarEnumerationTraits<T>::value &&
723                                         !has_ScalarBitSetTraits<T>::value &&
724                                         !has_ScalarTraits<T>::value &&
725                                         !has_BlockScalarTraits<T>::value &&
726                                         !has_TaggedScalarTraits<T>::value &&
727                                         !has_MappingTraits<T, Context>::value &&
728                                         !has_SequenceTraits<T>::value &&
729                                         !has_CustomMappingTraits<T>::value &&
730                                         !has_DocumentListTraits<T>::value &&
731                                         !has_PolymorphicTraits<T>::value> {};
732 
733 template <typename T, typename Context>
734 struct validatedMappingTraits
735     : public std::integral_constant<
736           bool, has_MappingTraits<T, Context>::value &&
737                     has_MappingValidateTraits<T, Context>::value> {};
738 
739 template <typename T, typename Context>
740 struct unvalidatedMappingTraits
741     : public std::integral_constant<
742           bool, has_MappingTraits<T, Context>::value &&
743                     !has_MappingValidateTraits<T, Context>::value> {};
744 
745 // Base class for Input and Output.
746 class IO {
747 public:
748   IO(void *Ctxt = nullptr);
749   virtual ~IO();
750 
751   virtual bool outputting() = 0;
752 
753   virtual unsigned beginSequence() = 0;
754   virtual bool preflightElement(unsigned, void *&) = 0;
755   virtual void postflightElement(void*) = 0;
756   virtual void endSequence() = 0;
757   virtual bool canElideEmptySequence() = 0;
758 
759   virtual unsigned beginFlowSequence() = 0;
760   virtual bool preflightFlowElement(unsigned, void *&) = 0;
761   virtual void postflightFlowElement(void*) = 0;
762   virtual void endFlowSequence() = 0;
763 
764   virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
765   virtual void beginMapping() = 0;
766   virtual void endMapping() = 0;
767   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
768   virtual void postflightKey(void*) = 0;
769   virtual std::vector<StringRef> keys() = 0;
770 
771   virtual void beginFlowMapping() = 0;
772   virtual void endFlowMapping() = 0;
773 
774   virtual void beginEnumScalar() = 0;
775   virtual bool matchEnumScalar(const char*, bool) = 0;
776   virtual bool matchEnumFallback() = 0;
777   virtual void endEnumScalar() = 0;
778 
779   virtual bool beginBitSetScalar(bool &) = 0;
780   virtual bool bitSetMatch(const char*, bool) = 0;
781   virtual void endBitSetScalar() = 0;
782 
783   virtual void scalarString(StringRef &, QuotingType) = 0;
784   virtual void blockScalarString(StringRef &) = 0;
785   virtual void scalarTag(std::string &) = 0;
786 
787   virtual NodeKind getNodeKind() = 0;
788 
789   virtual void setError(const Twine &) = 0;
790 
791   template <typename T>
792   void enumCase(T &Val, const char* Str, const T ConstVal) {
793     if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
794       Val = ConstVal;
795     }
796   }
797 
798   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
799   template <typename T>
800   void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
801     if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
802       Val = ConstVal;
803     }
804   }
805 
806   template <typename FBT, typename T>
807   void enumFallback(T &Val) {
808     if (matchEnumFallback()) {
809       EmptyContext Context;
810       // FIXME: Force integral conversion to allow strong typedefs to convert.
811       FBT Res = static_cast<typename FBT::BaseType>(Val);
812       yamlize(*this, Res, true, Context);
813       Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
814     }
815   }
816 
817   template <typename T>
818   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
819     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
820       Val = static_cast<T>(Val | ConstVal);
821     }
822   }
823 
824   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
825   template <typename T>
826   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
827     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
828       Val = static_cast<T>(Val | ConstVal);
829     }
830   }
831 
832   template <typename T>
833   void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
834     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
835       Val = Val | ConstVal;
836   }
837 
838   template <typename T>
839   void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
840                         uint32_t Mask) {
841     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
842       Val = Val | ConstVal;
843   }
844 
845   void *getContext();
846   void setContext(void *);
847 
848   template <typename T> void mapRequired(const char *Key, T &Val) {
849     EmptyContext Ctx;
850     this->processKey(Key, Val, true, Ctx);
851   }
852 
853   template <typename T, typename Context>
854   void mapRequired(const char *Key, T &Val, Context &Ctx) {
855     this->processKey(Key, Val, true, Ctx);
856   }
857 
858   template <typename T> void mapOptional(const char *Key, T &Val) {
859     EmptyContext Ctx;
860     mapOptionalWithContext(Key, Val, Ctx);
861   }
862 
863   template <typename T, typename DefaultT>
864   void mapOptional(const char *Key, T &Val, const DefaultT &Default) {
865     EmptyContext Ctx;
866     mapOptionalWithContext(Key, Val, Default, Ctx);
867   }
868 
869   template <typename T, typename Context>
870   typename std::enable_if<has_SequenceTraits<T>::value, void>::type
871   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
872     // omit key/value instead of outputting empty sequence
873     if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
874       return;
875     this->processKey(Key, Val, false, Ctx);
876   }
877 
878   template <typename T, typename Context>
879   void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
880     this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
881                                 Ctx);
882   }
883 
884   template <typename T, typename Context>
885   typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
886   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
887     this->processKey(Key, Val, false, Ctx);
888   }
889 
890   template <typename T, typename Context, typename DefaultT>
891   void mapOptionalWithContext(const char *Key, T &Val, const DefaultT &Default,
892                               Context &Ctx) {
893     static_assert(std::is_convertible<DefaultT, T>::value,
894                   "Default type must be implicitly convertible to value type!");
895     this->processKeyWithDefault(Key, Val, static_cast<const T &>(Default),
896                                 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 = T();
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 use existing scalar Traits class for the underlying
1246 // type.  This way endian aware types are supported whenever the traits are
1247 // defined for the underlying type.
1248 template <typename value_type, support::endianness endian, size_t alignment>
1249 struct ScalarTraits<
1250     support::detail::packed_endian_specific_integral<value_type, endian,
1251                                                      alignment>,
1252     typename std::enable_if<has_ScalarTraits<value_type>::value>::type> {
1253   using endian_type =
1254       support::detail::packed_endian_specific_integral<value_type, endian,
1255                                                        alignment>;
1256 
1257   static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1258     ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1259   }
1260 
1261   static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1262     value_type V;
1263     auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1264     E = static_cast<endian_type>(V);
1265     return R;
1266   }
1267 
1268   static QuotingType mustQuote(StringRef Str) {
1269     return ScalarTraits<value_type>::mustQuote(Str);
1270   }
1271 };
1272 
1273 template <typename value_type, support::endianness endian, size_t alignment>
1274 struct ScalarEnumerationTraits<
1275     support::detail::packed_endian_specific_integral<value_type, endian,
1276                                                      alignment>,
1277     typename std::enable_if<
1278         has_ScalarEnumerationTraits<value_type>::value>::type> {
1279   using endian_type =
1280       support::detail::packed_endian_specific_integral<value_type, endian,
1281                                                        alignment>;
1282 
1283   static void enumeration(IO &io, endian_type &E) {
1284     value_type V = E;
1285     ScalarEnumerationTraits<value_type>::enumeration(io, V);
1286     E = V;
1287   }
1288 };
1289 
1290 template <typename value_type, support::endianness endian, size_t alignment>
1291 struct ScalarBitSetTraits<
1292     support::detail::packed_endian_specific_integral<value_type, endian,
1293                                                      alignment>,
1294     typename std::enable_if<has_ScalarBitSetTraits<value_type>::value>::type> {
1295   using endian_type =
1296       support::detail::packed_endian_specific_integral<value_type, endian,
1297                                                        alignment>;
1298   static void bitset(IO &io, endian_type &E) {
1299     value_type V = E;
1300     ScalarBitSetTraits<value_type>::bitset(io, V);
1301     E = V;
1302   }
1303 };
1304 
1305 // Utility for use within MappingTraits<>::mapping() method
1306 // to [de]normalize an object for use with YAML conversion.
1307 template <typename TNorm, typename TFinal>
1308 struct MappingNormalization {
1309   MappingNormalization(IO &i_o, TFinal &Obj)
1310       : io(i_o), BufPtr(nullptr), Result(Obj) {
1311     if ( io.outputting() ) {
1312       BufPtr = new (&Buffer) TNorm(io, Obj);
1313     }
1314     else {
1315       BufPtr = new (&Buffer) TNorm(io);
1316     }
1317   }
1318 
1319   ~MappingNormalization() {
1320     if ( ! io.outputting() ) {
1321       Result = BufPtr->denormalize(io);
1322     }
1323     BufPtr->~TNorm();
1324   }
1325 
1326   TNorm* operator->() { return BufPtr; }
1327 
1328 private:
1329   using Storage = AlignedCharArrayUnion<TNorm>;
1330 
1331   Storage       Buffer;
1332   IO           &io;
1333   TNorm        *BufPtr;
1334   TFinal       &Result;
1335 };
1336 
1337 // Utility for use within MappingTraits<>::mapping() method
1338 // to [de]normalize an object for use with YAML conversion.
1339 template <typename TNorm, typename TFinal>
1340 struct MappingNormalizationHeap {
1341   MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1342     : io(i_o), Result(Obj) {
1343     if ( io.outputting() ) {
1344       BufPtr = new (&Buffer) TNorm(io, Obj);
1345     }
1346     else if (allocator) {
1347       BufPtr = allocator->Allocate<TNorm>();
1348       new (BufPtr) TNorm(io);
1349     } else {
1350       BufPtr = new TNorm(io);
1351     }
1352   }
1353 
1354   ~MappingNormalizationHeap() {
1355     if ( io.outputting() ) {
1356       BufPtr->~TNorm();
1357     }
1358     else {
1359       Result = BufPtr->denormalize(io);
1360     }
1361   }
1362 
1363   TNorm* operator->() { return BufPtr; }
1364 
1365 private:
1366   using Storage = AlignedCharArrayUnion<TNorm>;
1367 
1368   Storage       Buffer;
1369   IO           &io;
1370   TNorm        *BufPtr = nullptr;
1371   TFinal       &Result;
1372 };
1373 
1374 ///
1375 /// The Input class is used to parse a yaml document into in-memory structs
1376 /// and vectors.
1377 ///
1378 /// It works by using YAMLParser to do a syntax parse of the entire yaml
1379 /// document, then the Input class builds a graph of HNodes which wraps
1380 /// each yaml Node.  The extra layer is buffering.  The low level yaml
1381 /// parser only lets you look at each node once.  The buffering layer lets
1382 /// you search and interate multiple times.  This is necessary because
1383 /// the mapRequired() method calls may not be in the same order
1384 /// as the keys in the document.
1385 ///
1386 class Input : public IO {
1387 public:
1388   // Construct a yaml Input object from a StringRef and optional
1389   // user-data. The DiagHandler can be specified to provide
1390   // alternative error reporting.
1391   Input(StringRef InputContent,
1392         void *Ctxt = nullptr,
1393         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1394         void *DiagHandlerCtxt = nullptr);
1395   Input(MemoryBufferRef Input,
1396         void *Ctxt = nullptr,
1397         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1398         void *DiagHandlerCtxt = nullptr);
1399   ~Input() override;
1400 
1401   // Check if there was an syntax or semantic error during parsing.
1402   std::error_code error();
1403 
1404 private:
1405   bool outputting() override;
1406   bool mapTag(StringRef, bool) override;
1407   void beginMapping() override;
1408   void endMapping() override;
1409   bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1410   void postflightKey(void *) override;
1411   std::vector<StringRef> keys() override;
1412   void beginFlowMapping() override;
1413   void endFlowMapping() override;
1414   unsigned beginSequence() override;
1415   void endSequence() override;
1416   bool preflightElement(unsigned index, void *&) override;
1417   void postflightElement(void *) override;
1418   unsigned beginFlowSequence() override;
1419   bool preflightFlowElement(unsigned , void *&) override;
1420   void postflightFlowElement(void *) override;
1421   void endFlowSequence() override;
1422   void beginEnumScalar() override;
1423   bool matchEnumScalar(const char*, bool) override;
1424   bool matchEnumFallback() override;
1425   void endEnumScalar() override;
1426   bool beginBitSetScalar(bool &) override;
1427   bool bitSetMatch(const char *, bool ) override;
1428   void endBitSetScalar() override;
1429   void scalarString(StringRef &, QuotingType) override;
1430   void blockScalarString(StringRef &) override;
1431   void scalarTag(std::string &) override;
1432   NodeKind getNodeKind() override;
1433   void setError(const Twine &message) override;
1434   bool canElideEmptySequence() override;
1435 
1436   class HNode {
1437     virtual void anchor();
1438 
1439   public:
1440     HNode(Node *n) : _node(n) { }
1441     virtual ~HNode() = default;
1442 
1443     static bool classof(const HNode *) { return true; }
1444 
1445     Node *_node;
1446   };
1447 
1448   class EmptyHNode : public HNode {
1449     void anchor() override;
1450 
1451   public:
1452     EmptyHNode(Node *n) : HNode(n) { }
1453 
1454     static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1455 
1456     static bool classof(const EmptyHNode *) { return true; }
1457   };
1458 
1459   class ScalarHNode : public HNode {
1460     void anchor() override;
1461 
1462   public:
1463     ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1464 
1465     StringRef value() const { return _value; }
1466 
1467     static bool classof(const HNode *n) {
1468       return ScalarNode::classof(n->_node) ||
1469              BlockScalarNode::classof(n->_node);
1470     }
1471 
1472     static bool classof(const ScalarHNode *) { return true; }
1473 
1474   protected:
1475     StringRef _value;
1476   };
1477 
1478   class MapHNode : public HNode {
1479     void anchor() override;
1480 
1481   public:
1482     MapHNode(Node *n) : HNode(n) { }
1483 
1484     static bool classof(const HNode *n) {
1485       return MappingNode::classof(n->_node);
1486     }
1487 
1488     static bool classof(const MapHNode *) { return true; }
1489 
1490     using NameToNode = StringMap<std::unique_ptr<HNode>>;
1491 
1492     NameToNode Mapping;
1493     SmallVector<std::string, 6> ValidKeys;
1494   };
1495 
1496   class SequenceHNode : public HNode {
1497     void anchor() override;
1498 
1499   public:
1500     SequenceHNode(Node *n) : HNode(n) { }
1501 
1502     static bool classof(const HNode *n) {
1503       return SequenceNode::classof(n->_node);
1504     }
1505 
1506     static bool classof(const SequenceHNode *) { return true; }
1507 
1508     std::vector<std::unique_ptr<HNode>> Entries;
1509   };
1510 
1511   std::unique_ptr<Input::HNode> createHNodes(Node *node);
1512   void setError(HNode *hnode, const Twine &message);
1513   void setError(Node *node, const Twine &message);
1514 
1515 public:
1516   // These are only used by operator>>. They could be private
1517   // if those templated things could be made friends.
1518   bool setCurrentDocument();
1519   bool nextDocument();
1520 
1521   /// Returns the current node that's being parsed by the YAML Parser.
1522   const Node *getCurrentNode() const;
1523 
1524 private:
1525   SourceMgr                           SrcMgr; // must be before Strm
1526   std::unique_ptr<llvm::yaml::Stream> Strm;
1527   std::unique_ptr<HNode>              TopNode;
1528   std::error_code                     EC;
1529   BumpPtrAllocator                    StringAllocator;
1530   document_iterator                   DocIterator;
1531   std::vector<bool>                   BitValuesUsed;
1532   HNode *CurrentNode = nullptr;
1533   bool                                ScalarMatchFound;
1534 };
1535 
1536 ///
1537 /// The Output class is used to generate a yaml document from in-memory structs
1538 /// and vectors.
1539 ///
1540 class Output : public IO {
1541 public:
1542   Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1543   ~Output() override;
1544 
1545   /// Set whether or not to output optional values which are equal
1546   /// to the default value.  By default, when outputting if you attempt
1547   /// to write a value that is equal to the default, the value gets ignored.
1548   /// Sometimes, it is useful to be able to see these in the resulting YAML
1549   /// anyway.
1550   void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1551 
1552   bool outputting() override;
1553   bool mapTag(StringRef, bool) override;
1554   void beginMapping() override;
1555   void endMapping() override;
1556   bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1557   void postflightKey(void *) override;
1558   std::vector<StringRef> keys() override;
1559   void beginFlowMapping() override;
1560   void endFlowMapping() override;
1561   unsigned beginSequence() override;
1562   void endSequence() override;
1563   bool preflightElement(unsigned, void *&) override;
1564   void postflightElement(void *) override;
1565   unsigned beginFlowSequence() override;
1566   bool preflightFlowElement(unsigned, void *&) override;
1567   void postflightFlowElement(void *) override;
1568   void endFlowSequence() override;
1569   void beginEnumScalar() override;
1570   bool matchEnumScalar(const char*, bool) override;
1571   bool matchEnumFallback() override;
1572   void endEnumScalar() override;
1573   bool beginBitSetScalar(bool &) override;
1574   bool bitSetMatch(const char *, bool ) override;
1575   void endBitSetScalar() override;
1576   void scalarString(StringRef &, QuotingType) override;
1577   void blockScalarString(StringRef &) override;
1578   void scalarTag(std::string &) override;
1579   NodeKind getNodeKind() override;
1580   void setError(const Twine &message) override;
1581   bool canElideEmptySequence() override;
1582 
1583   // These are only used by operator<<. They could be private
1584   // if that templated operator could be made a friend.
1585   void beginDocuments();
1586   bool preflightDocument(unsigned);
1587   void postflightDocument();
1588   void endDocuments();
1589 
1590 private:
1591   void output(StringRef s);
1592   void outputUpToEndOfLine(StringRef s);
1593   void newLineCheck();
1594   void outputNewLine();
1595   void paddedKey(StringRef key);
1596   void flowKey(StringRef Key);
1597 
1598   enum InState {
1599     inSeqFirstElement,
1600     inSeqOtherElement,
1601     inFlowSeqFirstElement,
1602     inFlowSeqOtherElement,
1603     inMapFirstKey,
1604     inMapOtherKey,
1605     inFlowMapFirstKey,
1606     inFlowMapOtherKey
1607   };
1608 
1609   static bool inSeqAnyElement(InState State);
1610   static bool inFlowSeqAnyElement(InState State);
1611   static bool inMapAnyKey(InState State);
1612   static bool inFlowMapAnyKey(InState State);
1613 
1614   raw_ostream &Out;
1615   int WrapColumn;
1616   SmallVector<InState, 8> StateStack;
1617   int Column = 0;
1618   int ColumnAtFlowStart = 0;
1619   int ColumnAtMapFlowStart = 0;
1620   bool NeedBitValueComma = false;
1621   bool NeedFlowSequenceComma = false;
1622   bool EnumerationMatchFound = false;
1623   bool WriteDefaultValues = false;
1624   StringRef Padding;
1625   StringRef PaddingBeforeContainer;
1626 };
1627 
1628 /// YAML I/O does conversion based on types. But often native data types
1629 /// are just a typedef of built in intergral types (e.g. int).  But the C++
1630 /// type matching system sees through the typedef and all the typedefed types
1631 /// look like a built in type. This will cause the generic YAML I/O conversion
1632 /// to be used. To provide better control over the YAML conversion, you can
1633 /// use this macro instead of typedef.  It will create a class with one field
1634 /// and automatic conversion operators to and from the base type.
1635 /// Based on BOOST_STRONG_TYPEDEF
1636 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type)                                 \
1637     struct _type {                                                             \
1638         _type() = default;                                                     \
1639         _type(const _base v) : value(v) {}                                     \
1640         _type(const _type &v) = default;                                       \
1641         _type &operator=(const _type &rhs) = default;                          \
1642         _type &operator=(const _base &rhs) { value = rhs; return *this; }      \
1643         operator const _base & () const { return value; }                      \
1644         bool operator==(const _type &rhs) const { return value == rhs.value; } \
1645         bool operator==(const _base &rhs) const { return value == rhs; }       \
1646         bool operator<(const _type &rhs) const { return value < rhs.value; }   \
1647         _base value;                                                           \
1648         using BaseType = _base;                                                \
1649     };
1650 
1651 ///
1652 /// Use these types instead of uintXX_t in any mapping to have
1653 /// its yaml output formatted as hexadecimal.
1654 ///
1655 LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
1656 LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
1657 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
1658 LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
1659 
1660 template<>
1661 struct ScalarTraits<Hex8> {
1662   static void output(const Hex8 &, void *, raw_ostream &);
1663   static StringRef input(StringRef, void *, Hex8 &);
1664   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1665 };
1666 
1667 template<>
1668 struct ScalarTraits<Hex16> {
1669   static void output(const Hex16 &, void *, raw_ostream &);
1670   static StringRef input(StringRef, void *, Hex16 &);
1671   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1672 };
1673 
1674 template<>
1675 struct ScalarTraits<Hex32> {
1676   static void output(const Hex32 &, void *, raw_ostream &);
1677   static StringRef input(StringRef, void *, Hex32 &);
1678   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1679 };
1680 
1681 template<>
1682 struct ScalarTraits<Hex64> {
1683   static void output(const Hex64 &, void *, raw_ostream &);
1684   static StringRef input(StringRef, void *, Hex64 &);
1685   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1686 };
1687 
1688 // Define non-member operator>> so that Input can stream in a document list.
1689 template <typename T>
1690 inline
1691 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1692 operator>>(Input &yin, T &docList) {
1693   int i = 0;
1694   EmptyContext Ctx;
1695   while ( yin.setCurrentDocument() ) {
1696     yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1697     if ( yin.error() )
1698       return yin;
1699     yin.nextDocument();
1700     ++i;
1701   }
1702   return yin;
1703 }
1704 
1705 // Define non-member operator>> so that Input can stream in a map as a document.
1706 template <typename T>
1707 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1708                                Input &>::type
1709 operator>>(Input &yin, T &docMap) {
1710   EmptyContext Ctx;
1711   yin.setCurrentDocument();
1712   yamlize(yin, docMap, true, Ctx);
1713   return yin;
1714 }
1715 
1716 // Define non-member operator>> so that Input can stream in a sequence as
1717 // a document.
1718 template <typename T>
1719 inline
1720 typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1721 operator>>(Input &yin, T &docSeq) {
1722   EmptyContext Ctx;
1723   if (yin.setCurrentDocument())
1724     yamlize(yin, docSeq, true, Ctx);
1725   return yin;
1726 }
1727 
1728 // Define non-member operator>> so that Input can stream in a block scalar.
1729 template <typename T>
1730 inline
1731 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1732 operator>>(Input &In, T &Val) {
1733   EmptyContext Ctx;
1734   if (In.setCurrentDocument())
1735     yamlize(In, Val, true, Ctx);
1736   return In;
1737 }
1738 
1739 // Define non-member operator>> so that Input can stream in a string map.
1740 template <typename T>
1741 inline
1742 typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
1743 operator>>(Input &In, T &Val) {
1744   EmptyContext Ctx;
1745   if (In.setCurrentDocument())
1746     yamlize(In, Val, true, Ctx);
1747   return In;
1748 }
1749 
1750 // Define non-member operator>> so that Input can stream in a polymorphic type.
1751 template <typename T>
1752 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Input &>::type
1753 operator>>(Input &In, T &Val) {
1754   EmptyContext Ctx;
1755   if (In.setCurrentDocument())
1756     yamlize(In, Val, true, Ctx);
1757   return In;
1758 }
1759 
1760 // Provide better error message about types missing a trait specialization
1761 template <typename T>
1762 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1763                                Input &>::type
1764 operator>>(Input &yin, T &docSeq) {
1765   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1766   return yin;
1767 }
1768 
1769 // Define non-member operator<< so that Output can stream out document list.
1770 template <typename T>
1771 inline
1772 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1773 operator<<(Output &yout, T &docList) {
1774   EmptyContext Ctx;
1775   yout.beginDocuments();
1776   const size_t count = DocumentListTraits<T>::size(yout, docList);
1777   for(size_t i=0; i < count; ++i) {
1778     if ( yout.preflightDocument(i) ) {
1779       yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1780               Ctx);
1781       yout.postflightDocument();
1782     }
1783   }
1784   yout.endDocuments();
1785   return yout;
1786 }
1787 
1788 // Define non-member operator<< so that Output can stream out a map.
1789 template <typename T>
1790 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1791                                Output &>::type
1792 operator<<(Output &yout, T &map) {
1793   EmptyContext Ctx;
1794   yout.beginDocuments();
1795   if ( yout.preflightDocument(0) ) {
1796     yamlize(yout, map, true, Ctx);
1797     yout.postflightDocument();
1798   }
1799   yout.endDocuments();
1800   return yout;
1801 }
1802 
1803 // Define non-member operator<< so that Output can stream out a sequence.
1804 template <typename T>
1805 inline
1806 typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1807 operator<<(Output &yout, T &seq) {
1808   EmptyContext Ctx;
1809   yout.beginDocuments();
1810   if ( yout.preflightDocument(0) ) {
1811     yamlize(yout, seq, true, Ctx);
1812     yout.postflightDocument();
1813   }
1814   yout.endDocuments();
1815   return yout;
1816 }
1817 
1818 // Define non-member operator<< so that Output can stream out a block scalar.
1819 template <typename T>
1820 inline
1821 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1822 operator<<(Output &Out, T &Val) {
1823   EmptyContext Ctx;
1824   Out.beginDocuments();
1825   if (Out.preflightDocument(0)) {
1826     yamlize(Out, Val, true, Ctx);
1827     Out.postflightDocument();
1828   }
1829   Out.endDocuments();
1830   return Out;
1831 }
1832 
1833 // Define non-member operator<< so that Output can stream out a string map.
1834 template <typename T>
1835 inline
1836 typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
1837 operator<<(Output &Out, T &Val) {
1838   EmptyContext Ctx;
1839   Out.beginDocuments();
1840   if (Out.preflightDocument(0)) {
1841     yamlize(Out, Val, true, Ctx);
1842     Out.postflightDocument();
1843   }
1844   Out.endDocuments();
1845   return Out;
1846 }
1847 
1848 // Define non-member operator<< so that Output can stream out a polymorphic
1849 // type.
1850 template <typename T>
1851 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Output &>::type
1852 operator<<(Output &Out, T &Val) {
1853   EmptyContext Ctx;
1854   Out.beginDocuments();
1855   if (Out.preflightDocument(0)) {
1856     // FIXME: The parser does not support explicit documents terminated with a
1857     // plain scalar; the end-marker is included as part of the scalar token.
1858     assert(PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && "plain scalar documents are not supported");
1859     yamlize(Out, Val, true, Ctx);
1860     Out.postflightDocument();
1861   }
1862   Out.endDocuments();
1863   return Out;
1864 }
1865 
1866 // Provide better error message about types missing a trait specialization
1867 template <typename T>
1868 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1869                                Output &>::type
1870 operator<<(Output &yout, T &seq) {
1871   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1872   return yout;
1873 }
1874 
1875 template <bool B> struct IsFlowSequenceBase {};
1876 template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1877 
1878 template <typename T, bool Flow>
1879 struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1880 private:
1881   using type = typename T::value_type;
1882 
1883 public:
1884   static size_t size(IO &io, T &seq) { return seq.size(); }
1885 
1886   static type &element(IO &io, T &seq, size_t index) {
1887     if (index >= seq.size())
1888       seq.resize(index + 1);
1889     return seq[index];
1890   }
1891 };
1892 
1893 // Simple helper to check an expression can be used as a bool-valued template
1894 // argument.
1895 template <bool> struct CheckIsBool { static const bool value = true; };
1896 
1897 // If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1898 // SequenceTraits that do the obvious thing.
1899 template <typename T>
1900 struct SequenceTraits<std::vector<T>,
1901                       typename std::enable_if<CheckIsBool<
1902                           SequenceElementTraits<T>::flow>::value>::type>
1903     : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1904 template <typename T, unsigned N>
1905 struct SequenceTraits<SmallVector<T, N>,
1906                       typename std::enable_if<CheckIsBool<
1907                           SequenceElementTraits<T>::flow>::value>::type>
1908     : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1909 template <typename T>
1910 struct SequenceTraits<SmallVectorImpl<T>,
1911                       typename std::enable_if<CheckIsBool<
1912                           SequenceElementTraits<T>::flow>::value>::type>
1913     : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
1914 
1915 // Sequences of fundamental types use flow formatting.
1916 template <typename T>
1917 struct SequenceElementTraits<
1918     T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
1919   static const bool flow = true;
1920 };
1921 
1922 // Sequences of strings use block formatting.
1923 template<> struct SequenceElementTraits<std::string> {
1924   static const bool flow = false;
1925 };
1926 template<> struct SequenceElementTraits<StringRef> {
1927   static const bool flow = false;
1928 };
1929 template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1930   static const bool flow = false;
1931 };
1932 
1933 /// Implementation of CustomMappingTraits for std::map<std::string, T>.
1934 template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1935   using map_type = std::map<std::string, T>;
1936 
1937   static void inputOne(IO &io, StringRef key, map_type &v) {
1938     io.mapRequired(key.str().c_str(), v[key]);
1939   }
1940 
1941   static void output(IO &io, map_type &v) {
1942     for (auto &p : v)
1943       io.mapRequired(p.first.c_str(), p.second);
1944   }
1945 };
1946 
1947 } // end namespace yaml
1948 } // end namespace llvm
1949 
1950 #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)                          \
1951   namespace llvm {                                                             \
1952   namespace yaml {                                                             \
1953   static_assert(                                                               \
1954       !std::is_fundamental<TYPE>::value &&                                     \
1955       !std::is_same<TYPE, std::string>::value &&                               \
1956       !std::is_same<TYPE, llvm::StringRef>::value,                             \
1957       "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control");          \
1958   template <> struct SequenceElementTraits<TYPE> {                             \
1959     static const bool flow = FLOW;                                             \
1960   };                                                                           \
1961   }                                                                            \
1962   }
1963 
1964 /// Utility for declaring that a std::vector of a particular type
1965 /// should be considered a YAML sequence.
1966 #define LLVM_YAML_IS_SEQUENCE_VECTOR(type)                                     \
1967   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
1968 
1969 /// Utility for declaring that a std::vector of a particular type
1970 /// should be considered a YAML flow sequence.
1971 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)                                \
1972   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
1973 
1974 #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)                                 \
1975   namespace llvm {                                                             \
1976   namespace yaml {                                                             \
1977   template <> struct MappingTraits<Type> {                                     \
1978     static void mapping(IO &IO, Type &Obj);                                    \
1979   };                                                                           \
1980   }                                                                            \
1981   }
1982 
1983 #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)                                    \
1984   namespace llvm {                                                             \
1985   namespace yaml {                                                             \
1986   template <> struct ScalarEnumerationTraits<Type> {                           \
1987     static void enumeration(IO &io, Type &Value);                              \
1988   };                                                                           \
1989   }                                                                            \
1990   }
1991 
1992 #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)                                  \
1993   namespace llvm {                                                             \
1994   namespace yaml {                                                             \
1995   template <> struct ScalarBitSetTraits<Type> {                                \
1996     static void bitset(IO &IO, Type &Options);                                 \
1997   };                                                                           \
1998   }                                                                            \
1999   }
2000 
2001 #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)                       \
2002   namespace llvm {                                                             \
2003   namespace yaml {                                                             \
2004   template <> struct ScalarTraits<Type> {                                      \
2005     static void output(const Type &Value, void *ctx, raw_ostream &Out);        \
2006     static StringRef input(StringRef Scalar, void *ctxt, Type &Value);         \
2007     static QuotingType mustQuote(StringRef) { return MustQuote; }              \
2008   };                                                                           \
2009   }                                                                            \
2010   }
2011 
2012 /// Utility for declaring that a std::vector of a particular type
2013 /// should be considered a YAML document list.
2014 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                               \
2015   namespace llvm {                                                             \
2016   namespace yaml {                                                             \
2017   template <unsigned N>                                                        \
2018   struct DocumentListTraits<SmallVector<_type, N>>                             \
2019       : public SequenceTraitsImpl<SmallVector<_type, N>, false> {};            \
2020   template <>                                                                  \
2021   struct DocumentListTraits<std::vector<_type>>                                \
2022       : public SequenceTraitsImpl<std::vector<_type>, false> {};               \
2023   }                                                                            \
2024   }
2025 
2026 /// Utility for declaring that std::map<std::string, _type> should be considered
2027 /// a YAML map.
2028 #define LLVM_YAML_IS_STRING_MAP(_type)                                         \
2029   namespace llvm {                                                             \
2030   namespace yaml {                                                             \
2031   template <>                                                                  \
2032   struct CustomMappingTraits<std::map<std::string, _type>>                     \
2033       : public StdMapStringCustomMappingTraitsImpl<_type> {};                  \
2034   }                                                                            \
2035   }
2036 
2037 #endif // LLVM_SUPPORT_YAMLTRAITS_H
2038