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 
653   QuotingType MaxQuotingNeeded = QuotingType::None;
654   if (isSpace(static_cast<unsigned char>(S.front())) ||
655       isSpace(static_cast<unsigned char>(S.back())))
656     MaxQuotingNeeded = QuotingType::Single;
657   if (isNull(S))
658     MaxQuotingNeeded = QuotingType::Single;
659   if (isBool(S))
660     MaxQuotingNeeded = QuotingType::Single;
661   if (isNumeric(S))
662     MaxQuotingNeeded = QuotingType::Single;
663 
664   // 7.3.3 Plain Style
665   // Plain scalars must not begin with most indicators, as this would cause
666   // ambiguity with other YAML constructs.
667   static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
668   if (S.find_first_of(Indicators) == 0)
669     MaxQuotingNeeded = QuotingType::Single;
670 
671   for (unsigned char C : S) {
672     // Alphanum is safe.
673     if (isAlnum(C))
674       continue;
675 
676     switch (C) {
677     // Safe scalar characters.
678     case '_':
679     case '-':
680     case '^':
681     case '.':
682     case ',':
683     case ' ':
684     // TAB (0x9) is allowed in unquoted strings.
685     case 0x9:
686       continue;
687     // LF(0xA) and CR(0xD) may delimit values and so require at least single
688     // quotes. LLVM YAML parser cannot handle single quoted multiline so use
689     // double quoting to produce valid YAML.
690     case 0xA:
691     case 0xD:
692       return QuotingType::Double;
693     // DEL (0x7F) are excluded from the allowed character range.
694     case 0x7F:
695       return QuotingType::Double;
696     // Forward slash is allowed to be unquoted, but we quote it anyway.  We have
697     // many tests that use FileCheck against YAML output, and this output often
698     // contains paths.  If we quote backslashes but not forward slashes then
699     // paths will come out either quoted or unquoted depending on which platform
700     // the test is run on, making FileCheck comparisons difficult.
701     case '/':
702     default: {
703       // C0 control block (0x0 - 0x1F) is excluded from the allowed character
704       // range.
705       if (C <= 0x1F)
706         return QuotingType::Double;
707 
708       // Always double quote UTF-8.
709       if ((C & 0x80) != 0)
710         return QuotingType::Double;
711 
712       // The character is not safe, at least simple quoting needed.
713       MaxQuotingNeeded = QuotingType::Single;
714     }
715     }
716   }
717 
718   return MaxQuotingNeeded;
719 }
720 
721 template <typename T, typename Context>
722 struct missingTraits
723     : public std::integral_constant<bool,
724                                     !has_ScalarEnumerationTraits<T>::value &&
725                                         !has_ScalarBitSetTraits<T>::value &&
726                                         !has_ScalarTraits<T>::value &&
727                                         !has_BlockScalarTraits<T>::value &&
728                                         !has_TaggedScalarTraits<T>::value &&
729                                         !has_MappingTraits<T, Context>::value &&
730                                         !has_SequenceTraits<T>::value &&
731                                         !has_CustomMappingTraits<T>::value &&
732                                         !has_DocumentListTraits<T>::value &&
733                                         !has_PolymorphicTraits<T>::value> {};
734 
735 template <typename T, typename Context>
736 struct validatedMappingTraits
737     : public std::integral_constant<
738           bool, has_MappingTraits<T, Context>::value &&
739                     has_MappingValidateTraits<T, Context>::value> {};
740 
741 template <typename T, typename Context>
742 struct unvalidatedMappingTraits
743     : public std::integral_constant<
744           bool, has_MappingTraits<T, Context>::value &&
745                     !has_MappingValidateTraits<T, Context>::value> {};
746 
747 // Base class for Input and Output.
748 class IO {
749 public:
750   IO(void *Ctxt = nullptr);
751   virtual ~IO();
752 
753   virtual bool outputting() const = 0;
754 
755   virtual unsigned beginSequence() = 0;
756   virtual bool preflightElement(unsigned, void *&) = 0;
757   virtual void postflightElement(void*) = 0;
758   virtual void endSequence() = 0;
759   virtual bool canElideEmptySequence() = 0;
760 
761   virtual unsigned beginFlowSequence() = 0;
762   virtual bool preflightFlowElement(unsigned, void *&) = 0;
763   virtual void postflightFlowElement(void*) = 0;
764   virtual void endFlowSequence() = 0;
765 
766   virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
767   virtual void beginMapping() = 0;
768   virtual void endMapping() = 0;
769   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
770   virtual void postflightKey(void*) = 0;
771   virtual std::vector<StringRef> keys() = 0;
772 
773   virtual void beginFlowMapping() = 0;
774   virtual void endFlowMapping() = 0;
775 
776   virtual void beginEnumScalar() = 0;
777   virtual bool matchEnumScalar(const char*, bool) = 0;
778   virtual bool matchEnumFallback() = 0;
779   virtual void endEnumScalar() = 0;
780 
781   virtual bool beginBitSetScalar(bool &) = 0;
782   virtual bool bitSetMatch(const char*, bool) = 0;
783   virtual void endBitSetScalar() = 0;
784 
785   virtual void scalarString(StringRef &, QuotingType) = 0;
786   virtual void blockScalarString(StringRef &) = 0;
787   virtual void scalarTag(std::string &) = 0;
788 
789   virtual NodeKind getNodeKind() = 0;
790 
791   virtual void setError(const Twine &) = 0;
792 
793   template <typename T>
794   void enumCase(T &Val, const char* Str, const T ConstVal) {
795     if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
796       Val = ConstVal;
797     }
798   }
799 
800   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
801   template <typename T>
802   void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
803     if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
804       Val = ConstVal;
805     }
806   }
807 
808   template <typename FBT, typename T>
809   void enumFallback(T &Val) {
810     if (matchEnumFallback()) {
811       EmptyContext Context;
812       // FIXME: Force integral conversion to allow strong typedefs to convert.
813       FBT Res = static_cast<typename FBT::BaseType>(Val);
814       yamlize(*this, Res, true, Context);
815       Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
816     }
817   }
818 
819   template <typename T>
820   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
821     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
822       Val = static_cast<T>(Val | ConstVal);
823     }
824   }
825 
826   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
827   template <typename T>
828   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
829     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
830       Val = static_cast<T>(Val | ConstVal);
831     }
832   }
833 
834   template <typename T>
835   void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
836     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
837       Val = Val | ConstVal;
838   }
839 
840   template <typename T>
841   void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
842                         uint32_t Mask) {
843     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
844       Val = Val | ConstVal;
845   }
846 
847   void *getContext() const;
848   void setContext(void *);
849 
850   template <typename T> void mapRequired(const char *Key, T &Val) {
851     EmptyContext Ctx;
852     this->processKey(Key, Val, true, Ctx);
853   }
854 
855   template <typename T, typename Context>
856   void mapRequired(const char *Key, T &Val, Context &Ctx) {
857     this->processKey(Key, Val, true, Ctx);
858   }
859 
860   template <typename T> void mapOptional(const char *Key, T &Val) {
861     EmptyContext Ctx;
862     mapOptionalWithContext(Key, Val, Ctx);
863   }
864 
865   template <typename T, typename DefaultT>
866   void mapOptional(const char *Key, T &Val, const DefaultT &Default) {
867     EmptyContext Ctx;
868     mapOptionalWithContext(Key, Val, Default, Ctx);
869   }
870 
871   template <typename T, typename Context>
872   std::enable_if_t<has_SequenceTraits<T>::value, void>
873   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
874     // omit key/value instead of outputting empty sequence
875     if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
876       return;
877     this->processKey(Key, Val, false, Ctx);
878   }
879 
880   template <typename T, typename Context>
881   void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
882     this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
883                                 Ctx);
884   }
885 
886   template <typename T, typename Context>
887   std::enable_if_t<!has_SequenceTraits<T>::value, void>
888   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
889     this->processKey(Key, Val, false, Ctx);
890   }
891 
892   template <typename T, typename Context, typename DefaultT>
893   void mapOptionalWithContext(const char *Key, T &Val, const DefaultT &Default,
894                               Context &Ctx) {
895     static_assert(std::is_convertible<DefaultT, T>::value,
896                   "Default type must be implicitly convertible to value type!");
897     this->processKeyWithDefault(Key, Val, static_cast<const T &>(Default),
898                                 false, Ctx);
899   }
900 
901 private:
902   template <typename T, typename Context>
903   void processKeyWithDefault(const char *Key, Optional<T> &Val,
904                              const Optional<T> &DefaultValue, bool Required,
905                              Context &Ctx) {
906     assert(DefaultValue.hasValue() == false &&
907            "Optional<T> shouldn't have a value!");
908     void *SaveInfo;
909     bool UseDefault = true;
910     const bool sameAsDefault = outputting() && !Val.hasValue();
911     if (!outputting() && !Val.hasValue())
912       Val = T();
913     if (Val.hasValue() &&
914         this->preflightKey(Key, Required, sameAsDefault, UseDefault,
915                            SaveInfo)) {
916       yamlize(*this, Val.getValue(), Required, Ctx);
917       this->postflightKey(SaveInfo);
918     } else {
919       if (UseDefault)
920         Val = DefaultValue;
921     }
922   }
923 
924   template <typename T, typename Context>
925   void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
926                              bool Required, Context &Ctx) {
927     void *SaveInfo;
928     bool UseDefault;
929     const bool sameAsDefault = outputting() && Val == DefaultValue;
930     if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
931                                                                   SaveInfo) ) {
932       yamlize(*this, Val, Required, Ctx);
933       this->postflightKey(SaveInfo);
934     }
935     else {
936       if ( UseDefault )
937         Val = DefaultValue;
938     }
939   }
940 
941   template <typename T, typename Context>
942   void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
943     void *SaveInfo;
944     bool UseDefault;
945     if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
946       yamlize(*this, Val, Required, Ctx);
947       this->postflightKey(SaveInfo);
948     }
949   }
950 
951 private:
952   void *Ctxt;
953 };
954 
955 namespace detail {
956 
957 template <typename T, typename Context>
958 void doMapping(IO &io, T &Val, Context &Ctx) {
959   MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
960 }
961 
962 template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
963   MappingTraits<T>::mapping(io, Val);
964 }
965 
966 } // end namespace detail
967 
968 template <typename T>
969 std::enable_if_t<has_ScalarEnumerationTraits<T>::value, void>
970 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
971   io.beginEnumScalar();
972   ScalarEnumerationTraits<T>::enumeration(io, Val);
973   io.endEnumScalar();
974 }
975 
976 template <typename T>
977 std::enable_if_t<has_ScalarBitSetTraits<T>::value, void>
978 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
979   bool DoClear;
980   if ( io.beginBitSetScalar(DoClear) ) {
981     if ( DoClear )
982       Val = T();
983     ScalarBitSetTraits<T>::bitset(io, Val);
984     io.endBitSetScalar();
985   }
986 }
987 
988 template <typename T>
989 std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
990                                                            EmptyContext &Ctx) {
991   if ( io.outputting() ) {
992     std::string Storage;
993     raw_string_ostream Buffer(Storage);
994     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
995     StringRef Str = Buffer.str();
996     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
997   }
998   else {
999     StringRef Str;
1000     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
1001     StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
1002     if ( !Result.empty() ) {
1003       io.setError(Twine(Result));
1004     }
1005   }
1006 }
1007 
1008 template <typename T>
1009 std::enable_if_t<has_BlockScalarTraits<T>::value, void>
1010 yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
1011   if (YamlIO.outputting()) {
1012     std::string Storage;
1013     raw_string_ostream Buffer(Storage);
1014     BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
1015     StringRef Str = Buffer.str();
1016     YamlIO.blockScalarString(Str);
1017   } else {
1018     StringRef Str;
1019     YamlIO.blockScalarString(Str);
1020     StringRef Result =
1021         BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
1022     if (!Result.empty())
1023       YamlIO.setError(Twine(Result));
1024   }
1025 }
1026 
1027 template <typename T>
1028 std::enable_if_t<has_TaggedScalarTraits<T>::value, void>
1029 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1030   if (io.outputting()) {
1031     std::string ScalarStorage, TagStorage;
1032     raw_string_ostream ScalarBuffer(ScalarStorage), TagBuffer(TagStorage);
1033     TaggedScalarTraits<T>::output(Val, io.getContext(), ScalarBuffer,
1034                                   TagBuffer);
1035     io.scalarTag(TagBuffer.str());
1036     StringRef ScalarStr = ScalarBuffer.str();
1037     io.scalarString(ScalarStr,
1038                     TaggedScalarTraits<T>::mustQuote(Val, ScalarStr));
1039   } else {
1040     std::string Tag;
1041     io.scalarTag(Tag);
1042     StringRef Str;
1043     io.scalarString(Str, QuotingType::None);
1044     StringRef Result =
1045         TaggedScalarTraits<T>::input(Str, Tag, io.getContext(), Val);
1046     if (!Result.empty()) {
1047       io.setError(Twine(Result));
1048     }
1049   }
1050 }
1051 
1052 template <typename T, typename Context>
1053 std::enable_if_t<validatedMappingTraits<T, Context>::value, void>
1054 yamlize(IO &io, T &Val, bool, Context &Ctx) {
1055   if (has_FlowTraits<MappingTraits<T>>::value)
1056     io.beginFlowMapping();
1057   else
1058     io.beginMapping();
1059   if (io.outputting()) {
1060     StringRef Err = MappingTraits<T>::validate(io, Val);
1061     if (!Err.empty()) {
1062       errs() << Err << "\n";
1063       assert(Err.empty() && "invalid struct trying to be written as yaml");
1064     }
1065   }
1066   detail::doMapping(io, Val, Ctx);
1067   if (!io.outputting()) {
1068     StringRef Err = MappingTraits<T>::validate(io, Val);
1069     if (!Err.empty())
1070       io.setError(Err);
1071   }
1072   if (has_FlowTraits<MappingTraits<T>>::value)
1073     io.endFlowMapping();
1074   else
1075     io.endMapping();
1076 }
1077 
1078 template <typename T, typename Context>
1079 std::enable_if_t<unvalidatedMappingTraits<T, Context>::value, void>
1080 yamlize(IO &io, T &Val, bool, Context &Ctx) {
1081   if (has_FlowTraits<MappingTraits<T>>::value) {
1082     io.beginFlowMapping();
1083     detail::doMapping(io, Val, Ctx);
1084     io.endFlowMapping();
1085   } else {
1086     io.beginMapping();
1087     detail::doMapping(io, Val, Ctx);
1088     io.endMapping();
1089   }
1090 }
1091 
1092 template <typename T>
1093 std::enable_if_t<has_CustomMappingTraits<T>::value, void>
1094 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1095   if ( io.outputting() ) {
1096     io.beginMapping();
1097     CustomMappingTraits<T>::output(io, Val);
1098     io.endMapping();
1099   } else {
1100     io.beginMapping();
1101     for (StringRef key : io.keys())
1102       CustomMappingTraits<T>::inputOne(io, key, Val);
1103     io.endMapping();
1104   }
1105 }
1106 
1107 template <typename T>
1108 std::enable_if_t<has_PolymorphicTraits<T>::value, void>
1109 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1110   switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
1111                           : io.getNodeKind()) {
1112   case NodeKind::Scalar:
1113     return yamlize(io, PolymorphicTraits<T>::getAsScalar(Val), true, Ctx);
1114   case NodeKind::Map:
1115     return yamlize(io, PolymorphicTraits<T>::getAsMap(Val), true, Ctx);
1116   case NodeKind::Sequence:
1117     return yamlize(io, PolymorphicTraits<T>::getAsSequence(Val), true, Ctx);
1118   }
1119 }
1120 
1121 template <typename T>
1122 std::enable_if_t<missingTraits<T, EmptyContext>::value, void>
1123 yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
1124   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1125 }
1126 
1127 template <typename T, typename Context>
1128 std::enable_if_t<has_SequenceTraits<T>::value, void>
1129 yamlize(IO &io, T &Seq, bool, Context &Ctx) {
1130   if ( has_FlowTraits< SequenceTraits<T>>::value ) {
1131     unsigned incnt = io.beginFlowSequence();
1132     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1133     for(unsigned i=0; i < count; ++i) {
1134       void *SaveInfo;
1135       if ( io.preflightFlowElement(i, SaveInfo) ) {
1136         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1137         io.postflightFlowElement(SaveInfo);
1138       }
1139     }
1140     io.endFlowSequence();
1141   }
1142   else {
1143     unsigned incnt = io.beginSequence();
1144     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
1145     for(unsigned i=0; i < count; ++i) {
1146       void *SaveInfo;
1147       if ( io.preflightElement(i, SaveInfo) ) {
1148         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
1149         io.postflightElement(SaveInfo);
1150       }
1151     }
1152     io.endSequence();
1153   }
1154 }
1155 
1156 template<>
1157 struct ScalarTraits<bool> {
1158   static void output(const bool &, void* , raw_ostream &);
1159   static StringRef input(StringRef, void *, bool &);
1160   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1161 };
1162 
1163 template<>
1164 struct ScalarTraits<StringRef> {
1165   static void output(const StringRef &, void *, raw_ostream &);
1166   static StringRef input(StringRef, void *, StringRef &);
1167   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1168 };
1169 
1170 template<>
1171 struct ScalarTraits<std::string> {
1172   static void output(const std::string &, void *, raw_ostream &);
1173   static StringRef input(StringRef, void *, std::string &);
1174   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
1175 };
1176 
1177 template<>
1178 struct ScalarTraits<uint8_t> {
1179   static void output(const uint8_t &, void *, raw_ostream &);
1180   static StringRef input(StringRef, void *, uint8_t &);
1181   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1182 };
1183 
1184 template<>
1185 struct ScalarTraits<uint16_t> {
1186   static void output(const uint16_t &, void *, raw_ostream &);
1187   static StringRef input(StringRef, void *, uint16_t &);
1188   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1189 };
1190 
1191 template<>
1192 struct ScalarTraits<uint32_t> {
1193   static void output(const uint32_t &, void *, raw_ostream &);
1194   static StringRef input(StringRef, void *, uint32_t &);
1195   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1196 };
1197 
1198 template<>
1199 struct ScalarTraits<uint64_t> {
1200   static void output(const uint64_t &, void *, raw_ostream &);
1201   static StringRef input(StringRef, void *, uint64_t &);
1202   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1203 };
1204 
1205 template<>
1206 struct ScalarTraits<int8_t> {
1207   static void output(const int8_t &, void *, raw_ostream &);
1208   static StringRef input(StringRef, void *, int8_t &);
1209   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1210 };
1211 
1212 template<>
1213 struct ScalarTraits<int16_t> {
1214   static void output(const int16_t &, void *, raw_ostream &);
1215   static StringRef input(StringRef, void *, int16_t &);
1216   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1217 };
1218 
1219 template<>
1220 struct ScalarTraits<int32_t> {
1221   static void output(const int32_t &, void *, raw_ostream &);
1222   static StringRef input(StringRef, void *, int32_t &);
1223   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1224 };
1225 
1226 template<>
1227 struct ScalarTraits<int64_t> {
1228   static void output(const int64_t &, void *, raw_ostream &);
1229   static StringRef input(StringRef, void *, int64_t &);
1230   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1231 };
1232 
1233 template<>
1234 struct ScalarTraits<float> {
1235   static void output(const float &, void *, raw_ostream &);
1236   static StringRef input(StringRef, void *, float &);
1237   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1238 };
1239 
1240 template<>
1241 struct ScalarTraits<double> {
1242   static void output(const double &, void *, raw_ostream &);
1243   static StringRef input(StringRef, void *, double &);
1244   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
1245 };
1246 
1247 // For endian types, we use existing scalar Traits class for the underlying
1248 // type.  This way endian aware types are supported whenever the traits are
1249 // defined for the underlying type.
1250 template <typename value_type, support::endianness endian, size_t alignment>
1251 struct ScalarTraits<support::detail::packed_endian_specific_integral<
1252                         value_type, endian, alignment>,
1253                     std::enable_if_t<has_ScalarTraits<value_type>::value>> {
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     std::enable_if_t<has_ScalarEnumerationTraits<value_type>::value>> {
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     std::enable_if_t<has_ScalarBitSetTraits<value_type>::value>> {
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() const 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 = false;
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() const 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 std::enable_if_t<has_DocumentListTraits<T>::value, Input &>
1691 operator>>(Input &yin, T &docList) {
1692   int i = 0;
1693   EmptyContext Ctx;
1694   while ( yin.setCurrentDocument() ) {
1695     yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
1696     if ( yin.error() )
1697       return yin;
1698     yin.nextDocument();
1699     ++i;
1700   }
1701   return yin;
1702 }
1703 
1704 // Define non-member operator>> so that Input can stream in a map as a document.
1705 template <typename T>
1706 inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Input &>
1707 operator>>(Input &yin, T &docMap) {
1708   EmptyContext Ctx;
1709   yin.setCurrentDocument();
1710   yamlize(yin, docMap, true, Ctx);
1711   return yin;
1712 }
1713 
1714 // Define non-member operator>> so that Input can stream in a sequence as
1715 // a document.
1716 template <typename T>
1717 inline std::enable_if_t<has_SequenceTraits<T>::value, Input &>
1718 operator>>(Input &yin, T &docSeq) {
1719   EmptyContext Ctx;
1720   if (yin.setCurrentDocument())
1721     yamlize(yin, docSeq, true, Ctx);
1722   return yin;
1723 }
1724 
1725 // Define non-member operator>> so that Input can stream in a block scalar.
1726 template <typename T>
1727 inline std::enable_if_t<has_BlockScalarTraits<T>::value, Input &>
1728 operator>>(Input &In, T &Val) {
1729   EmptyContext Ctx;
1730   if (In.setCurrentDocument())
1731     yamlize(In, Val, true, Ctx);
1732   return In;
1733 }
1734 
1735 // Define non-member operator>> so that Input can stream in a string map.
1736 template <typename T>
1737 inline std::enable_if_t<has_CustomMappingTraits<T>::value, Input &>
1738 operator>>(Input &In, T &Val) {
1739   EmptyContext Ctx;
1740   if (In.setCurrentDocument())
1741     yamlize(In, Val, true, Ctx);
1742   return In;
1743 }
1744 
1745 // Define non-member operator>> so that Input can stream in a polymorphic type.
1746 template <typename T>
1747 inline std::enable_if_t<has_PolymorphicTraits<T>::value, Input &>
1748 operator>>(Input &In, T &Val) {
1749   EmptyContext Ctx;
1750   if (In.setCurrentDocument())
1751     yamlize(In, Val, true, Ctx);
1752   return In;
1753 }
1754 
1755 // Provide better error message about types missing a trait specialization
1756 template <typename T>
1757 inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Input &>
1758 operator>>(Input &yin, T &docSeq) {
1759   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1760   return yin;
1761 }
1762 
1763 // Define non-member operator<< so that Output can stream out document list.
1764 template <typename T>
1765 inline std::enable_if_t<has_DocumentListTraits<T>::value, Output &>
1766 operator<<(Output &yout, T &docList) {
1767   EmptyContext Ctx;
1768   yout.beginDocuments();
1769   const size_t count = DocumentListTraits<T>::size(yout, docList);
1770   for(size_t i=0; i < count; ++i) {
1771     if ( yout.preflightDocument(i) ) {
1772       yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
1773               Ctx);
1774       yout.postflightDocument();
1775     }
1776   }
1777   yout.endDocuments();
1778   return yout;
1779 }
1780 
1781 // Define non-member operator<< so that Output can stream out a map.
1782 template <typename T>
1783 inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Output &>
1784 operator<<(Output &yout, T &map) {
1785   EmptyContext Ctx;
1786   yout.beginDocuments();
1787   if ( yout.preflightDocument(0) ) {
1788     yamlize(yout, map, true, Ctx);
1789     yout.postflightDocument();
1790   }
1791   yout.endDocuments();
1792   return yout;
1793 }
1794 
1795 // Define non-member operator<< so that Output can stream out a sequence.
1796 template <typename T>
1797 inline std::enable_if_t<has_SequenceTraits<T>::value, Output &>
1798 operator<<(Output &yout, T &seq) {
1799   EmptyContext Ctx;
1800   yout.beginDocuments();
1801   if ( yout.preflightDocument(0) ) {
1802     yamlize(yout, seq, true, Ctx);
1803     yout.postflightDocument();
1804   }
1805   yout.endDocuments();
1806   return yout;
1807 }
1808 
1809 // Define non-member operator<< so that Output can stream out a block scalar.
1810 template <typename T>
1811 inline std::enable_if_t<has_BlockScalarTraits<T>::value, Output &>
1812 operator<<(Output &Out, T &Val) {
1813   EmptyContext Ctx;
1814   Out.beginDocuments();
1815   if (Out.preflightDocument(0)) {
1816     yamlize(Out, Val, true, Ctx);
1817     Out.postflightDocument();
1818   }
1819   Out.endDocuments();
1820   return Out;
1821 }
1822 
1823 // Define non-member operator<< so that Output can stream out a string map.
1824 template <typename T>
1825 inline std::enable_if_t<has_CustomMappingTraits<T>::value, Output &>
1826 operator<<(Output &Out, T &Val) {
1827   EmptyContext Ctx;
1828   Out.beginDocuments();
1829   if (Out.preflightDocument(0)) {
1830     yamlize(Out, Val, true, Ctx);
1831     Out.postflightDocument();
1832   }
1833   Out.endDocuments();
1834   return Out;
1835 }
1836 
1837 // Define non-member operator<< so that Output can stream out a polymorphic
1838 // type.
1839 template <typename T>
1840 inline std::enable_if_t<has_PolymorphicTraits<T>::value, Output &>
1841 operator<<(Output &Out, T &Val) {
1842   EmptyContext Ctx;
1843   Out.beginDocuments();
1844   if (Out.preflightDocument(0)) {
1845     // FIXME: The parser does not support explicit documents terminated with a
1846     // plain scalar; the end-marker is included as part of the scalar token.
1847     assert(PolymorphicTraits<T>::getKind(Val) != NodeKind::Scalar && "plain scalar documents are not supported");
1848     yamlize(Out, Val, true, Ctx);
1849     Out.postflightDocument();
1850   }
1851   Out.endDocuments();
1852   return Out;
1853 }
1854 
1855 // Provide better error message about types missing a trait specialization
1856 template <typename T>
1857 inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Output &>
1858 operator<<(Output &yout, T &seq) {
1859   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1860   return yout;
1861 }
1862 
1863 template <bool B> struct IsFlowSequenceBase {};
1864 template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
1865 
1866 template <typename T, bool Flow>
1867 struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
1868 private:
1869   using type = typename T::value_type;
1870 
1871 public:
1872   static size_t size(IO &io, T &seq) { return seq.size(); }
1873 
1874   static type &element(IO &io, T &seq, size_t index) {
1875     if (index >= seq.size())
1876       seq.resize(index + 1);
1877     return seq[index];
1878   }
1879 };
1880 
1881 // Simple helper to check an expression can be used as a bool-valued template
1882 // argument.
1883 template <bool> struct CheckIsBool { static const bool value = true; };
1884 
1885 // If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
1886 // SequenceTraits that do the obvious thing.
1887 template <typename T>
1888 struct SequenceTraits<
1889     std::vector<T>,
1890     std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1891     : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
1892 template <typename T, unsigned N>
1893 struct SequenceTraits<
1894     SmallVector<T, N>,
1895     std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1896     : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
1897 template <typename T>
1898 struct SequenceTraits<
1899     SmallVectorImpl<T>,
1900     std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
1901     : SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
1902 
1903 // Sequences of fundamental types use flow formatting.
1904 template <typename T>
1905 struct SequenceElementTraits<T,
1906                              std::enable_if_t<std::is_fundamental<T>::value>> {
1907   static const bool flow = true;
1908 };
1909 
1910 // Sequences of strings use block formatting.
1911 template<> struct SequenceElementTraits<std::string> {
1912   static const bool flow = false;
1913 };
1914 template<> struct SequenceElementTraits<StringRef> {
1915   static const bool flow = false;
1916 };
1917 template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
1918   static const bool flow = false;
1919 };
1920 
1921 /// Implementation of CustomMappingTraits for std::map<std::string, T>.
1922 template <typename T> struct StdMapStringCustomMappingTraitsImpl {
1923   using map_type = std::map<std::string, T>;
1924 
1925   static void inputOne(IO &io, StringRef key, map_type &v) {
1926     io.mapRequired(key.str().c_str(), v[std::string(key)]);
1927   }
1928 
1929   static void output(IO &io, map_type &v) {
1930     for (auto &p : v)
1931       io.mapRequired(p.first.c_str(), p.second);
1932   }
1933 };
1934 
1935 } // end namespace yaml
1936 } // end namespace llvm
1937 
1938 #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)                          \
1939   namespace llvm {                                                             \
1940   namespace yaml {                                                             \
1941   static_assert(                                                               \
1942       !std::is_fundamental<TYPE>::value &&                                     \
1943       !std::is_same<TYPE, std::string>::value &&                               \
1944       !std::is_same<TYPE, llvm::StringRef>::value,                             \
1945       "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control");          \
1946   template <> struct SequenceElementTraits<TYPE> {                             \
1947     static const bool flow = FLOW;                                             \
1948   };                                                                           \
1949   }                                                                            \
1950   }
1951 
1952 /// Utility for declaring that a std::vector of a particular type
1953 /// should be considered a YAML sequence.
1954 #define LLVM_YAML_IS_SEQUENCE_VECTOR(type)                                     \
1955   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
1956 
1957 /// Utility for declaring that a std::vector of a particular type
1958 /// should be considered a YAML flow sequence.
1959 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)                                \
1960   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
1961 
1962 #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)                                 \
1963   namespace llvm {                                                             \
1964   namespace yaml {                                                             \
1965   template <> struct MappingTraits<Type> {                                     \
1966     static void mapping(IO &IO, Type &Obj);                                    \
1967   };                                                                           \
1968   }                                                                            \
1969   }
1970 
1971 #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)                                    \
1972   namespace llvm {                                                             \
1973   namespace yaml {                                                             \
1974   template <> struct ScalarEnumerationTraits<Type> {                           \
1975     static void enumeration(IO &io, Type &Value);                              \
1976   };                                                                           \
1977   }                                                                            \
1978   }
1979 
1980 #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)                                  \
1981   namespace llvm {                                                             \
1982   namespace yaml {                                                             \
1983   template <> struct ScalarBitSetTraits<Type> {                                \
1984     static void bitset(IO &IO, Type &Options);                                 \
1985   };                                                                           \
1986   }                                                                            \
1987   }
1988 
1989 #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)                       \
1990   namespace llvm {                                                             \
1991   namespace yaml {                                                             \
1992   template <> struct ScalarTraits<Type> {                                      \
1993     static void output(const Type &Value, void *ctx, raw_ostream &Out);        \
1994     static StringRef input(StringRef Scalar, void *ctxt, Type &Value);         \
1995     static QuotingType mustQuote(StringRef) { return MustQuote; }              \
1996   };                                                                           \
1997   }                                                                            \
1998   }
1999 
2000 /// Utility for declaring that a std::vector of a particular type
2001 /// should be considered a YAML document list.
2002 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                               \
2003   namespace llvm {                                                             \
2004   namespace yaml {                                                             \
2005   template <unsigned N>                                                        \
2006   struct DocumentListTraits<SmallVector<_type, N>>                             \
2007       : public SequenceTraitsImpl<SmallVector<_type, N>, false> {};            \
2008   template <>                                                                  \
2009   struct DocumentListTraits<std::vector<_type>>                                \
2010       : public SequenceTraitsImpl<std::vector<_type>, false> {};               \
2011   }                                                                            \
2012   }
2013 
2014 /// Utility for declaring that std::map<std::string, _type> should be considered
2015 /// a YAML map.
2016 #define LLVM_YAML_IS_STRING_MAP(_type)                                         \
2017   namespace llvm {                                                             \
2018   namespace yaml {                                                             \
2019   template <>                                                                  \
2020   struct CustomMappingTraits<std::map<std::string, _type>>                     \
2021       : public StdMapStringCustomMappingTraitsImpl<_type> {};                  \
2022   }                                                                            \
2023   }
2024 
2025 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex64)
2026 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex32)
2027 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex16)
2028 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::yaml::Hex8)
2029 
2030 #endif // LLVM_SUPPORT_YAMLTRAITS_H
2031