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