LCOV - code coverage report
Current view: top level - include/llvm/Support - YAMLTraits.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 303 306 99.0 %
Date: 2017-09-14 15:23:50 Functions: 1328 1460 91.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/Support/YAMLTraits.h --------------------------------*- C++ -*-===//
       2             : //
       3             : //                             The LLVM Linker
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_SUPPORT_YAMLTRAITS_H
      11             : #define LLVM_SUPPORT_YAMLTRAITS_H
      12             : 
      13             : #include "llvm/ADT/Optional.h"
      14             : #include "llvm/ADT/SmallVector.h"
      15             : #include "llvm/ADT/StringMap.h"
      16             : #include "llvm/ADT/StringRef.h"
      17             : #include "llvm/ADT/Twine.h"
      18             : #include "llvm/Support/AlignOf.h"
      19             : #include "llvm/Support/Allocator.h"
      20             : #include "llvm/Support/Endian.h"
      21             : #include "llvm/Support/Regex.h"
      22             : #include "llvm/Support/SourceMgr.h"
      23             : #include "llvm/Support/YAMLParser.h"
      24             : #include "llvm/Support/raw_ostream.h"
      25             : #include <cassert>
      26             : #include <cctype>
      27             : #include <cstddef>
      28             : #include <cstdint>
      29             : #include <map>
      30             : #include <memory>
      31             : #include <new>
      32             : #include <string>
      33             : #include <system_error>
      34             : #include <type_traits>
      35             : #include <vector>
      36             : 
      37             : namespace llvm {
      38             : namespace yaml {
      39             : 
      40             : struct EmptyContext {};
      41             : 
      42             : /// This class should be specialized by any type that needs to be converted
      43             : /// to/from a YAML mapping.  For example:
      44             : ///
      45             : ///     struct MappingTraits<MyStruct> {
      46             : ///       static void mapping(IO &io, MyStruct &s) {
      47             : ///         io.mapRequired("name", s.name);
      48             : ///         io.mapRequired("size", s.size);
      49             : ///         io.mapOptional("age",  s.age);
      50             : ///       }
      51             : ///     };
      52             : template<class T>
      53             : struct MappingTraits {
      54             :   // Must provide:
      55             :   // static void mapping(IO &io, T &fields);
      56             :   // Optionally may provide:
      57             :   // static StringRef validate(IO &io, T &fields);
      58             :   //
      59             :   // The optional flow flag will cause generated YAML to use a flow mapping
      60             :   // (e.g. { a: 0, b: 1 }):
      61             :   // static const bool flow = true;
      62             : };
      63             : 
      64             : /// This class is similar to MappingTraits<T> but allows you to pass in
      65             : /// additional context for each map operation.  For example:
      66             : ///
      67             : ///     struct MappingContextTraits<MyStruct, MyContext> {
      68             : ///       static void mapping(IO &io, MyStruct &s, MyContext &c) {
      69             : ///         io.mapRequired("name", s.name);
      70             : ///         io.mapRequired("size", s.size);
      71             : ///         io.mapOptional("age",  s.age);
      72             : ///         ++c.TimesMapped;
      73             : ///       }
      74             : ///     };
      75             : template <class T, class Context> struct MappingContextTraits {
      76             :   // Must provide:
      77             :   // static void mapping(IO &io, T &fields, Context &Ctx);
      78             :   // Optionally may provide:
      79             :   // static StringRef validate(IO &io, T &fields, Context &Ctx);
      80             :   //
      81             :   // The optional flow flag will cause generated YAML to use a flow mapping
      82             :   // (e.g. { a: 0, b: 1 }):
      83             :   // static const bool flow = true;
      84             : };
      85             : 
      86             : /// This class should be specialized by any integral type that converts
      87             : /// to/from a YAML scalar where there is a one-to-one mapping between
      88             : /// in-memory values and a string in YAML.  For example:
      89             : ///
      90             : ///     struct ScalarEnumerationTraits<Colors> {
      91             : ///         static void enumeration(IO &io, Colors &value) {
      92             : ///           io.enumCase(value, "red",   cRed);
      93             : ///           io.enumCase(value, "blue",  cBlue);
      94             : ///           io.enumCase(value, "green", cGreen);
      95             : ///         }
      96             : ///       };
      97             : template<typename T>
      98             : struct ScalarEnumerationTraits {
      99             :   // Must provide:
     100             :   // static void enumeration(IO &io, T &value);
     101             : };
     102             : 
     103             : /// This class should be specialized by any integer type that is a union
     104             : /// of bit values and the YAML representation is a flow sequence of
     105             : /// strings.  For example:
     106             : ///
     107             : ///      struct ScalarBitSetTraits<MyFlags> {
     108             : ///        static void bitset(IO &io, MyFlags &value) {
     109             : ///          io.bitSetCase(value, "big",   flagBig);
     110             : ///          io.bitSetCase(value, "flat",  flagFlat);
     111             : ///          io.bitSetCase(value, "round", flagRound);
     112             : ///        }
     113             : ///      };
     114             : template<typename T>
     115             : struct ScalarBitSetTraits {
     116             :   // Must provide:
     117             :   // static void bitset(IO &io, T &value);
     118             : };
     119             : 
     120             : /// This class should be specialized by type that requires custom conversion
     121             : /// to/from a yaml scalar.  For example:
     122             : ///
     123             : ///    template<>
     124             : ///    struct ScalarTraits<MyType> {
     125             : ///      static void output(const MyType &val, void*, llvm::raw_ostream &out) {
     126             : ///        // stream out custom formatting
     127             : ///        out << llvm::format("%x", val);
     128             : ///      }
     129             : ///      static StringRef input(StringRef scalar, void*, MyType &value) {
     130             : ///        // parse scalar and set `value`
     131             : ///        // return empty string on success, or error string
     132             : ///        return StringRef();
     133             : ///      }
     134             : ///      static bool mustQuote(StringRef) { return true; }
     135             : ///    };
     136             : template<typename T>
     137             : struct ScalarTraits {
     138             :   // Must provide:
     139             :   //
     140             :   // Function to write the value as a string:
     141             :   //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
     142             :   //
     143             :   // Function to convert a string to a value.  Returns the empty
     144             :   // StringRef on success or an error string if string is malformed:
     145             :   //static StringRef input(StringRef scalar, void *ctxt, T &value);
     146             :   //
     147             :   // Function to determine if the value should be quoted.
     148             :   //static bool mustQuote(StringRef);
     149             : };
     150             : 
     151             : /// This class should be specialized by type that requires custom conversion
     152             : /// to/from a YAML literal block scalar. For example:
     153             : ///
     154             : ///    template <>
     155             : ///    struct BlockScalarTraits<MyType> {
     156             : ///      static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
     157             : ///      {
     158             : ///        // stream out custom formatting
     159             : ///        Out << Val;
     160             : ///      }
     161             : ///      static StringRef input(StringRef Scalar, void*, MyType &Value) {
     162             : ///        // parse scalar and set `value`
     163             : ///        // return empty string on success, or error string
     164             : ///        return StringRef();
     165             : ///      }
     166             : ///    };
     167             : template <typename T>
     168             : struct BlockScalarTraits {
     169             :   // Must provide:
     170             :   //
     171             :   // Function to write the value as a string:
     172             :   // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
     173             :   //
     174             :   // Function to convert a string to a value.  Returns the empty
     175             :   // StringRef on success or an error string if string is malformed:
     176             :   // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
     177             : };
     178             : 
     179             : /// This class should be specialized by any type that needs to be converted
     180             : /// to/from a YAML sequence.  For example:
     181             : ///
     182             : ///    template<>
     183             : ///    struct SequenceTraits<MyContainer> {
     184             : ///      static size_t size(IO &io, MyContainer &seq) {
     185             : ///        return seq.size();
     186             : ///      }
     187             : ///      static MyType& element(IO &, MyContainer &seq, size_t index) {
     188             : ///        if ( index >= seq.size() )
     189             : ///          seq.resize(index+1);
     190             : ///        return seq[index];
     191             : ///      }
     192             : ///    };
     193             : template<typename T, typename EnableIf = void>
     194             : struct SequenceTraits {
     195             :   // Must provide:
     196             :   // static size_t size(IO &io, T &seq);
     197             :   // static T::value_type& element(IO &io, T &seq, size_t index);
     198             :   //
     199             :   // The following is option and will cause generated YAML to use
     200             :   // a flow sequence (e.g. [a,b,c]).
     201             :   // static const bool flow = true;
     202             : };
     203             : 
     204             : /// This class should be specialized by any type for which vectors of that
     205             : /// type need to be converted to/from a YAML sequence.
     206             : template<typename T, typename EnableIf = void>
     207             : struct SequenceElementTraits {
     208             :   // Must provide:
     209             :   // static const bool flow;
     210             : };
     211             : 
     212             : /// This class should be specialized by any type that needs to be converted
     213             : /// to/from a list of YAML documents.
     214             : template<typename T>
     215             : struct DocumentListTraits {
     216             :   // Must provide:
     217             :   // static size_t size(IO &io, T &seq);
     218             :   // static T::value_type& element(IO &io, T &seq, size_t index);
     219             : };
     220             : 
     221             : /// This class should be specialized by any type that needs to be converted
     222             : /// to/from a YAML mapping in the case where the names of the keys are not known
     223             : /// in advance, e.g. a string map.
     224             : template <typename T>
     225             : struct CustomMappingTraits {
     226             :   // static void inputOne(IO &io, StringRef key, T &elem);
     227             :   // static void output(IO &io, T &elem);
     228             : };
     229             : 
     230             : // Only used for better diagnostics of missing traits
     231             : template <typename T>
     232             : struct MissingTrait;
     233             : 
     234             : // Test if ScalarEnumerationTraits<T> is defined on type T.
     235             : template <class T>
     236             : struct has_ScalarEnumerationTraits
     237             : {
     238             :   using Signature_enumeration = void (*)(class IO&, T&);
     239             : 
     240             :   template <typename U>
     241             :   static char test(SameType<Signature_enumeration, &U::enumeration>*);
     242             : 
     243             :   template <typename U>
     244             :   static double test(...);
     245             : 
     246             : public:
     247             :   static bool const value =
     248             :     (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
     249             : };
     250             : 
     251             : // Test if ScalarBitSetTraits<T> is defined on type T.
     252             : template <class T>
     253             : struct has_ScalarBitSetTraits
     254             : {
     255             :   using Signature_bitset = void (*)(class IO&, T&);
     256             : 
     257             :   template <typename U>
     258             :   static char test(SameType<Signature_bitset, &U::bitset>*);
     259             : 
     260             :   template <typename U>
     261             :   static double test(...);
     262             : 
     263             : public:
     264             :   static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
     265             : };
     266             : 
     267             : // Test if ScalarTraits<T> is defined on type T.
     268             : template <class T>
     269             : struct has_ScalarTraits
     270             : {
     271             :   using Signature_input = StringRef (*)(StringRef, void*, T&);
     272             :   using Signature_output = void (*)(const T&, void*, raw_ostream&);
     273             :   using Signature_mustQuote = bool (*)(StringRef);
     274             : 
     275             :   template <typename U>
     276             :   static char test(SameType<Signature_input, &U::input> *,
     277             :                    SameType<Signature_output, &U::output> *,
     278             :                    SameType<Signature_mustQuote, &U::mustQuote> *);
     279             : 
     280             :   template <typename U>
     281             :   static double test(...);
     282             : 
     283             : public:
     284             :   static bool const value =
     285             :       (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
     286             : };
     287             : 
     288             : // Test if BlockScalarTraits<T> is defined on type T.
     289             : template <class T>
     290             : struct has_BlockScalarTraits
     291             : {
     292             :   using Signature_input = StringRef (*)(StringRef, void *, T &);
     293             :   using Signature_output = void (*)(const T &, void *, raw_ostream &);
     294             : 
     295             :   template <typename U>
     296             :   static char test(SameType<Signature_input, &U::input> *,
     297             :                    SameType<Signature_output, &U::output> *);
     298             : 
     299             :   template <typename U>
     300             :   static double test(...);
     301             : 
     302             : public:
     303             :   static bool const value =
     304             :       (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
     305             : };
     306             : 
     307             : // Test if MappingContextTraits<T> is defined on type T.
     308             : template <class T, class Context> struct has_MappingTraits {
     309             :   using Signature_mapping = void (*)(class IO &, T &, Context &);
     310             : 
     311             :   template <typename U>
     312             :   static char test(SameType<Signature_mapping, &U::mapping>*);
     313             : 
     314             :   template <typename U>
     315             :   static double test(...);
     316             : 
     317             : public:
     318             :   static bool const value =
     319             :       (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
     320             : };
     321             : 
     322             : // Test if MappingTraits<T> is defined on type T.
     323             : template <class T> struct has_MappingTraits<T, EmptyContext> {
     324             :   using Signature_mapping = void (*)(class IO &, T &);
     325             : 
     326             :   template <typename U>
     327             :   static char test(SameType<Signature_mapping, &U::mapping> *);
     328             : 
     329             :   template <typename U> static double test(...);
     330             : 
     331             : public:
     332             :   static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
     333             : };
     334             : 
     335             : // Test if MappingContextTraits<T>::validate() is defined on type T.
     336             : template <class T, class Context> struct has_MappingValidateTraits {
     337             :   using Signature_validate = StringRef (*)(class IO &, T &, Context &);
     338             : 
     339             :   template <typename U>
     340             :   static char test(SameType<Signature_validate, &U::validate>*);
     341             : 
     342             :   template <typename U>
     343             :   static double test(...);
     344             : 
     345             : public:
     346             :   static bool const value =
     347             :       (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
     348             : };
     349             : 
     350             : // Test if MappingTraits<T>::validate() is defined on type T.
     351             : template <class T> struct has_MappingValidateTraits<T, EmptyContext> {
     352             :   using Signature_validate = StringRef (*)(class IO &, T &);
     353             : 
     354             :   template <typename U>
     355             :   static char test(SameType<Signature_validate, &U::validate> *);
     356             : 
     357             :   template <typename U> static double test(...);
     358             : 
     359             : public:
     360             :   static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
     361             : };
     362             : 
     363             : // Test if SequenceTraits<T> is defined on type T.
     364             : template <class T>
     365             : struct has_SequenceMethodTraits
     366             : {
     367             :   using Signature_size = size_t (*)(class IO&, T&);
     368             : 
     369             :   template <typename U>
     370             :   static char test(SameType<Signature_size, &U::size>*);
     371             : 
     372             :   template <typename U>
     373             :   static double test(...);
     374             : 
     375             : public:
     376             :   static bool const value =  (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
     377             : };
     378             : 
     379             : // Test if CustomMappingTraits<T> is defined on type T.
     380             : template <class T>
     381             : struct has_CustomMappingTraits
     382             : {
     383             :   using Signature_input = void (*)(IO &io, StringRef key, T &v);
     384             : 
     385             :   template <typename U>
     386             :   static char test(SameType<Signature_input, &U::inputOne>*);
     387             : 
     388             :   template <typename U>
     389             :   static double test(...);
     390             : 
     391             : public:
     392             :   static bool const value =
     393             :       (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
     394             : };
     395             : 
     396             : // has_FlowTraits<int> will cause an error with some compilers because
     397             : // it subclasses int.  Using this wrapper only instantiates the
     398             : // real has_FlowTraits only if the template type is a class.
     399             : template <typename T, bool Enabled = std::is_class<T>::value>
     400             : class has_FlowTraits
     401             : {
     402             : public:
     403             :    static const bool value = false;
     404             : };
     405             : 
     406             : // Some older gcc compilers don't support straight forward tests
     407             : // for members, so test for ambiguity cause by the base and derived
     408             : // classes both defining the member.
     409             : template <class T>
     410             : struct has_FlowTraits<T, true>
     411             : {
     412             :   struct Fallback { bool flow; };
     413             :   struct Derived : T, Fallback { };
     414             : 
     415             :   template<typename C>
     416             :   static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
     417             : 
     418             :   template<typename C>
     419             :   static char (&f(...))[2];
     420             : 
     421             : public:
     422             :   static bool const value = sizeof(f<Derived>(nullptr)) == 2;
     423             : };
     424             : 
     425             : // Test if SequenceTraits<T> is defined on type T
     426             : template<typename T>
     427             : struct has_SequenceTraits : public std::integral_constant<bool,
     428             :                                       has_SequenceMethodTraits<T>::value > { };
     429             : 
     430             : // Test if DocumentListTraits<T> is defined on type T
     431             : template <class T>
     432             : struct has_DocumentListTraits
     433             : {
     434             :   using Signature_size = size_t (*)(class IO &, T &);
     435             : 
     436             :   template <typename U>
     437             :   static char test(SameType<Signature_size, &U::size>*);
     438             : 
     439             :   template <typename U>
     440             :   static double test(...);
     441             : 
     442             : public:
     443             :   static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
     444             : };
     445             : 
     446       22424 : inline bool isNumber(StringRef S) {
     447             :   static const char OctalChars[] = "01234567";
     448       22536 :   if (S.startswith("0") &&
     449       22536 :       S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
     450             :     return true;
     451             : 
     452       22381 :   if (S.startswith("0o") &&
     453       22381 :       S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
     454             :     return true;
     455             : 
     456             :   static const char HexChars[] = "0123456789abcdefABCDEF";
     457       22385 :   if (S.startswith("0x") &&
     458       22385 :       S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
     459             :     return true;
     460             : 
     461             :   static const char DecChars[] = "0123456789";
     462       22379 :   if (S.find_first_not_of(DecChars) == StringRef::npos)
     463             :     return true;
     464             : 
     465       66489 :   if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
     466             :     return true;
     467             : 
     468       44326 :   Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
     469       22163 :   if (FloatMatcher.match(S))
     470             :     return true;
     471             : 
     472       22161 :   return false;
     473             : }
     474             : 
     475       22421 : inline bool isNumeric(StringRef S) {
     476       44857 :   if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
     477             :     return true;
     478             : 
     479       22409 :   if (isNumber(S))
     480             :     return true;
     481             : 
     482       66474 :   if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
     483             :     return true;
     484             : 
     485             :   return false;
     486             : }
     487             : 
     488       22437 : inline bool isNull(StringRef S) {
     489       67307 :   return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
     490       44867 :          S.equals("~");
     491             : }
     492             : 
     493       22427 : inline bool isBool(StringRef S) {
     494       67273 :   return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
     495       89696 :          S.equals("false") || S.equals("False") || S.equals("FALSE");
     496             : }
     497             : 
     498       86402 : inline bool needsQuotes(StringRef S) {
     499       86402 :   if (S.empty())
     500             :     return true;
     501       75442 :   if (isspace(S.front()) || isspace(S.back()))
     502             :     return true;
     503       24902 :   if (S.front() == ',')
     504             :     return true;
     505             : 
     506             :   static const char ScalarSafeChars[] =
     507             :       "abcdefghijklmnopqrstuvwxyz"
     508             :       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
     509       24899 :   if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
     510             :     return true;
     511             : 
     512       22432 :   if (isNull(S))
     513             :     return true;
     514       22427 :   if (isBool(S))
     515             :     return true;
     516       22421 :   if (isNumeric(S))
     517             :     return true;
     518             : 
     519       22158 :   return false;
     520             : }
     521             : 
     522             : template <typename T, typename Context>
     523             : struct missingTraits
     524             :     : public std::integral_constant<bool,
     525             :                                     !has_ScalarEnumerationTraits<T>::value &&
     526             :                                         !has_ScalarBitSetTraits<T>::value &&
     527             :                                         !has_ScalarTraits<T>::value &&
     528             :                                         !has_BlockScalarTraits<T>::value &&
     529             :                                         !has_MappingTraits<T, Context>::value &&
     530             :                                         !has_SequenceTraits<T>::value &&
     531             :                                         !has_CustomMappingTraits<T>::value &&
     532             :                                         !has_DocumentListTraits<T>::value> {};
     533             : 
     534             : template <typename T, typename Context>
     535             : struct validatedMappingTraits
     536             :     : public std::integral_constant<
     537             :           bool, has_MappingTraits<T, Context>::value &&
     538             :                     has_MappingValidateTraits<T, Context>::value> {};
     539             : 
     540             : template <typename T, typename Context>
     541             : struct unvalidatedMappingTraits
     542             :     : public std::integral_constant<
     543             :           bool, has_MappingTraits<T, Context>::value &&
     544             :                     !has_MappingValidateTraits<T, Context>::value> {};
     545             : 
     546             : // Base class for Input and Output.
     547        6829 : class IO {
     548             : public:
     549             :   IO(void *Ctxt = nullptr);
     550             :   virtual ~IO();
     551             : 
     552             :   virtual bool outputting() = 0;
     553             : 
     554             :   virtual unsigned beginSequence() = 0;
     555             :   virtual bool preflightElement(unsigned, void *&) = 0;
     556             :   virtual void postflightElement(void*) = 0;
     557             :   virtual void endSequence() = 0;
     558             :   virtual bool canElideEmptySequence() = 0;
     559             : 
     560             :   virtual unsigned beginFlowSequence() = 0;
     561             :   virtual bool preflightFlowElement(unsigned, void *&) = 0;
     562             :   virtual void postflightFlowElement(void*) = 0;
     563             :   virtual void endFlowSequence() = 0;
     564             : 
     565             :   virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
     566             :   virtual void beginMapping() = 0;
     567             :   virtual void endMapping() = 0;
     568             :   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
     569             :   virtual void postflightKey(void*) = 0;
     570             :   virtual std::vector<StringRef> keys() = 0;
     571             : 
     572             :   virtual void beginFlowMapping() = 0;
     573             :   virtual void endFlowMapping() = 0;
     574             : 
     575             :   virtual void beginEnumScalar() = 0;
     576             :   virtual bool matchEnumScalar(const char*, bool) = 0;
     577             :   virtual bool matchEnumFallback() = 0;
     578             :   virtual void endEnumScalar() = 0;
     579             : 
     580             :   virtual bool beginBitSetScalar(bool &) = 0;
     581             :   virtual bool bitSetMatch(const char*, bool) = 0;
     582             :   virtual void endBitSetScalar() = 0;
     583             : 
     584             :   virtual void scalarString(StringRef &, bool) = 0;
     585             :   virtual void blockScalarString(StringRef &) = 0;
     586             : 
     587             :   virtual void setError(const Twine &) = 0;
     588             : 
     589             :   template <typename T>
     590     1082108 :   void enumCase(T &Val, const char* Str, const T ConstVal) {
     591     1082108 :     if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
     592       20523 :       Val = ConstVal;
     593             :     }
     594     1082108 :   }
     595             : 
     596             :   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
     597             :   template <typename T>
     598       41306 :   void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
     599       50929 :     if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
     600        1590 :       Val = ConstVal;
     601             :     }
     602       41306 :   }
     603             : 
     604             :   template <typename FBT, typename T>
     605        7945 :   void enumFallback(T &Val) {
     606        7945 :     if (matchEnumFallback()) {
     607             :       EmptyContext Context;
     608             :       // FIXME: Force integral conversion to allow strong typedefs to convert.
     609         106 :       FBT Res = static_cast<typename FBT::BaseType>(Val);
     610          53 :       yamlize(*this, Res, true, Context);
     611          53 :       Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
     612             :     }
     613        7945 :   }
     614             : 
     615             :   template <typename T>
     616       16524 :   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
     617       18948 :     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
     618        3427 :       Val = static_cast<T>(Val | ConstVal);
     619             :     }
     620       16524 :   }
     621             : 
     622             :   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
     623             :   template <typename T>
     624        5248 :   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
     625        5248 :     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
     626        1074 :       Val = static_cast<T>(Val | ConstVal);
     627             :     }
     628        5248 :   }
     629             : 
     630             :   template <typename T>
     631             :   void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
     632             :     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
     633             :       Val = Val | ConstVal;
     634             :   }
     635             : 
     636             :   template <typename T>
     637         732 :   void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
     638             :                         uint32_t Mask) {
     639         732 :     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
     640          46 :       Val = Val | ConstVal;
     641         732 :   }
     642             : 
     643             :   void *getContext();
     644             :   void setContext(void *);
     645             : 
     646             :   template <typename T> void mapRequired(const char *Key, T &Val) {
     647             :     EmptyContext Ctx;
     648      171230 :     this->processKey(Key, Val, true, Ctx);
     649             :   }
     650             : 
     651             :   template <typename T, typename Context>
     652             :   void mapRequired(const char *Key, T &Val, Context &Ctx) {
     653           2 :     this->processKey(Key, Val, true, Ctx);
     654             :   }
     655             : 
     656             :   template <typename T> void mapOptional(const char *Key, T &Val) {
     657             :     EmptyContext Ctx;
     658       99675 :     mapOptionalWithContext(Key, Val, Ctx);
     659             :   }
     660             : 
     661             :   template <typename T>
     662             :   void mapOptional(const char *Key, T &Val, const T &Default) {
     663             :     EmptyContext Ctx;
     664      321951 :     mapOptionalWithContext(Key, Val, Default, Ctx);
     665             :   }
     666             : 
     667             :   template <typename T, typename Context>
     668             :   typename std::enable_if<has_SequenceTraits<T>::value, void>::type
     669       27502 :   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
     670             :     // omit key/value instead of outputting empty sequence
     671       79101 :     if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
     672             :       return;
     673       14696 :     this->processKey(Key, Val, false, Ctx);
     674             :   }
     675             : 
     676             :   template <typename T, typename Context>
     677        2827 :   void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
     678       16804 :     this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
     679             :                                 Ctx);
     680        2827 :   }
     681             : 
     682             :   template <typename T, typename Context>
     683             :   typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
     684             :   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
     685       63771 :     this->processKey(Key, Val, false, Ctx);
     686             :   }
     687             : 
     688             :   template <typename T, typename Context>
     689             :   void mapOptionalWithContext(const char *Key, T &Val, const T &Default,
     690             :                               Context &Ctx) {
     691      321951 :     this->processKeyWithDefault(Key, Val, Default, false, Ctx);
     692             :   }
     693             : 
     694             : private:
     695             :   template <typename T, typename Context>
     696       13469 :   void processKeyWithDefault(const char *Key, Optional<T> &Val,
     697             :                              const Optional<T> &DefaultValue, bool Required,
     698             :                              Context &Ctx) {
     699             :     assert(DefaultValue.hasValue() == false &&
     700             :            "Optional<T> shouldn't have a value!");
     701             :     void *SaveInfo;
     702       13469 :     bool UseDefault = true;
     703       13469 :     const bool sameAsDefault = outputting() && !Val.hasValue();
     704       13469 :     if (!outputting() && !Val.hasValue())
     705       17950 :       Val = T();
     706       23635 :     if (Val.hasValue() &&
     707       10166 :         this->preflightKey(Key, Required, sameAsDefault, UseDefault,
     708             :                            SaveInfo)) {
     709        2542 :       yamlize(*this, Val.getValue(), Required, Ctx);
     710        1271 :       this->postflightKey(SaveInfo);
     711             :     } else {
     712       12198 :       if (UseDefault)
     713        6903 :         Val = DefaultValue;
     714             :     }
     715       13469 :   }
     716             : 
     717             :   template <typename T, typename Context>
     718      316884 :   void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
     719             :                              bool Required, Context &Ctx) {
     720             :     void *SaveInfo;
     721             :     bool UseDefault;
     722      346789 :     const bool sameAsDefault = outputting() && Val == DefaultValue;
     723      316884 :     if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
     724             :                                                                   SaveInfo) ) {
     725      153241 :       yamlize(*this, Val, Required, Ctx);
     726      153241 :       this->postflightKey(SaveInfo);
     727             :     }
     728             :     else {
     729      163643 :       if ( UseDefault )
     730       62182 :         Val = DefaultValue;
     731             :     }
     732      316884 :   }
     733             : 
     734             :   template <typename T, typename Context>
     735      249699 :   void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
     736             :     void *SaveInfo;
     737             :     bool UseDefault;
     738      249699 :     if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
     739      199656 :       yamlize(*this, Val, Required, Ctx);
     740      197336 :       this->postflightKey(SaveInfo);
     741             :     }
     742      249699 :   }
     743             : 
     744             : private:
     745             :   void *Ctxt;
     746             : };
     747             : 
     748             : namespace detail {
     749             : 
     750             : template <typename T, typename Context>
     751             : void doMapping(IO &io, T &Val, Context &Ctx) {
     752           2 :   MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
     753             : }
     754             : 
     755             : template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
     756       78016 :   MappingTraits<T>::mapping(io, Val);
     757             : }
     758             : 
     759             : } // end namespace detail
     760             : 
     761             : template <typename T>
     762             : typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
     763       51638 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     764       51638 :   io.beginEnumScalar();
     765       51638 :   ScalarEnumerationTraits<T>::enumeration(io, Val);
     766       51638 :   io.endEnumScalar();
     767       51638 : }
     768             : 
     769             : template <typename T>
     770             : typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
     771        2206 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     772             :   bool DoClear;
     773        2206 :   if ( io.beginBitSetScalar(DoClear) ) {
     774        2206 :     if ( DoClear )
     775        1827 :       Val = static_cast<T>(0);
     776        2206 :     ScalarBitSetTraits<T>::bitset(io, Val);
     777        2206 :     io.endBitSetScalar();
     778             :   }
     779        2206 : }
     780             : 
     781             : template <typename T>
     782             : typename std::enable_if<has_ScalarTraits<T>::value, void>::type
     783      281735 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     784      281735 :   if ( io.outputting() ) {
     785      373510 :     std::string Storage;
     786      373510 :     raw_string_ostream Buffer(Storage);
     787      235104 :     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
     788      373510 :     StringRef Str = Buffer.str();
     789      247049 :     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
     790             :   }
     791             :   else {
     792       94980 :     StringRef Str;
     793      119945 :     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
     794       95852 :     StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
     795       94980 :     if ( !Result.empty() ) {
     796          40 :       io.setError(Twine(Result));
     797             :     }
     798             :   }
     799      281735 : }
     800             : 
     801             : template <typename T>
     802             : typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
     803        5295 : yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
     804        5295 :   if (YamlIO.outputting()) {
     805        6100 :     std::string Storage;
     806        6100 :     raw_string_ostream Buffer(Storage);
     807        6100 :     BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
     808        6100 :     StringRef Str = Buffer.str();
     809        3050 :     YamlIO.blockScalarString(Str);
     810             :   } else {
     811        2245 :     StringRef Str;
     812        2245 :     YamlIO.blockScalarString(Str);
     813        2245 :     StringRef Result =
     814        2245 :         BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
     815        2245 :     if (!Result.empty())
     816           0 :       YamlIO.setError(Twine(Result));
     817             :   }
     818        5295 : }
     819             : 
     820             : template <typename T, typename Context>
     821             : typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
     822         508 : yamlize(IO &io, T &Val, bool, Context &Ctx) {
     823             :   if (has_FlowTraits<MappingTraits<T>>::value)
     824             :     io.beginFlowMapping();
     825             :   else
     826         508 :     io.beginMapping();
     827         508 :   if (io.outputting()) {
     828         175 :     StringRef Err = MappingTraits<T>::validate(io, Val);
     829         175 :     if (!Err.empty()) {
     830           0 :       errs() << Err << "\n";
     831             :       assert(Err.empty() && "invalid struct trying to be written as yaml");
     832             :     }
     833             :   }
     834        1016 :   detail::doMapping(io, Val, Ctx);
     835         508 :   if (!io.outputting()) {
     836         321 :     StringRef Err = MappingTraits<T>::validate(io, Val);
     837         319 :     if (!Err.empty())
     838          12 :       io.setError(Err);
     839             :   }
     840             :   if (has_FlowTraits<MappingTraits<T>>::value)
     841             :     io.endFlowMapping();
     842             :   else
     843         508 :     io.endMapping();
     844         508 : }
     845             : 
     846             : template <typename T, typename Context>
     847             : typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
     848       75190 : yamlize(IO &io, T &Val, bool, Context &Ctx) {
     849             :   if (has_FlowTraits<MappingTraits<T>>::value) {
     850       21622 :     io.beginFlowMapping();
     851       43244 :     detail::doMapping(io, Val, Ctx);
     852       21622 :     io.endFlowMapping();
     853             :   } else {
     854       55888 :     io.beginMapping();
     855      111774 :     detail::doMapping(io, Val, Ctx);
     856       55888 :     io.endMapping();
     857             :   }
     858       75190 : }
     859             : 
     860             : template <typename T>
     861             : typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
     862         156 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     863         156 :   if ( io.outputting() ) {
     864          93 :     io.beginMapping();
     865          93 :     CustomMappingTraits<T>::output(io, Val);
     866          93 :     io.endMapping();
     867             :   } else {
     868          63 :     io.beginMapping();
     869         414 :     for (StringRef key : io.keys())
     870          99 :       CustomMappingTraits<T>::inputOne(io, key, Val);
     871          63 :     io.endMapping();
     872             :   }
     873         156 : }
     874             : 
     875             : template <typename T>
     876             : typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
     877             : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     878             :   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
     879             : }
     880             : 
     881             : template <typename T, typename Context>
     882             : typename std::enable_if<has_SequenceTraits<T>::value, void>::type
     883       26911 : yamlize(IO &io, T &Seq, bool, Context &Ctx) {
     884             :   if ( has_FlowTraits< SequenceTraits<T>>::value ) {
     885        2948 :     unsigned incnt = io.beginFlowSequence();
     886        4594 :     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
     887       20133 :     for(unsigned i=0; i < count; ++i) {
     888             :       void *SaveInfo;
     889       17185 :       if ( io.preflightFlowElement(i, SaveInfo) ) {
     890       28357 :         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
     891       17185 :         io.postflightFlowElement(SaveInfo);
     892             :       }
     893             :     }
     894        2948 :     io.endFlowSequence();
     895             :   }
     896             :   else {
     897       23963 :     unsigned incnt = io.beginSequence();
     898       40834 :     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
     899       92522 :     for(unsigned i=0; i < count; ++i) {
     900             :       void *SaveInfo;
     901       68559 :       if ( io.preflightElement(i, SaveInfo) ) {
     902       69057 :         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
     903       68558 :         io.postflightElement(SaveInfo);
     904             :       }
     905             :     }
     906       23963 :     io.endSequence();
     907             :   }
     908       26911 : }
     909             : 
     910             : template<>
     911             : struct ScalarTraits<bool> {
     912             :   static void output(const bool &, void* , raw_ostream &);
     913             :   static StringRef input(StringRef, void *, bool &);
     914             :   static bool mustQuote(StringRef) { return false; }
     915             : };
     916             : 
     917             : template<>
     918             : struct ScalarTraits<StringRef> {
     919             :   static void output(const StringRef &, void *, raw_ostream &);
     920             :   static StringRef input(StringRef, void *, StringRef &);
     921       28624 :   static bool mustQuote(StringRef S) { return needsQuotes(S); }
     922             : };
     923             : 
     924             : template<>
     925             : struct ScalarTraits<std::string> {
     926             :   static void output(const std::string &, void *, raw_ostream &);
     927             :   static StringRef input(StringRef, void *, std::string &);
     928       14256 :   static bool mustQuote(StringRef S) { return needsQuotes(S); }
     929             : };
     930             : 
     931             : template<>
     932             : struct ScalarTraits<uint8_t> {
     933             :   static void output(const uint8_t &, void *, raw_ostream &);
     934             :   static StringRef input(StringRef, void *, uint8_t &);
     935             :   static bool mustQuote(StringRef) { return false; }
     936             : };
     937             : 
     938             : template<>
     939             : struct ScalarTraits<uint16_t> {
     940             :   static void output(const uint16_t &, void *, raw_ostream &);
     941             :   static StringRef input(StringRef, void *, uint16_t &);
     942             :   static bool mustQuote(StringRef) { return false; }
     943             : };
     944             : 
     945             : template<>
     946             : struct ScalarTraits<uint32_t> {
     947             :   static void output(const uint32_t &, void *, raw_ostream &);
     948             :   static StringRef input(StringRef, void *, uint32_t &);
     949             :   static bool mustQuote(StringRef) { return false; }
     950             : };
     951             : 
     952             : template<>
     953             : struct ScalarTraits<uint64_t> {
     954             :   static void output(const uint64_t &, void *, raw_ostream &);
     955             :   static StringRef input(StringRef, void *, uint64_t &);
     956             :   static bool mustQuote(StringRef) { return false; }
     957             : };
     958             : 
     959             : template<>
     960             : struct ScalarTraits<int8_t> {
     961             :   static void output(const int8_t &, void *, raw_ostream &);
     962             :   static StringRef input(StringRef, void *, int8_t &);
     963             :   static bool mustQuote(StringRef) { return false; }
     964             : };
     965             : 
     966             : template<>
     967             : struct ScalarTraits<int16_t> {
     968             :   static void output(const int16_t &, void *, raw_ostream &);
     969             :   static StringRef input(StringRef, void *, int16_t &);
     970             :   static bool mustQuote(StringRef) { return false; }
     971             : };
     972             : 
     973             : template<>
     974             : struct ScalarTraits<int32_t> {
     975             :   static void output(const int32_t &, void *, raw_ostream &);
     976             :   static StringRef input(StringRef, void *, int32_t &);
     977             :   static bool mustQuote(StringRef) { return false; }
     978             : };
     979             : 
     980             : template<>
     981             : struct ScalarTraits<int64_t> {
     982             :   static void output(const int64_t &, void *, raw_ostream &);
     983             :   static StringRef input(StringRef, void *, int64_t &);
     984             :   static bool mustQuote(StringRef) { return false; }
     985             : };
     986             : 
     987             : template<>
     988             : struct ScalarTraits<float> {
     989             :   static void output(const float &, void *, raw_ostream &);
     990             :   static StringRef input(StringRef, void *, float &);
     991             :   static bool mustQuote(StringRef) { return false; }
     992             : };
     993             : 
     994             : template<>
     995             : struct ScalarTraits<double> {
     996             :   static void output(const double &, void *, raw_ostream &);
     997             :   static StringRef input(StringRef, void *, double &);
     998             :   static bool mustQuote(StringRef) { return false; }
     999             : };
    1000             : 
    1001             : // For endian types, we just use the existing ScalarTraits for the underlying
    1002             : // type.  This way endian aware types are supported whenever a ScalarTraits
    1003             : // is defined for the underlying type.
    1004             : template <typename value_type, support::endianness endian, size_t alignment>
    1005             : struct ScalarTraits<support::detail::packed_endian_specific_integral<
    1006             :     value_type, endian, alignment>> {
    1007             :   using endian_type =
    1008             :       support::detail::packed_endian_specific_integral<value_type, endian,
    1009             :                                                        alignment>;
    1010             : 
    1011             :   static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
    1012          82 :     ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
    1013             :   }
    1014             : 
    1015             :   static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
    1016             :     value_type V;
    1017          48 :     auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
    1018          96 :     E = static_cast<endian_type>(V);
    1019          48 :     return R;
    1020             :   }
    1021             : 
    1022             :   static bool mustQuote(StringRef Str) {
    1023             :     return ScalarTraits<value_type>::mustQuote(Str);
    1024             :   }
    1025             : };
    1026             : 
    1027             : // Utility for use within MappingTraits<>::mapping() method
    1028             : // to [de]normalize an object for use with YAML conversion.
    1029             : template <typename TNorm, typename TFinal>
    1030             : struct MappingNormalization {
    1031        3445 :   MappingNormalization(IO &i_o, TFinal &Obj)
    1032        3445 :       : io(i_o), BufPtr(nullptr), Result(Obj) {
    1033        3445 :     if ( io.outputting() ) {
    1034         544 :       BufPtr = new (&Buffer) TNorm(io, Obj);
    1035             :     }
    1036             :     else {
    1037        6260 :       BufPtr = new (&Buffer) TNorm(io);
    1038             :     }
    1039         822 :   }
    1040             : 
    1041         822 :   ~MappingNormalization() {
    1042        3445 :     if ( ! io.outputting() ) {
    1043        6290 :       Result = BufPtr->denormalize(io);
    1044             :     }
    1045        1404 :     BufPtr->~TNorm();
    1046         998 :   }
    1047             : 
    1048             :   TNorm* operator->() { return BufPtr; }
    1049             : 
    1050             : private:
    1051             :   using Storage = AlignedCharArrayUnion<TNorm>;
    1052             : 
    1053             :   Storage       Buffer;
    1054             :   IO           &io;
    1055             :   TNorm        *BufPtr;
    1056             :   TFinal       &Result;
    1057             : };
    1058             : 
    1059             : // Utility for use within MappingTraits<>::mapping() method
    1060             : // to [de]normalize an object for use with YAML conversion.
    1061             : template <typename TNorm, typename TFinal>
    1062             : struct MappingNormalizationHeap {
    1063         932 :   MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
    1064         932 :     : io(i_o), Result(Obj) {
    1065         932 :     if ( io.outputting() ) {
    1066         826 :       BufPtr = new (&Buffer) TNorm(io, Obj);
    1067             :     }
    1068         106 :     else if (allocator) {
    1069          89 :       BufPtr = allocator->Allocate<TNorm>();
    1070         120 :       new (BufPtr) TNorm(io);
    1071             :     } else {
    1072          17 :       BufPtr = new TNorm(io);
    1073             :     }
    1074         932 :   }
    1075             : 
    1076         932 :   ~MappingNormalizationHeap() {
    1077         932 :     if ( io.outputting() ) {
    1078         826 :       BufPtr->~TNorm();
    1079             :     }
    1080             :     else {
    1081         106 :       Result = BufPtr->denormalize(io);
    1082             :     }
    1083         932 :   }
    1084             : 
    1085             :   TNorm* operator->() { return BufPtr; }
    1086             : 
    1087             : private:
    1088             :   using Storage = AlignedCharArrayUnion<TNorm>;
    1089             : 
    1090             :   Storage       Buffer;
    1091             :   IO           &io;
    1092             :   TNorm        *BufPtr = nullptr;
    1093             :   TFinal       &Result;
    1094             : };
    1095             : 
    1096             : ///
    1097             : /// The Input class is used to parse a yaml document into in-memory structs
    1098             : /// and vectors.
    1099             : ///
    1100             : /// It works by using YAMLParser to do a syntax parse of the entire yaml
    1101             : /// document, then the Input class builds a graph of HNodes which wraps
    1102             : /// each yaml Node.  The extra layer is buffering.  The low level yaml
    1103             : /// parser only lets you look at each node once.  The buffering layer lets
    1104             : /// you search and interate multiple times.  This is necessary because
    1105             : /// the mapRequired() method calls may not be in the same order
    1106             : /// as the keys in the document.
    1107             : ///
    1108        8880 : class Input : public IO {
    1109             : public:
    1110             :   // Construct a yaml Input object from a StringRef and optional
    1111             :   // user-data. The DiagHandler can be specified to provide
    1112             :   // alternative error reporting.
    1113             :   Input(StringRef InputContent,
    1114             :         void *Ctxt = nullptr,
    1115             :         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
    1116             :         void *DiagHandlerCtxt = nullptr);
    1117             :   Input(MemoryBufferRef Input,
    1118             :         void *Ctxt = nullptr,
    1119             :         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
    1120             :         void *DiagHandlerCtxt = nullptr);
    1121             :   ~Input() override;
    1122             : 
    1123             :   // Check if there was an syntax or semantic error during parsing.
    1124             :   std::error_code error();
    1125             : 
    1126             : private:
    1127             :   bool outputting() override;
    1128             :   bool mapTag(StringRef, bool) override;
    1129             :   void beginMapping() override;
    1130             :   void endMapping() override;
    1131             :   bool preflightKey(const char *, bool, bool, bool &, void *&) override;
    1132             :   void postflightKey(void *) override;
    1133             :   std::vector<StringRef> keys() override;
    1134             :   void beginFlowMapping() override;
    1135             :   void endFlowMapping() override;
    1136             :   unsigned beginSequence() override;
    1137             :   void endSequence() override;
    1138             :   bool preflightElement(unsigned index, void *&) override;
    1139             :   void postflightElement(void *) override;
    1140             :   unsigned beginFlowSequence() override;
    1141             :   bool preflightFlowElement(unsigned , void *&) override;
    1142             :   void postflightFlowElement(void *) override;
    1143             :   void endFlowSequence() override;
    1144             :   void beginEnumScalar() override;
    1145             :   bool matchEnumScalar(const char*, bool) override;
    1146             :   bool matchEnumFallback() override;
    1147             :   void endEnumScalar() override;
    1148             :   bool beginBitSetScalar(bool &) override;
    1149             :   bool bitSetMatch(const char *, bool ) override;
    1150             :   void endBitSetScalar() override;
    1151             :   void scalarString(StringRef &, bool) override;
    1152             :   void blockScalarString(StringRef &) override;
    1153             :   void setError(const Twine &message) override;
    1154             :   bool canElideEmptySequence() override;
    1155             : 
    1156             :   class HNode {
    1157             :     virtual void anchor();
    1158             : 
    1159             :   public:
    1160      165264 :     HNode(Node *n) : _node(n) { }
    1161           0 :     virtual ~HNode() = default;
    1162             : 
    1163             :     static bool classof(const HNode *) { return true; }
    1164             : 
    1165             :     Node *_node;
    1166             :   };
    1167             : 
    1168         566 :   class EmptyHNode : public HNode {
    1169             :     void anchor() override;
    1170             : 
    1171             :   public:
    1172        1134 :     EmptyHNode(Node *n) : HNode(n) { }
    1173             : 
    1174        1058 :     static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
    1175             : 
    1176             :     static bool classof(const EmptyHNode *) { return true; }
    1177             :   };
    1178             : 
    1179      122202 :   class ScalarHNode : public HNode {
    1180             :     void anchor() override;
    1181             : 
    1182             :   public:
    1183      244594 :     ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
    1184             : 
    1185             :     StringRef value() const { return _value; }
    1186             : 
    1187             :     static bool classof(const HNode *n) {
    1188      590318 :       return ScalarNode::classof(n->_node) ||
    1189        4492 :              BlockScalarNode::classof(n->_node);
    1190             :     }
    1191             : 
    1192             :     static bool classof(const ScalarHNode *) { return true; }
    1193             : 
    1194             :   protected:
    1195             :     StringRef _value;
    1196             :   };
    1197             : 
    1198       65334 :   class MapHNode : public HNode {
    1199             :     void anchor() override;
    1200             : 
    1201             :   public:
    1202      130804 :     MapHNode(Node *n) : HNode(n) { }
    1203             : 
    1204             :     static bool classof(const HNode *n) {
    1205      663790 :       return MappingNode::classof(n->_node);
    1206             :     }
    1207             : 
    1208             :     static bool classof(const MapHNode *) { return true; }
    1209             : 
    1210             :     using NameToNode = StringMap<std::unique_ptr<HNode>>;
    1211             : 
    1212             :     NameToNode Mapping;
    1213             :     SmallVector<std::string, 6> ValidKeys;
    1214             :   };
    1215             : 
    1216        9690 :   class SequenceHNode : public HNode {
    1217             :     void anchor() override;
    1218             : 
    1219             :   public:
    1220       29097 :     SequenceHNode(Node *n) : HNode(n) { }
    1221             : 
    1222             :     static bool classof(const HNode *n) {
    1223      129024 :       return SequenceNode::classof(n->_node);
    1224             :     }
    1225             : 
    1226             :     static bool classof(const SequenceHNode *) { return true; }
    1227             : 
    1228             :     std::vector<std::unique_ptr<HNode>> Entries;
    1229             :   };
    1230             : 
    1231             :   std::unique_ptr<Input::HNode> createHNodes(Node *node);
    1232             :   void setError(HNode *hnode, const Twine &message);
    1233             :   void setError(Node *node, const Twine &message);
    1234             : 
    1235             : public:
    1236             :   // These are only used by operator>>. They could be private
    1237             :   // if those templated things could be made friends.
    1238             :   bool setCurrentDocument();
    1239             :   bool nextDocument();
    1240             : 
    1241             :   /// Returns the current node that's being parsed by the YAML Parser.
    1242             :   const Node *getCurrentNode() const;
    1243             : 
    1244             : private:
    1245             :   SourceMgr                           SrcMgr; // must be before Strm
    1246             :   std::unique_ptr<llvm::yaml::Stream> Strm;
    1247             :   std::unique_ptr<HNode>              TopNode;
    1248             :   std::error_code                     EC;
    1249             :   BumpPtrAllocator                    StringAllocator;
    1250             :   document_iterator                   DocIterator;
    1251             :   std::vector<bool>                   BitValuesUsed;
    1252             :   HNode *CurrentNode = nullptr;
    1253             :   bool                                ScalarMatchFound;
    1254             : };
    1255             : 
    1256             : ///
    1257             : /// The Output class is used to generate a yaml document from in-memory structs
    1258             : /// and vectors.
    1259             : ///
    1260        7788 : class Output : public IO {
    1261             : public:
    1262             :   Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
    1263             :   ~Output() override;
    1264             : 
    1265             :   /// \brief Set whether or not to output optional values which are equal
    1266             :   /// to the default value.  By default, when outputting if you attempt
    1267             :   /// to write a value that is equal to the default, the value gets ignored.
    1268             :   /// Sometimes, it is useful to be able to see these in the resulting YAML
    1269             :   /// anyway.
    1270        2487 :   void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
    1271             : 
    1272             :   bool outputting() override;
    1273             :   bool mapTag(StringRef, bool) override;
    1274             :   void beginMapping() override;
    1275             :   void endMapping() override;
    1276             :   bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
    1277             :   void postflightKey(void *) override;
    1278             :   std::vector<StringRef> keys() override;
    1279             :   void beginFlowMapping() override;
    1280             :   void endFlowMapping() override;
    1281             :   unsigned beginSequence() override;
    1282             :   void endSequence() override;
    1283             :   bool preflightElement(unsigned, void *&) override;
    1284             :   void postflightElement(void *) override;
    1285             :   unsigned beginFlowSequence() override;
    1286             :   bool preflightFlowElement(unsigned, void *&) override;
    1287             :   void postflightFlowElement(void *) override;
    1288             :   void endFlowSequence() override;
    1289             :   void beginEnumScalar() override;
    1290             :   bool matchEnumScalar(const char*, bool) override;
    1291             :   bool matchEnumFallback() override;
    1292             :   void endEnumScalar() override;
    1293             :   bool beginBitSetScalar(bool &) override;
    1294             :   bool bitSetMatch(const char *, bool ) override;
    1295             :   void endBitSetScalar() override;
    1296             :   void scalarString(StringRef &, bool) override;
    1297             :   void blockScalarString(StringRef &) override;
    1298             :   void setError(const Twine &message) override;
    1299             :   bool canElideEmptySequence() override;
    1300             : 
    1301             :   // These are only used by operator<<. They could be private
    1302             :   // if that templated operator could be made a friend.
    1303             :   void beginDocuments();
    1304             :   bool preflightDocument(unsigned);
    1305             :   void postflightDocument();
    1306             :   void endDocuments();
    1307             : 
    1308             : private:
    1309             :   void output(StringRef s);
    1310             :   void outputUpToEndOfLine(StringRef s);
    1311             :   void newLineCheck();
    1312             :   void outputNewLine();
    1313             :   void paddedKey(StringRef key);
    1314             :   void flowKey(StringRef Key);
    1315             : 
    1316             :   enum InState {
    1317             :     inSeq,
    1318             :     inFlowSeq,
    1319             :     inMapFirstKey,
    1320             :     inMapOtherKey,
    1321             :     inFlowMapFirstKey,
    1322             :     inFlowMapOtherKey
    1323             :   };
    1324             : 
    1325             :   raw_ostream &Out;
    1326             :   int WrapColumn;
    1327             :   SmallVector<InState, 8> StateStack;
    1328             :   int Column = 0;
    1329             :   int ColumnAtFlowStart = 0;
    1330             :   int ColumnAtMapFlowStart = 0;
    1331             :   bool NeedBitValueComma = false;
    1332             :   bool NeedFlowSequenceComma = false;
    1333             :   bool EnumerationMatchFound = false;
    1334             :   bool NeedsNewLine = false;
    1335             :   bool WriteDefaultValues = false;
    1336             : };
    1337             : 
    1338             : /// YAML I/O does conversion based on types. But often native data types
    1339             : /// are just a typedef of built in intergral types (e.g. int).  But the C++
    1340             : /// type matching system sees through the typedef and all the typedefed types
    1341             : /// look like a built in type. This will cause the generic YAML I/O conversion
    1342             : /// to be used. To provide better control over the YAML conversion, you can
    1343             : /// use this macro instead of typedef.  It will create a class with one field
    1344             : /// and automatic conversion operators to and from the base type.
    1345             : /// Based on BOOST_STRONG_TYPEDEF
    1346             : #define LLVM_YAML_STRONG_TYPEDEF(_base, _type)                                 \
    1347             :     struct _type {                                                             \
    1348             :         _type() = default;                                                     \
    1349             :         _type(const _base v) : value(v) {}                                     \
    1350             :         _type(const _type &v) = default;                                       \
    1351             :         _type &operator=(const _type &rhs) = default;                          \
    1352             :         _type &operator=(const _base &rhs) { value = rhs; return *this; }      \
    1353             :         operator const _base & () const { return value; }                      \
    1354             :         bool operator==(const _type &rhs) const { return value == rhs.value; } \
    1355             :         bool operator==(const _base &rhs) const { return value == rhs; }       \
    1356             :         bool operator<(const _type &rhs) const { return value < rhs.value; }   \
    1357             :         _base value;                                                           \
    1358             :         using BaseType = _base;                                                \
    1359             :     };
    1360             : 
    1361             : ///
    1362             : /// Use these types instead of uintXX_t in any mapping to have
    1363             : /// its yaml output formatted as hexadecimal.
    1364             : ///
    1365        6664 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
    1366         307 : LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
    1367        9853 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
    1368       15744 : LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
    1369             : 
    1370             : template<>
    1371             : struct ScalarTraits<Hex8> {
    1372             :   static void output(const Hex8 &, void *, raw_ostream &);
    1373             :   static StringRef input(StringRef, void *, Hex8 &);
    1374             :   static bool mustQuote(StringRef) { return false; }
    1375             : };
    1376             : 
    1377             : template<>
    1378             : struct ScalarTraits<Hex16> {
    1379             :   static void output(const Hex16 &, void *, raw_ostream &);
    1380             :   static StringRef input(StringRef, void *, Hex16 &);
    1381             :   static bool mustQuote(StringRef) { return false; }
    1382             : };
    1383             : 
    1384             : template<>
    1385             : struct ScalarTraits<Hex32> {
    1386             :   static void output(const Hex32 &, void *, raw_ostream &);
    1387             :   static StringRef input(StringRef, void *, Hex32 &);
    1388             :   static bool mustQuote(StringRef) { return false; }
    1389             : };
    1390             : 
    1391             : template<>
    1392             : struct ScalarTraits<Hex64> {
    1393             :   static void output(const Hex64 &, void *, raw_ostream &);
    1394             :   static StringRef input(StringRef, void *, Hex64 &);
    1395             :   static bool mustQuote(StringRef) { return false; }
    1396             : };
    1397             : 
    1398             : // Define non-member operator>> so that Input can stream in a document list.
    1399             : template <typename T>
    1400             : inline
    1401             : typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
    1402         744 : operator>>(Input &yin, T &docList) {
    1403         744 :   int i = 0;
    1404             :   EmptyContext Ctx;
    1405        2346 :   while ( yin.setCurrentDocument() ) {
    1406         812 :     yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
    1407         812 :     if ( yin.error() )
    1408             :       return yin;
    1409         801 :     yin.nextDocument();
    1410         801 :     ++i;
    1411             :   }
    1412             :   return yin;
    1413             : }
    1414             : 
    1415             : // Define non-member operator>> so that Input can stream in a map as a document.
    1416             : template <typename T>
    1417             : inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
    1418             :                                Input &>::type
    1419             : operator>>(Input &yin, T &docMap) {
    1420             :   EmptyContext Ctx;
    1421        1140 :   yin.setCurrentDocument();
    1422        1140 :   yamlize(yin, docMap, true, Ctx);
    1423             :   return yin;
    1424             : }
    1425             : 
    1426             : // Define non-member operator>> so that Input can stream in a sequence as
    1427             : // a document.
    1428             : template <typename T>
    1429             : inline
    1430             : typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
    1431         394 : operator>>(Input &yin, T &docSeq) {
    1432             :   EmptyContext Ctx;
    1433         394 :   if (yin.setCurrentDocument())
    1434          73 :     yamlize(yin, docSeq, true, Ctx);
    1435         394 :   return yin;
    1436             : }
    1437             : 
    1438             : // Define non-member operator>> so that Input can stream in a block scalar.
    1439             : template <typename T>
    1440             : inline
    1441             : typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
    1442           1 : operator>>(Input &In, T &Val) {
    1443             :   EmptyContext Ctx;
    1444           1 :   if (In.setCurrentDocument())
    1445           1 :     yamlize(In, Val, true, Ctx);
    1446           1 :   return In;
    1447             : }
    1448             : 
    1449             : // Define non-member operator>> so that Input can stream in a string map.
    1450             : template <typename T>
    1451             : inline
    1452             : typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
    1453           2 : operator>>(Input &In, T &Val) {
    1454             :   EmptyContext Ctx;
    1455           2 :   if (In.setCurrentDocument())
    1456           2 :     yamlize(In, Val, true, Ctx);
    1457           2 :   return In;
    1458             : }
    1459             : 
    1460             : // Provide better error message about types missing a trait specialization
    1461             : template <typename T>
    1462             : inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
    1463             :                                Input &>::type
    1464             : operator>>(Input &yin, T &docSeq) {
    1465             :   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
    1466             :   return yin;
    1467             : }
    1468             : 
    1469             : // Define non-member operator<< so that Output can stream out document list.
    1470             : template <typename T>
    1471             : inline
    1472             : typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
    1473           3 : operator<<(Output &yout, T &docList) {
    1474             :   EmptyContext Ctx;
    1475           3 :   yout.beginDocuments();
    1476           6 :   const size_t count = DocumentListTraits<T>::size(yout, docList);
    1477           8 :   for(size_t i=0; i < count; ++i) {
    1478           5 :     if ( yout.preflightDocument(i) ) {
    1479           5 :       yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
    1480             :               Ctx);
    1481           5 :       yout.postflightDocument();
    1482             :     }
    1483             :   }
    1484           3 :   yout.endDocuments();
    1485           3 :   return yout;
    1486             : }
    1487             : 
    1488             : // Define non-member operator<< so that Output can stream out a map.
    1489             : template <typename T>
    1490             : inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
    1491             :                                Output &>::type
    1492        3428 : operator<<(Output &yout, T &map) {
    1493             :   EmptyContext Ctx;
    1494        3428 :   yout.beginDocuments();
    1495        3428 :   if ( yout.preflightDocument(0) ) {
    1496        3428 :     yamlize(yout, map, true, Ctx);
    1497        3428 :     yout.postflightDocument();
    1498             :   }
    1499        3428 :   yout.endDocuments();
    1500        3428 :   return yout;
    1501             : }
    1502             : 
    1503             : // Define non-member operator<< so that Output can stream out a sequence.
    1504             : template <typename T>
    1505             : inline
    1506             : typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
    1507           9 : operator<<(Output &yout, T &seq) {
    1508             :   EmptyContext Ctx;
    1509           9 :   yout.beginDocuments();
    1510           9 :   if ( yout.preflightDocument(0) ) {
    1511           9 :     yamlize(yout, seq, true, Ctx);
    1512           9 :     yout.postflightDocument();
    1513             :   }
    1514           9 :   yout.endDocuments();
    1515           9 :   return yout;
    1516             : }
    1517             : 
    1518             : // Define non-member operator<< so that Output can stream out a block scalar.
    1519             : template <typename T>
    1520             : inline
    1521             : typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
    1522         588 : operator<<(Output &Out, T &Val) {
    1523             :   EmptyContext Ctx;
    1524         588 :   Out.beginDocuments();
    1525         588 :   if (Out.preflightDocument(0)) {
    1526         588 :     yamlize(Out, Val, true, Ctx);
    1527         588 :     Out.postflightDocument();
    1528             :   }
    1529         588 :   Out.endDocuments();
    1530         588 :   return Out;
    1531             : }
    1532             : 
    1533             : // Define non-member operator<< so that Output can stream out a string map.
    1534             : template <typename T>
    1535             : inline
    1536             : typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
    1537           2 : operator<<(Output &Out, T &Val) {
    1538             :   EmptyContext Ctx;
    1539           2 :   Out.beginDocuments();
    1540           2 :   if (Out.preflightDocument(0)) {
    1541           2 :     yamlize(Out, Val, true, Ctx);
    1542           2 :     Out.postflightDocument();
    1543             :   }
    1544           2 :   Out.endDocuments();
    1545           2 :   return Out;
    1546             : }
    1547             : 
    1548             : // Provide better error message about types missing a trait specialization
    1549             : template <typename T>
    1550             : inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
    1551             :                                Output &>::type
    1552             : operator<<(Output &yout, T &seq) {
    1553             :   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
    1554             :   return yout;
    1555             : }
    1556             : 
    1557             : template <bool B> struct IsFlowSequenceBase {};
    1558             : template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
    1559             : 
    1560             : template <typename T, bool Flow>
    1561             : struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
    1562             : private:
    1563             :   using type = typename T::value_type;
    1564             : 
    1565             : public:
    1566       18656 :   static size_t size(IO &io, T &seq) { return seq.size(); }
    1567             : 
    1568       72842 :   static type &element(IO &io, T &seq, size_t index) {
    1569      156096 :     if (index >= seq.size())
    1570       20885 :       seq.resize(index + 1);
    1571      156096 :     return seq[index];
    1572             :   }
    1573             : };
    1574             : 
    1575             : // Simple helper to check an expression can be used as a bool-valued template
    1576             : // argument.
    1577             : template <bool> struct CheckIsBool { static const bool value = true; };
    1578             : 
    1579             : // If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
    1580             : // SequenceTraits that do the obvious thing.
    1581             : template <typename T>
    1582             : struct SequenceTraits<std::vector<T>,
    1583             :                       typename std::enable_if<CheckIsBool<
    1584             :                           SequenceElementTraits<T>::flow>::value>::type>
    1585             :     : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
    1586             : template <typename T, unsigned N>
    1587             : struct SequenceTraits<SmallVector<T, N>,
    1588             :                       typename std::enable_if<CheckIsBool<
    1589             :                           SequenceElementTraits<T>::flow>::value>::type>
    1590             :     : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
    1591             : 
    1592             : // Sequences of fundamental types use flow formatting.
    1593             : template <typename T>
    1594             : struct SequenceElementTraits<
    1595             :     T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
    1596             :   static const bool flow = true;
    1597             : };
    1598             : 
    1599             : // Sequences of strings use block formatting.
    1600             : template<> struct SequenceElementTraits<std::string> {
    1601             :   static const bool flow = false;
    1602             : };
    1603             : template<> struct SequenceElementTraits<StringRef> {
    1604             :   static const bool flow = false;
    1605             : };
    1606             : template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
    1607             :   static const bool flow = false;
    1608             : };
    1609             : 
    1610             : /// Implementation of CustomMappingTraits for std::map<std::string, T>.
    1611             : template <typename T> struct StdMapStringCustomMappingTraitsImpl {
    1612             :   using map_type = std::map<std::string, T>;
    1613             : 
    1614          50 :   static void inputOne(IO &io, StringRef key, map_type &v) {
    1615         300 :     io.mapRequired(key.str().c_str(), v[key]);
    1616          50 :   }
    1617             : 
    1618          22 :   static void output(IO &io, map_type &v) {
    1619         104 :     for (auto &p : v)
    1620         114 :       io.mapRequired(p.first.c_str(), p.second);
    1621          22 :   }
    1622             : };
    1623             : 
    1624             : } // end namespace yaml
    1625             : } // end namespace llvm
    1626             : 
    1627             : #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)                          \
    1628             :   namespace llvm {                                                             \
    1629             :   namespace yaml {                                                             \
    1630             :   static_assert(                                                               \
    1631             :       !std::is_fundamental<TYPE>::value &&                                     \
    1632             :       !std::is_same<TYPE, std::string>::value &&                               \
    1633             :       !std::is_same<TYPE, llvm::StringRef>::value,                             \
    1634             :       "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control");          \
    1635             :   template <> struct SequenceElementTraits<TYPE> {                             \
    1636             :     static const bool flow = FLOW;                                             \
    1637             :   };                                                                           \
    1638             :   }                                                                            \
    1639             :   }
    1640             : 
    1641             : /// Utility for declaring that a std::vector of a particular type
    1642             : /// should be considered a YAML sequence.
    1643             : #define LLVM_YAML_IS_SEQUENCE_VECTOR(type)                                     \
    1644             :   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
    1645             : 
    1646             : /// Utility for declaring that a std::vector of a particular type
    1647             : /// should be considered a YAML flow sequence.
    1648             : #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)                                \
    1649             :   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
    1650             : 
    1651             : #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)                                 \
    1652             :   namespace llvm {                                                             \
    1653             :   namespace yaml {                                                             \
    1654             :   template <> struct MappingTraits<Type> {                                     \
    1655             :     static void mapping(IO &IO, Type &Obj);                                    \
    1656             :   };                                                                           \
    1657             :   }                                                                            \
    1658             :   }
    1659             : 
    1660             : #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)                                    \
    1661             :   namespace llvm {                                                             \
    1662             :   namespace yaml {                                                             \
    1663             :   template <> struct ScalarEnumerationTraits<Type> {                           \
    1664             :     static void enumeration(IO &io, Type &Value);                              \
    1665             :   };                                                                           \
    1666             :   }                                                                            \
    1667             :   }
    1668             : 
    1669             : #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)                                  \
    1670             :   namespace llvm {                                                             \
    1671             :   namespace yaml {                                                             \
    1672             :   template <> struct ScalarBitSetTraits<Type> {                                \
    1673             :     static void bitset(IO &IO, Type &Options);                                 \
    1674             :   };                                                                           \
    1675             :   }                                                                            \
    1676             :   }
    1677             : 
    1678             : #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)                       \
    1679             :   namespace llvm {                                                             \
    1680             :   namespace yaml {                                                             \
    1681             :   template <> struct ScalarTraits<Type> {                                      \
    1682             :     static void output(const Type &Value, void *ctx, raw_ostream &Out);        \
    1683             :     static StringRef input(StringRef Scalar, void *ctxt, Type &Value);         \
    1684             :     static bool mustQuote(StringRef) { return MustQuote; }                     \
    1685             :   };                                                                           \
    1686             :   }                                                                            \
    1687             :   }
    1688             : 
    1689             : /// Utility for declaring that a std::vector of a particular type
    1690             : /// should be considered a YAML document list.
    1691             : #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                               \
    1692             :   namespace llvm {                                                             \
    1693             :   namespace yaml {                                                             \
    1694             :   template <unsigned N>                                                        \
    1695             :   struct DocumentListTraits<SmallVector<_type, N>>                             \
    1696             :       : public SequenceTraitsImpl<SmallVector<_type, N>, false> {};            \
    1697             :   template <>                                                                  \
    1698             :   struct DocumentListTraits<std::vector<_type>>                                \
    1699             :       : public SequenceTraitsImpl<std::vector<_type>, false> {};               \
    1700             :   }                                                                            \
    1701             :   }
    1702             : 
    1703             : /// Utility for declaring that std::map<std::string, _type> should be considered
    1704             : /// a YAML map.
    1705             : #define LLVM_YAML_IS_STRING_MAP(_type)                                         \
    1706             :   namespace llvm {                                                             \
    1707             :   namespace yaml {                                                             \
    1708             :   template <>                                                                  \
    1709             :   struct CustomMappingTraits<std::map<std::string, _type>>                     \
    1710             :       : public StdMapStringCustomMappingTraitsImpl<_type> {};                  \
    1711             :   }                                                                            \
    1712             :   }
    1713             : 
    1714             : #endif // LLVM_SUPPORT_YAMLTRAITS_H

Generated by: LCOV version 1.13