]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Support/YAMLTraits.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Support / YAMLTraits.h
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(static_cast<unsigned char>(S.front())) ||
653       isspace(static_cast<unsigned char>(S.back())))
654     return QuotingType::Single;
655   if (isNull(S))
656     return QuotingType::Single;
657   if (isBool(S))
658     return QuotingType::Single;
659   if (isNumeric(S))
660     return QuotingType::Single;
661
662   // 7.3.3 Plain Style
663   // Plain scalars must not begin with most indicators, as this would cause
664   // ambiguity with other YAML constructs.
665   static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
666   if (S.find_first_of(Indicators) == 0)
667     return QuotingType::Single;
668
669   QuotingType MaxQuotingNeeded = QuotingType::None;
670   for (unsigned char C : S) {
671     // Alphanum is safe.
672     if (isAlnum(C))
673       continue;
674
675     switch (C) {
676     // Safe scalar characters.
677     case '_':
678     case '-':
679     case '^':
680     case '.':
681     case ',':
682     case ' ':
683     // TAB (0x9) is allowed in unquoted strings.
684     case 0x9:
685       continue;
686     // LF(0xA) and CR(0xD) may delimit values and so require at least single
687     // quotes.
688     case 0xA:
689     case 0xD:
690       MaxQuotingNeeded = QuotingType::Single;
691       continue;
692     // DEL (0x7F) are excluded from the allowed character range.
693     case 0x7F:
694       return QuotingType::Double;
695     // Forward slash is allowed to be unquoted, but we quote it anyway.  We have
696     // many tests that use FileCheck against YAML output, and this output often
697     // contains paths.  If we quote backslashes but not forward slashes then
698     // paths will come out either quoted or unquoted depending on which platform
699     // the test is run on, making FileCheck comparisons difficult.
700     case '/':
701     default: {
702       // C0 control block (0x0 - 0x1F) is excluded from the allowed character
703       // range.
704       if (C <= 0x1F)
705         return QuotingType::Double;
706
707       // Always double quote UTF-8.
708       if ((C & 0x80) != 0)
709         return QuotingType::Double;
710
711       // The character is not safe, at least simple quoting needed.
712       MaxQuotingNeeded = QuotingType::Single;
713     }
714     }
715   }
716
717   return MaxQuotingNeeded;
718 }
719
720 template <typename T, typename Context>
721 struct missingTraits
722     : public std::integral_constant<bool,
723                                     !has_ScalarEnumerationTraits<T>::value &&
724                                         !has_ScalarBitSetTraits<T>::value &&
725                                         !has_ScalarTraits<T>::value &&
726                                         !has_BlockScalarTraits<T>::value &&
727                                         !has_TaggedScalarTraits<T>::value &&
728                                         !has_MappingTraits<T, Context>::value &&
729                                         !has_SequenceTraits<T>::value &&
730                                         !has_CustomMappingTraits<T>::value &&
731                                         !has_DocumentListTraits<T>::value &&
732                                         !has_PolymorphicTraits<T>::value> {};
733
734 template <typename T, typename Context>
735 struct validatedMappingTraits
736     : public std::integral_constant<
737           bool, has_MappingTraits<T, Context>::value &&
738                     has_MappingValidateTraits<T, Context>::value> {};
739
740 template <typename T, typename Context>
741 struct unvalidatedMappingTraits
742     : public std::integral_constant<
743           bool, has_MappingTraits<T, Context>::value &&
744                     !has_MappingValidateTraits<T, Context>::value> {};
745
746 // Base class for Input and Output.
747 class IO {
748 public:
749   IO(void *Ctxt = nullptr);
750   virtual ~IO();
751
752   virtual bool outputting() const = 0;
753
754   virtual unsigned beginSequence() = 0;
755   virtual bool preflightElement(unsigned, void *&) = 0;
756   virtual void postflightElement(void*) = 0;
757   virtual void endSequence() = 0;
758   virtual bool canElideEmptySequence() = 0;
759
760   virtual unsigned beginFlowSequence() = 0;
761   virtual bool preflightFlowElement(unsigned, void *&) = 0;
762   virtual void postflightFlowElement(void*) = 0;
763   virtual void endFlowSequence() = 0;
764
765   virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
766   virtual void beginMapping() = 0;
767   virtual void endMapping() = 0;
768   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
769   virtual void postflightKey(void*) = 0;
770   virtual std::vector<StringRef> keys() = 0;
771
772   virtual void beginFlowMapping() = 0;
773   virtual void endFlowMapping() = 0;
774
775   virtual void beginEnumScalar() = 0;
776   virtual bool matchEnumScalar(const char*, bool) = 0;
777   virtual bool matchEnumFallback() = 0;
778   virtual void endEnumScalar() = 0;
779
780   virtual bool beginBitSetScalar(bool &) = 0;
781   virtual bool bitSetMatch(const char*, bool) = 0;
782   virtual void endBitSetScalar() = 0;
783
784   virtual void scalarString(StringRef &, QuotingType) = 0;
785   virtual void blockScalarString(StringRef &) = 0;
786   virtual void scalarTag(std::string &) = 0;
787
788   virtual NodeKind getNodeKind() = 0;
789
790   virtual void setError(const Twine &) = 0;
791
792   template <typename T>
793   void enumCase(T &Val, const char* Str, const T ConstVal) {
794     if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
795       Val = ConstVal;
796     }
797   }
798
799   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
800   template <typename T>
801   void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
802     if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
803       Val = ConstVal;
804     }
805   }
806
807   template <typename FBT, typename T>
808   void enumFallback(T &Val) {
809     if (matchEnumFallback()) {
810       EmptyContext Context;
811       // FIXME: Force integral conversion to allow strong typedefs to convert.
812       FBT Res = static_cast<typename FBT::BaseType>(Val);
813       yamlize(*this, Res, true, Context);
814       Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
815     }
816   }
817
818   template <typename T>
819   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
820     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
821       Val = static_cast<T>(Val | ConstVal);
822     }
823   }
824
825   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
826   template <typename T>
827   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
828     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
829       Val = static_cast<T>(Val | ConstVal);
830     }
831   }
832
833   template <typename T>
834   void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
835     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
836       Val = Val | ConstVal;
837   }
838
839   template <typename T>
840   void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
841                         uint32_t Mask) {
842     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
843       Val = Val | ConstVal;
844   }
845
846   void *getContext() const;
847   void setContext(void *);
848
849   template <typename T> void mapRequired(const char *Key, T &Val) {
850     EmptyContext Ctx;
851     this->processKey(Key, Val, true, Ctx);
852   }
853
854   template <typename T, typename Context>
855   void mapRequired(const char *Key, T &Val, Context &Ctx) {
856     this->processKey(Key, Val, true, Ctx);
857   }
858
859   template <typename T> void mapOptional(const char *Key, T &Val) {
860     EmptyContext Ctx;
861     mapOptionalWithContext(Key, Val, Ctx);
862   }
863
864   template <typename T, typename DefaultT>
865   void mapOptional(const char *Key, T &Val, const DefaultT &Default) {
866     EmptyContext Ctx;
867     mapOptionalWithContext(Key, Val, Default, Ctx);
868   }
869
870   template <typename T, typename Context>
871   typename std::enable_if<has_SequenceTraits<T>::value, void>::type
872   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
873     // omit key/value instead of outputting empty sequence
874     if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
875       return;
876     this->processKey(Key, Val, false, Ctx);
877   }
878
879   template <typename T, typename Context>
880   void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
881     this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
882                                 Ctx);
883   }
884
885   template <typename T, typename Context>
886   typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
887   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
888     this->processKey(Key, Val, false, Ctx);
889   }
890
891   template <typename T, typename Context, typename DefaultT>
892   void mapOptionalWithContext(const char *Key, T &Val, const DefaultT &Default,
893                               Context &Ctx) {
894     static_assert(std::is_convertible<DefaultT, T>::value,
895                   "Default type must be implicitly convertible to value type!");
896     this->processKeyWithDefault(Key, Val, static_cast<const T &>(Default),
897                                 false, Ctx);
898   }
899
900 private:
901   template <typename T, typename Context>
902   void processKeyWithDefault(const char *Key, Optional<T> &Val,
903                              const Optional<T> &DefaultValue, bool Required,
904                              Context &Ctx) {
905     assert(DefaultValue.hasValue() == false &&
906            "Optional<T> shouldn't have a value!");
907     void *SaveInfo;
908     bool UseDefault = true;
909     const bool sameAsDefault = outputting() && !Val.hasValue();
910     if (!outputting() && !Val.hasValue())
911       Val = T();
912     if (Val.hasValue() &&
913         this->preflightKey(Key, Required, sameAsDefault, UseDefault,
914                            SaveInfo)) {
915       yamlize(*this, Val.getValue(), Required, Ctx);
916       this->postflightKey(SaveInfo);
917     } else {
918       if (UseDefault)
919         Val = DefaultValue;
920     }
921   }
922
923   template <typename T, typename Context>
924   void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
925                              bool Required, Context &Ctx) {
926     void *SaveInfo;
927     bool UseDefault;
928     const bool sameAsDefault = outputting() && Val == DefaultValue;
929     if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
930                                                                   SaveInfo) ) {
931       yamlize(*this, Val, Required, Ctx);
932       this->postflightKey(SaveInfo);
933     }
934     else {
935       if ( UseDefault )
936         Val = DefaultValue;
937     }
938   }
939
940   template <typename T, typename Context>
941   void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
942     void *SaveInfo;
943     bool UseDefault;
944     if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
945       yamlize(*this, Val, Required, Ctx);
946       this->postflightKey(SaveInfo);
947     }
948   }
949
950 private:
951   void *Ctxt;
952 };
953
954 namespace detail {
955
956 template <typename T, typename Context>
957 void doMapping(IO &io, T &Val, Context &Ctx) {
958   MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
959 }
960
961 template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
962   MappingTraits<T>::mapping(io, Val);
963 }
964
965 } // end namespace detail
966
967 template <typename T>
968 typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
969 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
970   io.beginEnumScalar();
971   ScalarEnumerationTraits<T>::enumeration(io, Val);
972   io.endEnumScalar();
973 }
974
975 template <typename T>
976 typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
977 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
978   bool DoClear;
979   if ( io.beginBitSetScalar(DoClear) ) {
980     if ( DoClear )
981       Val = T();
982     ScalarBitSetTraits<T>::bitset(io, Val);
983     io.endBitSetScalar();
984   }
985 }
986
987 template <typename T>
988 typename std::enable_if<has_ScalarTraits<T>::value, void>::type
989 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
990   if ( io.outputting() ) {
991     std::string Storage;
992     raw_string_ostream Buffer(Storage);
993     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
994     StringRef Str = Buffer.str();
995     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
996   }
997   else {
998     StringRef Str;
999     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1000     StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1001     if ( !Result.empty() ) {
1002       io.setError(Twine(Result));
1003     }
1004   }
1005 }
1006
1007 template <typename T>
1008 typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
1009 yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
1010   if (YamlIO.outputting()) {
1011     std::string Storage;
1012     raw_string_ostream Buffer(Storage);
1013     BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1014     StringRef Str = Buffer.str();
1015     YamlIO.blockScalarString(Str);
1016   } else {
1017     StringRef Str;
1018     YamlIO.blockScalarString(Str);
1019     StringRef Result =
1020         BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1021     if (!Result.empty())
1022       YamlIO.setError(Twine(Result));
1023   }
1024 }
1025
1026 template <typename T>
1027 typename std::enable_if<has_TaggedScalarTraits<T>::value, void>::type
1028 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1029   if (io.outputting()) {
1030     std::string ScalarStorage, TagStorage;
1031     raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1032     TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1033                                   TagBuffer);
1034     io.scalarTag(TagBuffer.str());
1035     StringRef ScalarStr = ScalarBuffer.str();
1036     io.scalarString(ScalarStr,
1037                     TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1038   } else {
1039     std::string Tag;
1040     io.scalarTag(Tag);
1041     StringRef Str;
1042     io.scalarString(Str, QuotingType::None);
1043     StringRef Result =
1044         TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1045     if (!Result.empty()) {
1046       io.setError(Twine(Result));
1047     }
1048   }
1049 }
1050
1051 template <typename T, typename Context>
1052 typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
1053 yamlize(IO &io, T &Val, bool, Context &Ctx) {
1054   if (has_FlowTraits<MappingTraits<T>>::value)
1055     io.beginFlowMapping();
1056   else
1057     io.beginMapping();
1058   if (io.outputting()) {
1059     StringRef Err = MappingTraits<T>::validate(io, Val);
1060     if (!Err.empty()) {
1061       errs() << Err << "\n";
1062       assert(Err.empty() && "invalid struct trying to be written as yaml");
1063     }
1064   }
1065   detail::doMapping(io, Val, Ctx);
1066   if (!io.outputting()) {
1067     StringRef Err = MappingTraits<T>::validate(io, Val);
1068     if (!Err.empty())
1069       io.setError(Err);
1070   }
1071   if (has_FlowTraits<MappingTraits<T>>::value)
1072     io.endFlowMapping();
1073   else
1074     io.endMapping();
1075 }
1076
1077 template <typename T, typename Context>
1078 typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
1079 yamlize(IO &io, T &Val, bool, Context &Ctx) {
1080   if (has_FlowTraits<MappingTraits<T>>::value) {
1081     io.beginFlowMapping();
1082     detail::doMapping(io, Val, Ctx);
1083     io.endFlowMapping();
1084   } else {
1085     io.beginMapping();
1086     detail::doMapping(io, Val, Ctx);
1087     io.endMapping();
1088   }
1089 }
1090
1091 template <typename T>
1092 typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
1093 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1094   if ( io.outputting() ) {
1095     io.beginMapping();
1096     CustomMappingTraits<T>::output(io, Val);
1097     io.endMapping();
1098   } else {
1099     io.beginMapping();
1100     for (StringRef key : io.keys())
1101       CustomMappingTraits<T>::inputOne(io, key, Val);
1102     io.endMapping();
1103   }
1104 }
1105
1106 template <typename T>
1107 typename std::enable_if<has_PolymorphicTraits<T>::value, void>::type
1108 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1109   switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1110                           : io.getNodeKind()) {
1111   case NodeKind::Scalar:
1112     return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val), true, Ctx);
1113   case NodeKind::Map:
1114     return yamlize(io, PolymorphicTraits<T>::getAsMap(Val), true, Ctx);
1115   case NodeKind::Sequence:
1116     return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val), true, Ctx);
1117   }
1118 }
1119
1120 template <typename T>
1121 typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
1122 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1123   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1124 }
1125
1126 template <typename T, typename Context>
1127 typename std::enable_if<has_SequenceTraits<T>::value, void>::type
1128 yamlize(IO &io, T &Seq, bool, Context &Ctx) {
1129   if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1130     unsigned incnt = io.beginFlowSequence();
1131     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1132     for(unsigned i=0; i < count; ++i) {
1133       void *SaveInfo;
1134       if ( io.preflightFlowElement(i, SaveInfo) ) {
1135         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1136         io.postflightFlowElement(SaveInfo);
1137       }
1138     }
1139     io.endFlowSequence();
1140   }
1141   else {
1142     unsigned incnt = io.beginSequence();
1143     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1144     for(unsigned i=0; i < count; ++i) {
1145       void *SaveInfo;
1146       if ( io.preflightElement(i, SaveInfo) ) {
1147         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1148         io.postflightElement(SaveInfo);
1149       }
1150     }
1151     io.endSequence();
1152   }
1153 }
1154
1155 template<>
1156 struct ScalarTraits<bool> {
1157   static void output(const bool &, void* , raw_ostream &);
1158   static StringRef input(StringRef, void *, bool &);
1159   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1160 };
1161
1162 template<>
1163 struct ScalarTraits<StringRef> {
1164   static void output(const StringRef &, void *, raw_ostream &);
1165   static StringRef input(StringRef, void *, StringRef &);
1166   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1167 };
1168
1169 template<>
1170 struct ScalarTraits<std::string> {
1171   static void output(const std::string &, void *, raw_ostream &);
1172   static StringRef input(StringRef, void *, std::string &);
1173   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1174 };
1175
1176 template<>
1177 struct ScalarTraits<uint8_t> {
1178   static void output(const uint8_t &, void *, raw_ostream &);
1179   static StringRef input(StringRef, void *, uint8_t &);
1180   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1181 };
1182
1183 template<>
1184 struct ScalarTraits<uint16_t> {
1185   static void output(const uint16_t &, void *, raw_ostream &);
1186   static StringRef input(StringRef, void *, uint16_t &);
1187   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1188 };
1189
1190 template<>
1191 struct ScalarTraits<uint32_t> {
1192   static void output(const uint32_t &, void *, raw_ostream &);
1193   static StringRef input(StringRef, void *, uint32_t &);
1194   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1195 };
1196
1197 template<>
1198 struct ScalarTraits<uint64_t> {
1199   static void output(const uint64_t &, void *, raw_ostream &);
1200   static StringRef input(StringRef, void *, uint64_t &);
1201   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1202 };
1203
1204 template<>
1205 struct ScalarTraits<int8_t> {
1206   static void output(const int8_t &, void *, raw_ostream &);
1207   static StringRef input(StringRef, void *, int8_t &);
1208   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1209 };
1210
1211 template<>
1212 struct ScalarTraits<int16_t> {
1213   static void output(const int16_t &, void *, raw_ostream &);
1214   static StringRef input(StringRef, void *, int16_t &);
1215   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1216 };
1217
1218 template<>
1219 struct ScalarTraits<int32_t> {
1220   static void output(const int32_t &, void *, raw_ostream &);
1221   static StringRef input(StringRef, void *, int32_t &);
1222   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1223 };
1224
1225 template<>
1226 struct ScalarTraits<int64_t> {
1227   static void output(const int64_t &, void *, raw_ostream &);
1228   static StringRef input(StringRef, void *, int64_t &);
1229   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1230 };
1231
1232 template<>
1233 struct ScalarTraits<float> {
1234   static void output(const float &, void *, raw_ostream &);
1235   static StringRef input(StringRef, void *, float &);
1236   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1237 };
1238
1239 template<>
1240 struct ScalarTraits<double> {
1241   static void output(const double &, void *, raw_ostream &);
1242   static StringRef input(StringRef, void *, double &);
1243   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1244 };
1245
1246 // For endian types, we use existing scalar Traits class for the underlying
1247 // type.  This way endian aware types are supported whenever the traits are
1248 // defined for the underlying type.
1249 template <typename value_type, support::endianness endian, size_t alignment>
1250 struct ScalarTraits<
1251     support::detail::packed_endian_specific_integral<value_type, endian,
1252                                                      alignment>,
1253     typename std::enable_if<has_ScalarTraits<value_type>::value>::type> {
1254   using endian_type =
1255       support::detail::packed_endian_specific_integral<value_type, endian,
1256                                                        alignment>;
1257
1258   static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
1259     ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
1260   }
1261
1262   static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
1263     value_type V;
1264     auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
1265     E = static_cast<endian_type>(V);
1266     return R;
1267   }
1268
1269   static QuotingType mustQuote(StringRef Str) {
1270     return ScalarTraits<value_type>::mustQuote(Str);
1271   }
1272 };
1273
1274 template <typename value_type, support::endianness endian, size_t alignment>
1275 struct ScalarEnumerationTraits<
1276     support::detail::packed_endian_specific_integral<value_type, endian,
1277                                                      alignment>,
1278     typename std::enable_if<
1279         has_ScalarEnumerationTraits<value_type>::value>::type> {
1280   using endian_type =
1281       support::detail::packed_endian_specific_integral<value_type, endian,
1282                                                        alignment>;
1283
1284   static void enumeration(IO &io, endian_type &E) {
1285     value_type V = E;
1286     ScalarEnumerationTraits<value_type>::enumeration(io, V);
1287     E = V;
1288   }
1289 };
1290
1291 template <typename value_type, support::endianness endian, size_t alignment>
1292 struct ScalarBitSetTraits<
1293     support::detail::packed_endian_specific_integral<value_type, endian,
1294                                                      alignment>,
1295     typename std::enable_if<has_ScalarBitSetTraits<value_type>::value>::type> {
1296   using endian_type =
1297       support::detail::packed_endian_specific_integral<value_type, endian,
1298                                                        alignment>;
1299   static void bitset(IO &io, endian_type &E) {
1300     value_type V = E;
1301     ScalarBitSetTraits<value_type>::bitset(io, V);
1302     E = V;
1303   }
1304 };
1305
1306 // Utility for use within MappingTraits<>::mapping() method
1307 // to [de]normalize an object for use with YAML conversion.
1308 template <typename TNorm, typename TFinal>
1309 struct MappingNormalization {
1310   MappingNormalization(IO &i_o, TFinal &Obj)
1311       : io(i_o), BufPtr(nullptr), Result(Obj) {
1312     if ( io.outputting() ) {
1313       BufPtr = new (&Buffer) TNorm(io, Obj);
1314     }
1315     else {
1316       BufPtr = new (&Buffer) TNorm(io);
1317     }
1318   }
1319
1320   ~MappingNormalization() {
1321     if ( ! io.outputting() ) {
1322       Result = BufPtr->denormalize(io);
1323     }
1324     BufPtr->~TNorm();
1325   }
1326
1327   TNorm* operator->() { return BufPtr; }
1328
1329 private:
1330   using Storage = AlignedCharArrayUnion<TNorm>;
1331
1332   Storage       Buffer;
1333   IO           &io;
1334   TNorm        *BufPtr;
1335   TFinal       &Result;
1336 };
1337
1338 // Utility for use within MappingTraits<>::mapping() method
1339 // to [de]normalize an object for use with YAML conversion.
1340 template <typename TNorm, typename TFinal>
1341 struct MappingNormalizationHeap {
1342   MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
1343     : io(i_o), Result(Obj) {
1344     if ( io.outputting() ) {
1345       BufPtr = new (&Buffer) TNorm(io, Obj);
1346     }
1347     else if (allocator) {
1348       BufPtr = allocator->Allocate<TNorm>();
1349       new (BufPtr) TNorm(io);
1350     } else {
1351       BufPtr = new TNorm(io);
1352     }
1353   }
1354
1355   ~MappingNormalizationHeap() {
1356     if ( io.outputting() ) {
1357       BufPtr->~TNorm();
1358     }
1359     else {
1360       Result = BufPtr->denormalize(io);
1361     }
1362   }
1363
1364   TNorm* operator->() { return BufPtr; }
1365
1366 private:
1367   using Storage = AlignedCharArrayUnion<TNorm>;
1368
1369   Storage       Buffer;
1370   IO           &io;
1371   TNorm        *BufPtr = nullptr;
1372   TFinal       &Result;
1373 };
1374
1375 ///
1376 /// The Input class is used to parse a yaml document into in-memory structs
1377 /// and vectors.
1378 ///
1379 /// It works by using YAMLParser to do a syntax parse of the entire yaml
1380 /// document, then the Input class builds a graph of HNodes which wraps
1381 /// each yaml Node.  The extra layer is buffering.  The low level yaml
1382 /// parser only lets you look at each node once.  The buffering layer lets
1383 /// you search and interate multiple times.  This is necessary because
1384 /// the mapRequired() method calls may not be in the same order
1385 /// as the keys in the document.
1386 ///
1387 class Input : public IO {
1388 public:
1389   // Construct a yaml Input object from a StringRef and optional
1390   // user-data. The DiagHandler can be specified to provide
1391   // alternative error reporting.
1392   Input(StringRef InputContent,
1393         void *Ctxt = nullptr,
1394         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1395         void *DiagHandlerCtxt = nullptr);
1396   Input(MemoryBufferRef Input,
1397         void *Ctxt = nullptr,
1398         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
1399         void *DiagHandlerCtxt = nullptr);
1400   ~Input() override;
1401
1402   // Check if there was an syntax or semantic error during parsing.
1403   std::error_code error();
1404
1405 private:
1406   bool outputting() const override;
1407   bool mapTag(StringRef, bool) override;
1408   void beginMapping() override;
1409   void endMapping() override;
1410   bool preflightKey(const char *, bool, bool, bool &, void *&) override;
1411   void postflightKey(void *) override;
1412   std::vector<StringRef> keys() override;
1413   void beginFlowMapping() override;
1414   void endFlowMapping() override;
1415   unsigned beginSequence() override;
1416   void endSequence() override;
1417   bool preflightElement(unsigned index, void *&) override;
1418   void postflightElement(void *) override;
1419   unsigned beginFlowSequence() override;
1420   bool preflightFlowElement(unsigned , void *&) override;
1421   void postflightFlowElement(void *) override;
1422   void endFlowSequence() override;
1423   void beginEnumScalar() override;
1424   bool matchEnumScalar(const char*, bool) override;
1425   bool matchEnumFallback() override;
1426   void endEnumScalar() override;
1427   bool beginBitSetScalar(bool &) override;
1428   bool bitSetMatch(const char *, bool ) override;
1429   void endBitSetScalar() override;
1430   void scalarString(StringRef &, QuotingType) override;
1431   void blockScalarString(StringRef &) override;
1432   void scalarTag(std::string &) override;
1433   NodeKind getNodeKind() override;
1434   void setError(const Twine &message) override;
1435   bool canElideEmptySequence() override;
1436
1437   class HNode {
1438     virtual void anchor();
1439
1440   public:
1441     HNode(Node *n) : _node(n) { }
1442     virtual ~HNode() = default;
1443
1444     static bool classof(const HNode *) { return true; }
1445
1446     Node *_node;
1447   };
1448
1449   class EmptyHNode : public HNode {
1450     void anchor() override;
1451
1452   public:
1453     EmptyHNode(Node *n) : HNode(n) { }
1454
1455     static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
1456
1457     static bool classof(const EmptyHNode *) { return true; }
1458   };
1459
1460   class ScalarHNode : public HNode {
1461     void anchor() override;
1462
1463   public:
1464     ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1465
1466     StringRef value() const { return _value; }
1467
1468     static bool classof(const HNode *n) {
1469       return ScalarNode::classof(n->_node) ||
1470              BlockScalarNode::classof(n->_node);
1471     }
1472
1473     static bool classof(const ScalarHNode *) { return true; }
1474
1475   protected:
1476     StringRef _value;
1477   };
1478
1479   class MapHNode : public HNode {
1480     void anchor() override;
1481
1482   public:
1483     MapHNode(Node *n) : HNode(n) { }
1484
1485     static bool classof(const HNode *n) {
1486       return MappingNode::classof(n->_node);
1487     }
1488
1489     static bool classof(const MapHNode *) { return true; }
1490
1491     using NameToNode = StringMap<std::unique_ptr<HNode>>;
1492
1493     NameToNode Mapping;
1494     SmallVector<std::string, 6> ValidKeys;
1495   };
1496
1497   class SequenceHNode : public HNode {
1498     void anchor() override;
1499
1500   public:
1501     SequenceHNode(Node *n) : HNode(n) { }
1502
1503     static bool classof(const HNode *n) {
1504       return SequenceNode::classof(n->_node);
1505     }
1506
1507     static bool classof(const SequenceHNode *) { return true; }
1508
1509     std::vector<std::unique_ptr<HNode>> Entries;
1510   };
1511
1512   std::unique_ptr<Input::HNode> createHNodes(Node *node);
1513   void setError(HNode *hnode, const Twine &message);
1514   void setError(Node *node, const Twine &message);
1515
1516 public:
1517   // These are only used by operator>>. They could be private
1518   // if those templated things could be made friends.
1519   bool setCurrentDocument();
1520   bool nextDocument();
1521
1522   /// Returns the current node that's being parsed by the YAML Parser.
1523   const Node *getCurrentNode() const;
1524
1525 private:
1526   SourceMgr                           SrcMgr; // must be before Strm
1527   std::unique_ptr<llvm::yaml::Stream> Strm;
1528   std::unique_ptr<HNode>              TopNode;
1529   std::error_code                     EC;
1530   BumpPtrAllocator                    StringAllocator;
1531   document_iterator                   DocIterator;
1532   std::vector<bool>                   BitValuesUsed;
1533   HNode *CurrentNode = nullptr;
1534   bool                                ScalarMatchFound = false;
1535 };
1536
1537 ///
1538 /// The Output class is used to generate a yaml document from in-memory structs
1539 /// and vectors.
1540 ///
1541 class Output : public IO {
1542 public:
1543   Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
1544   ~Output() override;
1545
1546   /// Set whether or not to output optional values which are equal
1547   /// to the default value.  By default, when outputting if you attempt
1548   /// to write a value that is equal to the default, the value gets ignored.
1549   /// Sometimes, it is useful to be able to see these in the resulting YAML
1550   /// anyway.
1551   void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
1552
1553   bool outputting() const override;
1554   bool mapTag(StringRef, bool) override;
1555   void beginMapping() override;
1556   void endMapping() override;
1557   bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1558   void postflightKey(void *) override;
1559   std::vector<StringRef> keys() override;
1560   void beginFlowMapping() override;
1561   void endFlowMapping() override;
1562   unsigned beginSequence() override;
1563   void endSequence() override;
1564   bool preflightElement(unsigned, void *&) override;
1565   void postflightElement(void *) override;
1566   unsigned beginFlowSequence() override;
1567   bool preflightFlowElement(unsigned, void *&) override;
1568   void postflightFlowElement(void *) override;
1569   void endFlowSequence() override;
1570   void beginEnumScalar() override;
1571   bool matchEnumScalar(const char*, bool) override;
1572   bool matchEnumFallback() override;
1573   void endEnumScalar() override;
1574   bool beginBitSetScalar(bool &) override;
1575   bool bitSetMatch(const char *, bool ) override;
1576   void endBitSetScalar() override;
1577   void scalarString(StringRef &, QuotingType) override;
1578   void blockScalarString(StringRef &) override;
1579   void scalarTag(std::string &) override;
1580   NodeKind getNodeKind() override;
1581   void setError(const Twine &message) override;
1582   bool canElideEmptySequence() override;
1583
1584   // These are only used by operator<<. They could be private
1585   // if that templated operator could be made a friend.
1586   void beginDocuments();
1587   bool preflightDocument(unsigned);
1588   void postflightDocument();
1589   void endDocuments();
1590
1591 private:
1592   void output(StringRef s);
1593   void outputUpToEndOfLine(StringRef s);
1594   void newLineCheck();
1595   void outputNewLine();
1596   void paddedKey(StringRef key);
1597   void flowKey(StringRef Key);
1598
1599   enum InState {
1600     inSeqFirstElement,
1601     inSeqOtherElement,
1602     inFlowSeqFirstElement,
1603     inFlowSeqOtherElement,
1604     inMapFirstKey,
1605     inMapOtherKey,
1606     inFlowMapFirstKey,
1607     inFlowMapOtherKey
1608   };
1609
1610   static bool inSeqAnyElement(InState State);
1611   static bool inFlowSeqAnyElement(InState State);
1612   static bool inMapAnyKey(InState State);
1613   static bool inFlowMapAnyKey(InState State);
1614
1615   raw_ostream &Out;
1616   int WrapColumn;
1617   SmallVector<InState, 8> StateStack;
1618   int Column = 0;
1619   int ColumnAtFlowStart = 0;
1620   int ColumnAtMapFlowStart = 0;
1621   bool NeedBitValueComma = false;
1622   bool NeedFlowSequenceComma = false;
1623   bool EnumerationMatchFound = false;
1624   bool WriteDefaultValues = false;
1625   StringRef Padding;
1626   StringRef PaddingBeforeContainer;
1627 };
1628
1629 /// YAML I/O does conversion based on types. But often native data types
1630 /// are just a typedef of built in intergral types (e.g. int).  But the C++
1631 /// type matching system sees through the typedef and all the typedefed types
1632 /// look like a built in type. This will cause the generic YAML I/O conversion
1633 /// to be used. To provide better control over the YAML conversion, you can
1634 /// use this macro instead of typedef.  It will create a class with one field
1635 /// and automatic conversion operators to and from the base type.
1636 /// Based on BOOST_STRONG_TYPEDEF
1637 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type)                                 \
1638     struct _type {                                                             \
1639         _type() = default;                                                     \
1640         _type(const _base v) : value(v) {}                                     \
1641         _type(const _type &v) = default;                                       \
1642         _type &operator=(const _type &rhs) = default;                          \
1643         _type &operator=(const _base &rhs) { value = rhs; return *this; }      \
1644         operator const _base & () const { return value; }                      \
1645         bool operator==(const _type &rhs) const { return value == rhs.value; } \
1646         bool operator==(const _base &rhs) const { return value == rhs; }       \
1647         bool operator<(const _type &rhs) const { return value < rhs.value; }   \
1648         _base value;                                                           \
1649         using BaseType = _base;                                                \
1650     };
1651
1652 ///
1653 /// Use these types instead of uintXX_t in any mapping to have
1654 /// its yaml output formatted as hexadecimal.
1655 ///
1656 LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
1657 LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
1658 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
1659 LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
1660
1661 template<>
1662 struct ScalarTraits<Hex8> {
1663   static void output(const Hex8 &, void *, raw_ostream &);
1664   static StringRef input(StringRef, void *, Hex8 &);
1665   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1666 };
1667
1668 template<>
1669 struct ScalarTraits<Hex16> {
1670   static void output(const Hex16 &, void *, raw_ostream &);
1671   static StringRef input(StringRef, void *, Hex16 &);
1672   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1673 };
1674
1675 template<>
1676 struct ScalarTraits<Hex32> {
1677   static void output(const Hex32 &, void *, raw_ostream &);
1678   static StringRef input(StringRef, void *, Hex32 &);
1679   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1680 };
1681
1682 template<>
1683 struct ScalarTraits<Hex64> {
1684   static void output(const Hex64 &, void *, raw_ostream &);
1685   static StringRef input(StringRef, void *, Hex64 &);
1686   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1687 };
1688
1689 // Define non-member operator>> so that Input can stream in a document list.
1690 template <typename T>
1691 inline
1692 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1693 operator>>(Input &yin, T &docList) {
1694   int i = 0;
1695   EmptyContext Ctx;
1696   while ( yin.setCurrentDocument() ) {
1697     yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1698     if ( yin.error() )
1699       return yin;
1700     yin.nextDocument();
1701     ++i;
1702   }
1703   return yin;
1704 }
1705
1706 // Define non-member operator>> so that Input can stream in a map as a document.
1707 template <typename T>
1708 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1709                                Input &>::type
1710 operator>>(Input &yin, T &docMap) {
1711   EmptyContext Ctx;
1712   yin.setCurrentDocument();
1713   yamlize(yin, docMap, true, Ctx);
1714   return yin;
1715 }
1716
1717 // Define non-member operator>> so that Input can stream in a sequence as
1718 // a document.
1719 template <typename T>
1720 inline
1721 typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1722 operator>>(Input &yin, T &docSeq) {
1723   EmptyContext Ctx;
1724   if (yin.setCurrentDocument())
1725     yamlize(yin, docSeq, true, Ctx);
1726   return yin;
1727 }
1728
1729 // Define non-member operator>> so that Input can stream in a block scalar.
1730 template <typename T>
1731 inline
1732 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1733 operator>>(Input &In, T &Val) {
1734   EmptyContext Ctx;
1735   if (In.setCurrentDocument())
1736     yamlize(In, Val, true, Ctx);
1737   return In;
1738 }
1739
1740 // Define non-member operator>> so that Input can stream in a string map.
1741 template <typename T>
1742 inline
1743 typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
1744 operator>>(Input &In, T &Val) {
1745   EmptyContext Ctx;
1746   if (In.setCurrentDocument())
1747     yamlize(In, Val, true, Ctx);
1748   return In;
1749 }
1750
1751 // Define non-member operator>> so that Input can stream in a polymorphic type.
1752 template <typename T>
1753 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Input &>::type
1754 operator>>(Input &In, T &Val) {
1755   EmptyContext Ctx;
1756   if (In.setCurrentDocument())
1757     yamlize(In, Val, true, Ctx);
1758   return In;
1759 }
1760
1761 // Provide better error message about types missing a trait specialization
1762 template <typename T>
1763 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1764                                Input &>::type
1765 operator>>(Input &yin, T &docSeq) {
1766   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1767   return yin;
1768 }
1769
1770 // Define non-member operator<< so that Output can stream out document list.
1771 template <typename T>
1772 inline
1773 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1774 operator<<(Output &yout, T &docList) {
1775   EmptyContext Ctx;
1776   yout.beginDocuments();
1777   const size_t count = DocumentListTraits<T>::size(yout, docList);
1778   for(size_t i=0; i < count; ++i) {
1779     if ( yout.preflightDocument(i) ) {
1780       yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1781               Ctx);
1782       yout.postflightDocument();
1783     }
1784   }
1785   yout.endDocuments();
1786   return yout;
1787 }
1788
1789 // Define non-member operator<< so that Output can stream out a map.
1790 template <typename T>
1791 inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
1792                                Output &>::type
1793 operator<<(Output &yout, T &map) {
1794   EmptyContext Ctx;
1795   yout.beginDocuments();
1796   if ( yout.preflightDocument(0) ) {
1797     yamlize(yout, map, true, Ctx);
1798     yout.postflightDocument();
1799   }
1800   yout.endDocuments();
1801   return yout;
1802 }
1803
1804 // Define non-member operator<< so that Output can stream out a sequence.
1805 template <typename T>
1806 inline
1807 typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1808 operator<<(Output &yout, T &seq) {
1809   EmptyContext Ctx;
1810   yout.beginDocuments();
1811   if ( yout.preflightDocument(0) ) {
1812     yamlize(yout, seq, true, Ctx);
1813     yout.postflightDocument();
1814   }
1815   yout.endDocuments();
1816   return yout;
1817 }
1818
1819 // Define non-member operator<< so that Output can stream out a block scalar.
1820 template <typename T>
1821 inline
1822 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1823 operator<<(Output &Out, T &Val) {
1824   EmptyContext Ctx;
1825   Out.beginDocuments();
1826   if (Out.preflightDocument(0)) {
1827     yamlize(Out, Val, true, Ctx);
1828     Out.postflightDocument();
1829   }
1830   Out.endDocuments();
1831   return Out;
1832 }
1833
1834 // Define non-member operator<< so that Output can stream out a string map.
1835 template <typename T>
1836 inline
1837 typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
1838 operator<<(Output &Out, T &Val) {
1839   EmptyContext Ctx;
1840   Out.beginDocuments();
1841   if (Out.preflightDocument(0)) {
1842     yamlize(Out, Val, true, Ctx);
1843     Out.postflightDocument();
1844   }
1845   Out.endDocuments();
1846   return Out;
1847 }
1848
1849 // Define non-member operator<< so that Output can stream out a polymorphic
1850 // type.
1851 template <typename T>
1852 inline typename std::enable_if<has_PolymorphicTraits<T>::value, Output &>::type
1853 operator<<(Output &Out, T &Val) {
1854   EmptyContext Ctx;
1855   Out.beginDocuments();
1856   if (Out.preflightDocument(0)) {
1857     // FIXME: The parser does not support explicit documents terminated with a
1858     // plain scalar; the end-marker is included as part of the scalar token.
1859     assert(PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && "plain scalar documents are not supported");
1860     yamlize(Out, Val, true, Ctx);
1861     Out.postflightDocument();
1862   }
1863   Out.endDocuments();
1864   return Out;
1865 }
1866
1867 // Provide better error message about types missing a trait specialization
1868 template <typename T>
1869 inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
1870                                Output &>::type
1871 operator<<(Output &yout, T &seq) {
1872   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1873   return yout;
1874 }
1875
1876 template <bool B> struct IsFlowSequenceBase {};
1877 template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1878
1879 template <typename T, bool Flow>
1880 struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1881 private:
1882   using type = typename T::value_type;
1883
1884 public:
1885   static size_t size(IO &io, T &seq) { return seq.size(); }
1886
1887   static type &element(IO &io, T &seq, size_t index) {
1888     if (index >= seq.size())
1889       seq.resize(index + 1);
1890     return seq[index];
1891   }
1892 };
1893
1894 // Simple helper to check an expression can be used as a bool-valued template
1895 // argument.
1896 template <bool> struct CheckIsBool { static const bool value = true; };
1897
1898 // If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1899 // SequenceTraits that do the obvious thing.
1900 template <typename T>
1901 struct SequenceTraits<std::vector<T>,
1902                       typename std::enable_if<CheckIsBool<
1903                           SequenceElementTraits<T>::flow>::value>::type>
1904     : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1905 template <typename T, unsigned N>
1906 struct SequenceTraits<SmallVector<T, N>,
1907                       typename std::enable_if<CheckIsBool<
1908                           SequenceElementTraits<T>::flow>::value>::type>
1909     : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1910 template <typename T>
1911 struct SequenceTraits<SmallVectorImpl<T>,
1912                       typename std::enable_if<CheckIsBool<
1913                           SequenceElementTraits<T>::flow>::value>::type>
1914     : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
1915
1916 // Sequences of fundamental types use flow formatting.
1917 template <typename T>
1918 struct SequenceElementTraits<
1919     T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
1920   static const bool flow = true;
1921 };
1922
1923 // Sequences of strings use block formatting.
1924 template<> struct SequenceElementTraits<std::string> {
1925   static const bool flow = false;
1926 };
1927 template<> struct SequenceElementTraits<StringRef> {
1928   static const bool flow = false;
1929 };
1930 template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1931   static const bool flow = false;
1932 };
1933
1934 /// Implementation of CustomMappingTraits for std::map<std::string, T>.
1935 template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1936   using map_type = std::map<std::string, T>;
1937
1938   static void inputOne(IO &io, StringRef key, map_type &v) {
1939     io.mapRequired(key.str().c_str(), v[key]);
1940   }
1941
1942   static void output(IO &io, map_type &v) {
1943     for (auto &p : v)
1944       io.mapRequired(p.first.c_str(), p.second);
1945   }
1946 };
1947
1948 } // end namespace yaml
1949 } // end namespace llvm
1950
1951 #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)                          \
1952   namespace llvm {                                                             \
1953   namespace yaml {                                                             \
1954   static_assert(                                                               \
1955       !std::is_fundamental<TYPE>::value &&                                     \
1956       !std::is_same<TYPE, std::string>::value &&                               \
1957       !std::is_same<TYPE, llvm::StringRef>::value,                             \
1958       "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control");          \
1959   template <> struct SequenceElementTraits<TYPE> {                             \
1960     static const bool flow = FLOW;                                             \
1961   };                                                                           \
1962   }                                                                            \
1963   }
1964
1965 /// Utility for declaring that a std::vector of a particular type
1966 /// should be considered a YAML sequence.
1967 #define LLVM_YAML_IS_SEQUENCE_VECTOR(type)                                     \
1968   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
1969
1970 /// Utility for declaring that a std::vector of a particular type
1971 /// should be considered a YAML flow sequence.
1972 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)                                \
1973   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
1974
1975 #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)                                 \
1976   namespace llvm {                                                             \
1977   namespace yaml {                                                             \
1978   template <> struct MappingTraits<Type> {                                     \
1979     static void mapping(IO &IO, Type &Obj);                                    \
1980   };                                                                           \
1981   }                                                                            \
1982   }
1983
1984 #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)                                    \
1985   namespace llvm {                                                             \
1986   namespace yaml {                                                             \
1987   template <> struct ScalarEnumerationTraits<Type> {                           \
1988     static void enumeration(IO &io, Type &Value);                              \
1989   };                                                                           \
1990   }                                                                            \
1991   }
1992
1993 #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)                                  \
1994   namespace llvm {                                                             \
1995   namespace yaml {                                                             \
1996   template <> struct ScalarBitSetTraits<Type> {                                \
1997     static void bitset(IO &IO, Type &Options);                                 \
1998   };                                                                           \
1999   }                                                                            \
2000   }
2001
2002 #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)                       \
2003   namespace llvm {                                                             \
2004   namespace yaml {                                                             \
2005   template <> struct ScalarTraits<Type> {                                      \
2006     static void output(const Type &Value, void *ctx, raw_ostream &Out);        \
2007     static StringRef input(StringRef Scalar, void *ctxt, Type &Value);         \
2008     static QuotingType mustQuote(StringRef) { return MustQuote; }              \
2009   };                                                                           \
2010   }                                                                            \
2011   }
2012
2013 /// Utility for declaring that a std::vector of a particular type
2014 /// should be considered a YAML document list.
2015 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                               \
2016   namespace llvm {                                                             \
2017   namespace yaml {                                                             \
2018   template <unsigned N>                                                        \
2019   struct DocumentListTraits<SmallVector<_type, N>>                             \
2020       : public SequenceTraitsImpl<SmallVector<_type, N>, false> {};            \
2021   template <>                                                                  \
2022   struct DocumentListTraits<std::vector<_type>>                                \
2023       : public SequenceTraitsImpl<std::vector<_type>, false> {};               \
2024   }                                                                            \
2025   }
2026
2027 /// Utility for declaring that std::map<std::string, _type> should be considered
2028 /// a YAML map.
2029 #define LLVM_YAML_IS_STRING_MAP(_type)                                         \
2030   namespace llvm {                                                             \
2031   namespace yaml {                                                             \
2032   template <>                                                                  \
2033   struct CustomMappingTraits<std::map<std::string, _type>>                     \
2034       : public StdMapStringCustomMappingTraitsImpl<_type> {};                  \
2035   }                                                                            \
2036   }
2037
2038 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)
2039 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex32)
2040 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex16)
2041 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex8)
2042
2043 #endif // LLVM_SUPPORT_YAMLTRAITS_H