Home | History | Annotate | Line # | Download | only in Support
      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