LCOV - code coverage report
Current view: top level - include/llvm/Support - YAMLTraits.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 2338 2564 91.2 %
Date: 2018-10-20 13:21:21 Functions: 1348 1943 69.4 %
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/StringExtras.h"
      16             : #include "llvm/ADT/StringMap.h"
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/ADT/Twine.h"
      19             : #include "llvm/Support/AlignOf.h"
      20             : #include "llvm/Support/Allocator.h"
      21             : #include "llvm/Support/Endian.h"
      22             : #include "llvm/Support/Regex.h"
      23             : #include "llvm/Support/SourceMgr.h"
      24             : #include "llvm/Support/YAMLParser.h"
      25             : #include "llvm/Support/raw_ostream.h"
      26             : #include <cassert>
      27             : #include <cctype>
      28             : #include <cstddef>
      29             : #include <cstdint>
      30             : #include <iterator>
      31             : #include <map>
      32             : #include <memory>
      33             : #include <new>
      34             : #include <string>
      35             : #include <system_error>
      36             : #include <type_traits>
      37             : #include <vector>
      38             : 
      39             : namespace llvm {
      40             : namespace yaml {
      41             : 
      42             : struct EmptyContext {};
      43             : 
      44             : /// This class should be specialized by any type that needs to be converted
      45             : /// to/from a YAML mapping.  For example:
      46             : ///
      47             : ///     struct MappingTraits<MyStruct> {
      48             : ///       static void mapping(IO &io, MyStruct &s) {
      49             : ///         io.mapRequired("name", s.name);
      50             : ///         io.mapRequired("size", s.size);
      51             : ///         io.mapOptional("age",  s.age);
      52             : ///       }
      53             : ///     };
      54             : template<class T>
      55             : struct MappingTraits {
      56             :   // Must provide:
      57             :   // static void mapping(IO &io, T &fields);
      58             :   // Optionally may provide:
      59             :   // static StringRef validate(IO &io, T &fields);
      60             :   //
      61             :   // The optional flow flag will cause generated YAML to use a flow mapping
      62             :   // (e.g. { a: 0, b: 1 }):
      63             :   // static const bool flow = true;
      64             : };
      65             : 
      66             : /// This class is similar to MappingTraits<T> but allows you to pass in
      67             : /// additional context for each map operation.  For example:
      68             : ///
      69             : ///     struct MappingContextTraits<MyStruct, MyContext> {
      70             : ///       static void mapping(IO &io, MyStruct &s, MyContext &c) {
      71             : ///         io.mapRequired("name", s.name);
      72             : ///         io.mapRequired("size", s.size);
      73             : ///         io.mapOptional("age",  s.age);
      74             : ///         ++c.TimesMapped;
      75             : ///       }
      76             : ///     };
      77             : template <class T, class Context> struct MappingContextTraits {
      78             :   // Must provide:
      79             :   // static void mapping(IO &io, T &fields, Context &Ctx);
      80             :   // Optionally may provide:
      81             :   // static StringRef validate(IO &io, T &fields, Context &Ctx);
      82             :   //
      83             :   // The optional flow flag will cause generated YAML to use a flow mapping
      84             :   // (e.g. { a: 0, b: 1 }):
      85             :   // static const bool flow = true;
      86             : };
      87             : 
      88             : /// This class should be specialized by any integral type that converts
      89             : /// to/from a YAML scalar where there is a one-to-one mapping between
      90             : /// in-memory values and a string in YAML.  For example:
      91             : ///
      92             : ///     struct ScalarEnumerationTraits<Colors> {
      93             : ///         static void enumeration(IO &io, Colors &value) {
      94             : ///           io.enumCase(value, "red",   cRed);
      95             : ///           io.enumCase(value, "blue",  cBlue);
      96             : ///           io.enumCase(value, "green", cGreen);
      97             : ///         }
      98             : ///       };
      99             : template<typename T>
     100             : struct ScalarEnumerationTraits {
     101             :   // Must provide:
     102             :   // static void enumeration(IO &io, T &value);
     103             : };
     104             : 
     105             : /// This class should be specialized by any integer type that is a union
     106             : /// of bit values and the YAML representation is a flow sequence of
     107             : /// strings.  For example:
     108             : ///
     109             : ///      struct ScalarBitSetTraits<MyFlags> {
     110             : ///        static void bitset(IO &io, MyFlags &value) {
     111             : ///          io.bitSetCase(value, "big",   flagBig);
     112             : ///          io.bitSetCase(value, "flat",  flagFlat);
     113             : ///          io.bitSetCase(value, "round", flagRound);
     114             : ///        }
     115             : ///      };
     116             : template<typename T>
     117             : struct ScalarBitSetTraits {
     118             :   // Must provide:
     119             :   // static void bitset(IO &io, T &value);
     120             : };
     121             : 
     122             : /// Describe which type of quotes should be used when quoting is necessary.
     123             : /// Some non-printable characters need to be double-quoted, while some others
     124             : /// are fine with simple-quoting, and some don't need any quoting.
     125             : enum class QuotingType { None, Single, Double };
     126             : 
     127             : /// This class should be specialized by type that requires custom conversion
     128             : /// to/from a yaml scalar.  For example:
     129             : ///
     130             : ///    template<>
     131             : ///    struct ScalarTraits<MyType> {
     132             : ///      static void output(const MyType &val, void*, llvm::raw_ostream &out) {
     133             : ///        // stream out custom formatting
     134             : ///        out << llvm::format("%x", val);
     135             : ///      }
     136             : ///      static StringRef input(StringRef scalar, void*, MyType &value) {
     137             : ///        // parse scalar and set `value`
     138             : ///        // return empty string on success, or error string
     139             : ///        return StringRef();
     140             : ///      }
     141             : ///      static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
     142             : ///    };
     143             : template<typename T>
     144             : struct ScalarTraits {
     145             :   // Must provide:
     146             :   //
     147             :   // Function to write the value as a string:
     148             :   //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
     149             :   //
     150             :   // Function to convert a string to a value.  Returns the empty
     151             :   // StringRef on success or an error string if string is malformed:
     152             :   //static StringRef input(StringRef scalar, void *ctxt, T &value);
     153             :   //
     154             :   // Function to determine if the value should be quoted.
     155             :   //static QuotingType mustQuote(StringRef);
     156             : };
     157             : 
     158             : /// This class should be specialized by type that requires custom conversion
     159             : /// to/from a YAML literal block scalar. For example:
     160             : ///
     161             : ///    template <>
     162             : ///    struct BlockScalarTraits<MyType> {
     163             : ///      static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
     164             : ///      {
     165             : ///        // stream out custom formatting
     166             : ///        Out << Val;
     167             : ///      }
     168             : ///      static StringRef input(StringRef Scalar, void*, MyType &Value) {
     169             : ///        // parse scalar and set `value`
     170             : ///        // return empty string on success, or error string
     171             : ///        return StringRef();
     172             : ///      }
     173             : ///    };
     174             : template <typename T>
     175             : struct BlockScalarTraits {
     176             :   // Must provide:
     177             :   //
     178             :   // Function to write the value as a string:
     179             :   // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
     180             :   //
     181             :   // Function to convert a string to a value.  Returns the empty
     182             :   // StringRef on success or an error string if string is malformed:
     183             :   // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
     184             : };
     185             : 
     186             : /// This class should be specialized by any type that needs to be converted
     187             : /// to/from a YAML sequence.  For example:
     188             : ///
     189             : ///    template<>
     190             : ///    struct SequenceTraits<MyContainer> {
     191             : ///      static size_t size(IO &io, MyContainer &seq) {
     192             : ///        return seq.size();
     193             : ///      }
     194             : ///      static MyType& element(IO &, MyContainer &seq, size_t index) {
     195             : ///        if ( index >= seq.size() )
     196             : ///          seq.resize(index+1);
     197             : ///        return seq[index];
     198             : ///      }
     199             : ///    };
     200             : template<typename T, typename EnableIf = void>
     201             : struct SequenceTraits {
     202             :   // Must provide:
     203             :   // static size_t size(IO &io, T &seq);
     204             :   // static T::value_type& element(IO &io, T &seq, size_t index);
     205             :   //
     206             :   // The following is option and will cause generated YAML to use
     207             :   // a flow sequence (e.g. [a,b,c]).
     208             :   // static const bool flow = true;
     209             : };
     210             : 
     211             : /// This class should be specialized by any type for which vectors of that
     212             : /// type need to be converted to/from a YAML sequence.
     213             : template<typename T, typename EnableIf = void>
     214             : struct SequenceElementTraits {
     215             :   // Must provide:
     216             :   // static const bool flow;
     217             : };
     218             : 
     219             : /// This class should be specialized by any type that needs to be converted
     220             : /// to/from a list of YAML documents.
     221             : template<typename T>
     222             : struct DocumentListTraits {
     223             :   // Must provide:
     224             :   // static size_t size(IO &io, T &seq);
     225             :   // static T::value_type& element(IO &io, T &seq, size_t index);
     226             : };
     227             : 
     228             : /// This class should be specialized by any type that needs to be converted
     229             : /// to/from a YAML mapping in the case where the names of the keys are not known
     230             : /// in advance, e.g. a string map.
     231             : template <typename T>
     232             : struct CustomMappingTraits {
     233             :   // static void inputOne(IO &io, StringRef key, T &elem);
     234             :   // static void output(IO &io, T &elem);
     235             : };
     236             : 
     237             : // Only used for better diagnostics of missing traits
     238             : template <typename T>
     239             : struct MissingTrait;
     240             : 
     241             : // Test if ScalarEnumerationTraits<T> is defined on type T.
     242             : template <class T>
     243             : struct has_ScalarEnumerationTraits
     244             : {
     245             :   using Signature_enumeration = void (*)(class IO&, T&);
     246             : 
     247             :   template <typename U>
     248             :   static char test(SameType<Signature_enumeration, &U::enumeration>*);
     249             : 
     250             :   template <typename U>
     251             :   static double test(...);
     252             : 
     253             :   static bool const value =
     254             :     (sizeof(test<ScalarEnumerationTraits<T>>(nullptr)) == 1);
     255             : };
     256             : 
     257             : // Test if ScalarBitSetTraits<T> is defined on type T.
     258             : template <class T>
     259             : struct has_ScalarBitSetTraits
     260             : {
     261             :   using Signature_bitset = void (*)(class IO&, T&);
     262             : 
     263             :   template <typename U>
     264             :   static char test(SameType<Signature_bitset, &U::bitset>*);
     265             : 
     266             :   template <typename U>
     267             :   static double test(...);
     268             : 
     269             :   static bool const value = (sizeof(test<ScalarBitSetTraits<T>>(nullptr)) == 1);
     270             : };
     271             : 
     272             : // Test if ScalarTraits<T> is defined on type T.
     273             : template <class T>
     274             : struct has_ScalarTraits
     275             : {
     276             :   using Signature_input = StringRef (*)(StringRef, void*, T&);
     277             :   using Signature_output = void (*)(const T&, void*, raw_ostream&);
     278             :   using Signature_mustQuote = QuotingType (*)(StringRef);
     279             : 
     280             :   template <typename U>
     281             :   static char test(SameType<Signature_input, &U::input> *,
     282             :                    SameType<Signature_output, &U::output> *,
     283             :                    SameType<Signature_mustQuote, &U::mustQuote> *);
     284             : 
     285             :   template <typename U>
     286             :   static double test(...);
     287             : 
     288             :   static bool const value =
     289             :       (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
     290             : };
     291             : 
     292             : // Test if BlockScalarTraits<T> is defined on type T.
     293             : template <class T>
     294             : struct has_BlockScalarTraits
     295             : {
     296             :   using Signature_input = StringRef (*)(StringRef, void *, T &);
     297             :   using Signature_output = void (*)(const T &, void *, raw_ostream &);
     298             : 
     299             :   template <typename U>
     300             :   static char test(SameType<Signature_input, &U::input> *,
     301             :                    SameType<Signature_output, &U::output> *);
     302             : 
     303             :   template <typename U>
     304             :   static double test(...);
     305             : 
     306             :   static bool const value =
     307             :       (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
     308             : };
     309             : 
     310             : // Test if MappingContextTraits<T> is defined on type T.
     311             : template <class T, class Context> struct has_MappingTraits {
     312             :   using Signature_mapping = void (*)(class IO &, T &, Context &);
     313             : 
     314             :   template <typename U>
     315             :   static char test(SameType<Signature_mapping, &U::mapping>*);
     316             : 
     317             :   template <typename U>
     318             :   static double test(...);
     319             : 
     320             :   static bool const value =
     321             :       (sizeof(test<MappingContextTraits<T, Context>>(nullptr)) == 1);
     322             : };
     323             : 
     324             : // Test if MappingTraits<T> is defined on type T.
     325             : template <class T> struct has_MappingTraits<T, EmptyContext> {
     326             :   using Signature_mapping = void (*)(class IO &, T &);
     327             : 
     328             :   template <typename U>
     329             :   static char test(SameType<Signature_mapping, &U::mapping> *);
     330             : 
     331             :   template <typename U> static double test(...);
     332             : 
     333             :   static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
     334             : };
     335             : 
     336             : // Test if MappingContextTraits<T>::validate() is defined on type T.
     337             : template <class T, class Context> struct has_MappingValidateTraits {
     338             :   using Signature_validate = StringRef (*)(class IO &, T &, Context &);
     339             : 
     340             :   template <typename U>
     341             :   static char test(SameType<Signature_validate, &U::validate>*);
     342             : 
     343             :   template <typename U>
     344             :   static double test(...);
     345             : 
     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             :   static bool const value = (sizeof(test<MappingTraits<T>>(nullptr)) == 1);
     360             : };
     361             : 
     362             : // Test if SequenceTraits<T> is defined on type T.
     363             : template <class T>
     364             : struct has_SequenceMethodTraits
     365             : {
     366             :   using Signature_size = size_t (*)(class IO&, T&);
     367             : 
     368             :   template <typename U>
     369             :   static char test(SameType<Signature_size, &U::size>*);
     370             : 
     371             :   template <typename U>
     372             :   static double test(...);
     373             : 
     374             :   static bool const value =  (sizeof(test<SequenceTraits<T>>(nullptr)) == 1);
     375             : };
     376             : 
     377             : // Test if CustomMappingTraits<T> is defined on type T.
     378             : template <class T>
     379             : struct has_CustomMappingTraits
     380             : {
     381             :   using Signature_input = void (*)(IO &io, StringRef key, T &v);
     382             : 
     383             :   template <typename U>
     384             :   static char test(SameType<Signature_input, &U::inputOne>*);
     385             : 
     386             :   template <typename U>
     387             :   static double test(...);
     388             : 
     389             :   static bool const value =
     390             :       (sizeof(test<CustomMappingTraits<T>>(nullptr)) == 1);
     391             : };
     392             : 
     393             : // has_FlowTraits<int> will cause an error with some compilers because
     394             : // it subclasses int.  Using this wrapper only instantiates the
     395             : // real has_FlowTraits only if the template type is a class.
     396             : template <typename T, bool Enabled = std::is_class<T>::value>
     397             : class has_FlowTraits
     398             : {
     399             : public:
     400             :    static const bool value = false;
     401             : };
     402             : 
     403             : // Some older gcc compilers don't support straight forward tests
     404             : // for members, so test for ambiguity cause by the base and derived
     405             : // classes both defining the member.
     406             : template <class T>
     407             : struct has_FlowTraits<T, true>
     408             : {
     409             :   struct Fallback { bool flow; };
     410             :   struct Derived : T, Fallback { };
     411             : 
     412             :   template<typename C>
     413             :   static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
     414             : 
     415             :   template<typename C>
     416             :   static char (&f(...))[2];
     417             : 
     418             :   static bool const value = sizeof(f<Derived>(nullptr)) == 2;
     419             : };
     420             : 
     421             : // Test if SequenceTraits<T> is defined on type T
     422             : template<typename T>
     423             : struct has_SequenceTraits : public std::integral_constant<bool,
     424             :                                       has_SequenceMethodTraits<T>::value > { };
     425             : 
     426             : // Test if DocumentListTraits<T> is defined on type T
     427             : template <class T>
     428             : struct has_DocumentListTraits
     429             : {
     430             :   using Signature_size = size_t (*)(class IO &, T &);
     431             : 
     432             :   template <typename U>
     433             :   static char test(SameType<Signature_size, &U::size>*);
     434             : 
     435             :   template <typename U>
     436             :   static double test(...);
     437             : 
     438             :   static bool const value = (sizeof(test<DocumentListTraits<T>>(nullptr))==1);
     439             : };
     440             : 
     441       62233 : inline bool isNumeric(StringRef S) {
     442             :   const static auto skipDigits = [](StringRef Input) {
     443             :     return Input.drop_front(
     444             :         std::min(Input.find_first_not_of("0123456789"), Input.size()));
     445             :   };
     446             : 
     447             :   // Make S.front() and S.drop_front().front() (if S.front() is [+-]) calls
     448             :   // safe.
     449       62233 :   if (S.empty() || S.equals("+") || S.equals("-"))
     450             :     return false;
     451             : 
     452             :   if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
     453             :     return true;
     454             : 
     455             :   // Infinity and decimal numbers can be prefixed with sign.
     456      124527 :   StringRef Tail = (S.front() == '-' || S.front() == '+') ? S.drop_front() : S;
     457             : 
     458             :   // Check for infinity first, because checking for hex and oct numbers is more
     459             :   // expensive.
     460             :   if (Tail.equals(".inf") || Tail.equals(".Inf") || Tail.equals(".INF"))
     461             :     return true;
     462             : 
     463             :   // Section 10.3.2 Tag Resolution
     464             :   // YAML 1.2 Specification prohibits Base 8 and Base 16 numbers prefixed with
     465             :   // [-+], so S should be used instead of Tail.
     466             :   if (S.startswith("0o"))
     467           4 :     return S.size() > 2 &&
     468           6 :            S.drop_front(2).find_first_not_of("01234567") == StringRef::npos;
     469             : 
     470             :   if (S.startswith("0x"))
     471           7 :     return S.size() > 2 && S.drop_front(2).find_first_not_of(
     472             :                                "0123456789abcdefABCDEF") == StringRef::npos;
     473             : 
     474             :   // Parse float: [-+]? (\. [0-9]+ | [0-9]+ (\. [0-9]* )?) ([eE] [-+]? [0-9]+)?
     475       62217 :   S = Tail;
     476             : 
     477             :   // Handle cases when the number starts with '.' and hence needs at least one
     478             :   // digit after dot (as opposed by number which has digits before the dot), but
     479             :   // doesn't have one.
     480             :   if (S.startswith(".") &&
     481         994 :       (S.equals(".") ||
     482        1988 :        (S.size() > 1 && std::strchr("0123456789", S[1]) == nullptr)))
     483             :     return false;
     484             : 
     485             :   if (S.startswith("E") || S.startswith("e"))
     486             :     return false;
     487             : 
     488             :   enum ParseState {
     489             :     Default,
     490             :     FoundDot,
     491             :     FoundExponent,
     492             :   };
     493             :   ParseState State = Default;
     494             : 
     495       60263 :   S = skipDigits(S);
     496             : 
     497             :   // Accept decimal integer.
     498       60263 :   if (S.empty())
     499             :     return true;
     500             : 
     501      119364 :   if (S.front() == '.') {
     502             :     State = FoundDot;
     503          18 :     S = S.drop_front();
     504       59664 :   } else if (S.front() == 'e' || S.front() == 'E') {
     505             :     State = FoundExponent;
     506          12 :     S = S.drop_front();
     507             :   } else {
     508             :     return false;
     509             :   }
     510             : 
     511             :   if (State == FoundDot) {
     512          18 :     S = skipDigits(S);
     513          18 :     if (S.empty())
     514             :       return true;
     515             : 
     516          20 :     if (S.front() == 'e' || S.front() == 'E') {
     517             :       State = FoundExponent;
     518           9 :       S = S.drop_front();
     519             :     } else {
     520             :       return false;
     521             :     }
     522             :   }
     523             : 
     524             :   assert(State == FoundExponent && "Should have found exponent at this point.");
     525          21 :   if (S.empty())
     526             :     return false;
     527             : 
     528          40 :   if (S.front() == '+' || S.front() == '-') {
     529           6 :     S = S.drop_front();
     530           6 :     if (S.empty())
     531             :       return false;
     532             :   }
     533             : 
     534          19 :   return skipDigits(S).empty();
     535             : }
     536             : 
     537       62200 : inline bool isNull(StringRef S) {
     538             :   return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
     539       62200 :          S.equals("~");
     540             : }
     541             : 
     542       62188 : inline bool isBool(StringRef S) {
     543             :   return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
     544       62188 :          S.equals("false") || S.equals("False") || S.equals("FALSE");
     545             : }
     546             : 
     547             : // 5.1. Character Set
     548             : // The allowed character range explicitly excludes the C0 control block #x0-#x1F
     549             : // (except for TAB #x9, LF #xA, and CR #xD which are allowed), DEL #x7F, the C1
     550             : // control block #x80-#x9F (except for NEL #x85 which is allowed), the surrogate
     551             : // block #xD800-#xDFFF, #xFFFE, and #xFFFF.
     552      166542 : inline QuotingType needsQuotes(StringRef S) {
     553      166542 :   if (S.empty())
     554             :     return QuotingType::Single;
     555      125758 :   if (isspace(S.front()) || isspace(S.back()))
     556             :     return QuotingType::Single;
     557       62195 :   if (isNull(S))
     558             :     return QuotingType::Single;
     559       62188 :   if (isBool(S))
     560             :     return QuotingType::Single;
     561       62182 :   if (isNumeric(S))
     562             :     return QuotingType::Single;
     563             : 
     564             :   // 7.3.3 Plain Style
     565             :   // Plain scalars must not begin with most indicators, as this would cause
     566             :   // ambiguity with other YAML constructs.
     567             :   static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
     568       61600 :   if (S.find_first_of(Indicators) == 0)
     569             :     return QuotingType::Single;
     570             : 
     571             :   QuotingType MaxQuotingNeeded = QuotingType::None;
     572      821937 :   for (unsigned char C : S) {
     573             :     // Alphanum is safe.
     574             :     if (isAlnum(C))
     575             :       continue;
     576             : 
     577       91093 :     switch (C) {
     578             :     // Safe scalar characters.
     579             :     case '_':
     580             :     case '-':
     581             :     case '^':
     582             :     case '.':
     583             :     case ',':
     584             :     case ' ':
     585             :     // TAB (0x9) is allowed in unquoted strings.
     586             :     case 0x9:
     587             :       continue;
     588             :     // LF(0xA) and CR(0xD) may delimit values and so require at least single
     589             :     // quotes.
     590           2 :     case 0xA:
     591             :     case 0xD:
     592             :       MaxQuotingNeeded = QuotingType::Single;
     593           2 :       continue;
     594             :     // DEL (0x7F) are excluded from the allowed character range.
     595             :     case 0x7F:
     596             :       return QuotingType::Double;
     597             :     // Forward slash is allowed to be unquoted, but we quote it anyway.  We have
     598             :     // many tests that use FileCheck against YAML output, and this output often
     599             :     // contains paths.  If we quote backslashes but not forward slashes then
     600             :     // paths will come out either quoted or unquoted depending on which platform
     601             :     // the test is run on, making FileCheck comparisons difficult.
     602       18684 :     case '/':
     603             :     default: {
     604             :       // C0 control block (0x0 - 0x1F) is excluded from the allowed character
     605             :       // range.
     606       18684 :       if (C <= 0x1F)
     607             :         return QuotingType::Double;
     608             : 
     609             :       // Always double quote UTF-8.
     610       18680 :       if ((C & 0x80) != 0)
     611             :         return QuotingType::Double;
     612             : 
     613             :       // The character is not safe, at least simple quoting needed.
     614             :       MaxQuotingNeeded = QuotingType::Single;
     615             :     }
     616             :     }
     617             :   }
     618             : 
     619             :   return MaxQuotingNeeded;
     620             : }
     621             : 
     622             : template <typename T, typename Context>
     623             : struct missingTraits
     624             :     : public std::integral_constant<bool,
     625             :                                     !has_ScalarEnumerationTraits<T>::value &&
     626             :                                         !has_ScalarBitSetTraits<T>::value &&
     627             :                                         !has_ScalarTraits<T>::value &&
     628             :                                         !has_BlockScalarTraits<T>::value &&
     629             :                                         !has_MappingTraits<T, Context>::value &&
     630             :                                         !has_SequenceTraits<T>::value &&
     631             :                                         !has_CustomMappingTraits<T>::value &&
     632             :                                         !has_DocumentListTraits<T>::value> {};
     633             : 
     634             : template <typename T, typename Context>
     635             : struct validatedMappingTraits
     636             :     : public std::integral_constant<
     637             :           bool, has_MappingTraits<T, Context>::value &&
     638             :                     has_MappingValidateTraits<T, Context>::value> {};
     639             : 
     640             : template <typename T, typename Context>
     641             : struct unvalidatedMappingTraits
     642             :     : public std::integral_constant<
     643             :           bool, has_MappingTraits<T, Context>::value &&
     644             :                     !has_MappingValidateTraits<T, Context>::value> {};
     645             : 
     646             : // Base class for Input and Output.
     647       11187 : class IO {
     648             : public:
     649             :   IO(void *Ctxt = nullptr);
     650             :   virtual ~IO();
     651             : 
     652             :   virtual bool outputting() = 0;
     653             : 
     654             :   virtual unsigned beginSequence() = 0;
     655             :   virtual bool preflightElement(unsigned, void *&) = 0;
     656             :   virtual void postflightElement(void*) = 0;
     657             :   virtual void endSequence() = 0;
     658             :   virtual bool canElideEmptySequence() = 0;
     659             : 
     660             :   virtual unsigned beginFlowSequence() = 0;
     661             :   virtual bool preflightFlowElement(unsigned, void *&) = 0;
     662             :   virtual void postflightFlowElement(void*) = 0;
     663             :   virtual void endFlowSequence() = 0;
     664             : 
     665             :   virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
     666             :   virtual void beginMapping() = 0;
     667             :   virtual void endMapping() = 0;
     668             :   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
     669             :   virtual void postflightKey(void*) = 0;
     670             :   virtual std::vector<StringRef> keys() = 0;
     671             : 
     672             :   virtual void beginFlowMapping() = 0;
     673             :   virtual void endFlowMapping() = 0;
     674             : 
     675             :   virtual void beginEnumScalar() = 0;
     676             :   virtual bool matchEnumScalar(const char*, bool) = 0;
     677             :   virtual bool matchEnumFallback() = 0;
     678             :   virtual void endEnumScalar() = 0;
     679             : 
     680             :   virtual bool beginBitSetScalar(bool &) = 0;
     681             :   virtual bool bitSetMatch(const char*, bool) = 0;
     682             :   virtual void endBitSetScalar() = 0;
     683             : 
     684             :   virtual void scalarString(StringRef &, QuotingType) = 0;
     685             :   virtual void blockScalarString(StringRef &) = 0;
     686             : 
     687             :   virtual void setError(const Twine &) = 0;
     688             : 
     689             :   template <typename T>
     690     2049989 :   void enumCase(T &Val, const char* Str, const T ConstVal) {
     691     4053608 :     if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
     692       16775 :       Val = ConstVal;
     693             :     }
     694     2049989 :   }
     695      245968 : 
     696      472626 :   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
     697        1267 :   template <typename T>
     698      131630 :   void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
     699      410797 :     if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
     700      197675 :       Val = ConstVal;
     701      379476 :     }
     702      132899 :   }
     703        2577 : 
     704      201293 :   template <typename FBT, typename T>
     705       93466 :   void enumFallback(T &Val) {
     706      178704 :     if (matchEnumFallback()) {
     707        3566 :       EmptyContext Context;
     708         132 :       // FIXME: Force integral conversion to allow strong typedefs to convert.
     709       93543 :       FBT Res = static_cast<typename FBT::BaseType>(Val);
     710      113410 :       yamlize(*this, Res, true, Context);
     711      225604 :       Val = static_cast<T>(static_cast<typename FBT::BaseType>(Res));
     712        1100 :     }
     713        1938 :   }
     714      116700 : 
     715        6399 :   template <typename T>
     716       12781 :   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
     717        2248 :     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
     718        1793 :       Val = static_cast<T>(Val | ConstVal);
     719        9389 :     }
     720      209512 :   }
     721      411852 : 
     722        4170 :   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
     723       13964 :   template <typename T>
     724      222956 :   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
     725       47038 :     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
     726       93943 :       Val = static_cast<T>(Val | ConstVal);
     727       15720 :     }
     728        7861 :   }
     729       55330 : 
     730       51256 :   template <typename T>
     731       89905 :   void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
     732        3260 :     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
     733          86 :       Val = Val | ConstVal;
     734       45283 :   }
     735        7291 : 
     736       14520 :   template <typename T>
     737        6798 :   void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
     738       12560 :                         uint32_t Mask) {
     739       28104 :     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
     740        1774 :       Val = Val | ConstVal;
     741        1816 :   }
     742       12585 : 
     743         972 :   void *getContext();
     744        1350 :   void setContext(void *);
     745     1084324 : 
     746     2168737 :   template <typename T> void mapRequired(const char *Key, T &Val) {
     747        8857 :     EmptyContext Ctx;
     748       49888 :     this->processKey(Key, Val, true, Ctx);
     749     1124744 :   }
     750        3635 : 
     751        2149 :   template <typename T, typename Context>
     752       38648 :   void mapRequired(const char *Key, T &Val, Context &Ctx) {
     753        1663 :     this->processKey(Key, Val, true, Ctx);
     754        2160 :   }
     755        1797 : 
     756         727 :   template <typename T> void mapOptional(const char *Key, T &Val) {
     757        2297 :     EmptyContext Ctx;
     758        3932 :     mapOptionalWithContext(Key, Val, Ctx);
     759        1629 :   }
     760        1062 : 
     761         436 :   template <typename T>
     762        1897 :   void mapOptional(const char *Key, T &Val, const T &Default) {
     763       52329 :     EmptyContext Ctx;
     764         876 :     mapOptionalWithContext(Key, Val, Default, Ctx);
     765         756 :   }
     766          71 : 
     767        1149 :   template <typename T, typename Context>
     768       80323 :   typename std::enable_if<has_SequenceTraits<T>::value, void>::type
     769       65946 :   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
     770          21 :     // omit key/value instead of outputting empty sequence
     771       16128 :     if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
     772       74009 :       return;
     773        7382 :     this->processKey(Key, Val, false, Ctx);
     774         525 :   }
     775       15395 : 
     776       19984 :   template <typename T, typename Context>
     777       40989 :   void mapOptionalWithContext(const char *Key, Optional<T> &Val, Context &Ctx) {
     778       11252 :     this->processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false,
     779        7738 :                                 Ctx);
     780       22631 :   }
     781       13426 : 
     782       16832 :   template <typename T, typename Context>
     783        5981 :   typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
     784        1327 :   mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
     785       13965 :     this->processKey(Key, Val, false, Ctx);
     786       19305 :   }
     787       33117 : 
     788       10864 :   template <typename T, typename Context>
     789        8978 :   void mapOptionalWithContext(const char *Key, T &Val, const T &Default,
     790       29949 :                               Context &Ctx) {
     791        9818 :     this->processKeyWithDefault(Key, Val, Default, false, Ctx);
     792       11921 :   }
     793        7043 : 
     794        2238 : private:
     795        5645 :   template <typename T, typename Context>
     796        2463 :   void processKeyWithDefault(const char *Key, Optional<T> &Val,
     797        3270 :                              const Optional<T> &DefaultValue, bool Required,
     798        5240 :                              Context &Ctx) {
     799        2238 :     assert(DefaultValue.hasValue() == false &&
     800       12826 :            "Optional<T> shouldn't have a value!");
     801        4701 :     void *SaveInfo;
     802        1185 :     bool UseDefault = true;
     803        6868 :     const bool sameAsDefault = outputting() && !Val.hasValue();
     804        1365 :     if (!outputting() && !Val.hasValue())
     805        5272 :       Val = T();
     806      146145 :     if (Val.hasValue() &&
     807         294 :         this->preflightKey(Key, Required, sameAsDefault, UseDefault,
     808        1145 :                            SaveInfo)) {
     809        1977 :       yamlize(*this, Val.getValue(), Required, Ctx);
     810         558 :       this->postflightKey(SaveInfo);
     811       25178 :     } else {
     812         679 :       if (UseDefault)
     813       17152 :         Val = DefaultValue;
     814          27 :     }
     815        1671 :   }
     816        3779 : 
     817       16225 :   template <typename T, typename Context>
     818       11632 :   void processKeyWithDefault(const char *Key, T &Val, const T &DefaultValue,
     819       10676 :                              bool Required, Context &Ctx) {
     820        4681 :     void *SaveInfo;
     821       15791 :     bool UseDefault;
     822        9730 :     const bool sameAsDefault = outputting() && Val == DefaultValue;
     823       67209 :     if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
     824        4506 :                                                                   SaveInfo) ) {
     825        3949 :       yamlize(*this, Val, Required, Ctx);
     826        7547 :       this->postflightKey(SaveInfo);
     827       13884 :     }
     828       22260 :     else {
     829        2665 :       if ( UseDefault )
     830       11276 :         Val = DefaultValue;
     831       10563 :     }
     832        4442 :   }
     833        2264 : 
     834             :   template <typename T, typename Context>
     835       21484 :   void processKey(const char *Key, T &Val, bool Required, Context &Ctx) {
     836        1113 :     void *SaveInfo;
     837        9823 :     bool UseDefault;
     838       27922 :     if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
     839       24555 :       yamlize(*this, Val, Required, Ctx);
     840       25894 :       this->postflightKey(SaveInfo);
     841       27895 :     }
     842       23305 :   }
     843        9525 : 
     844        8285 : private:
     845        2315 :   void *Ctxt;
     846        5815 : };
     847       17219 : 
     848        2455 : namespace detail {
     849       11272 : 
     850      197606 : template <typename T, typename Context>
     851        7406 : void doMapping(IO &io, T &Val, Context &Ctx) {
     852        2469 :   MappingContextTraits<T, Context>::mapping(io, Val, Ctx);
     853       17179 : }
     854      187462 : 
     855      187508 : template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
     856       16197 :   MappingTraits<T>::mapping(io, Val);
     857       47937 : }
     858       49843 : 
     859        4106 : } // end namespace detail
     860       15854 : 
     861      156854 : template <typename T>
     862       13268 : typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
     863        5854 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     864      198838 :   io.beginEnumScalar();
     865        4357 :   ScalarEnumerationTraits<T>::enumeration(io, Val);
     866       11099 :   io.endEnumScalar();
     867        7371 : }
     868        2744 : 
     869       11858 : template <typename T>
     870        5525 : typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
     871        5905 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     872       14114 :   bool DoClear;
     873      297902 :   if ( io.beginBitSetScalar(DoClear) ) {
     874       16703 :     if ( DoClear )
     875        6839 :       Val = static_cast<T>(0);
     876       10676 :     ScalarBitSetTraits<T>::bitset(io, Val);
     877      293399 :     io.endBitSetScalar();
     878      295308 :   }
     879        8882 : }
     880      248238 : 
     881      229138 : template <typename T>
     882        5470 : typename std::enable_if<has_ScalarTraits<T>::value, void>::type
     883        6863 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     884       87630 :   if ( io.outputting() ) {
     885       71245 :     std::string Storage;
     886        4673 :     raw_string_ostream Buffer(Storage);
     887      302522 :     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
     888       10626 :     StringRef Str = Buffer.str();
     889        1568 :     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
     890        1618 :   }
     891       13373 :   else {
     892        4251 :     StringRef Str;
     893        8919 :     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
     894       24936 :     StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
     895       75827 :     if ( !Result.empty() ) {
     896        3967 :       io.setError(Twine(Result));
     897        7902 :     }
     898       15161 :   }
     899       75052 : }
     900       72333 : 
     901         562 : template <typename T>
     902       10144 : typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
     903       73641 : yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
     904        9981 :   if (YamlIO.outputting()) {
     905        8217 :     std::string Storage;
     906       78163 :     raw_string_ostream Buffer(Storage);
     907       81560 :     BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
     908       69814 :     StringRef Str = Buffer.str();
     909       65798 :     YamlIO.blockScalarString(Str);
     910       78888 :   } else {
     911       52197 :     StringRef Str;
     912         884 :     YamlIO.blockScalarString(Str);
     913        6889 :     StringRef Result =
     914       41191 :         BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
     915       53474 :     if (!Result.empty())
     916        7158 :       YamlIO.setError(Twine(Result));
     917       67434 :   }
     918       26403 : }
     919       19815 : 
     920       24122 : template <typename T, typename Context>
     921       27686 : typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
     922       26673 : yamlize(IO &io, T &Val, bool, Context &Ctx) {
     923        5096 :   if (has_FlowTraits<MappingTraits<T>>::value)
     924       36349 :     io.beginFlowMapping();
     925       23474 :   else
     926        4569 :     io.beginMapping();
     927        9926 :   if (io.outputting()) {
     928        3363 :     StringRef Err = MappingTraits<T>::validate(io, Val);
     929       52225 :     if (!Err.empty()) {
     930       79428 :       errs() << Err << "\n";
     931       10393 :       assert(Err.empty() && "invalid struct trying to be written as yaml");
     932       42496 :     }
     933       63020 :   }
     934       34505 :   detail::doMapping(io, Val, Ctx);
     935       54179 :   if (!io.outputting()) {
     936       15049 :     StringRef Err = MappingTraits<T>::validate(io, Val);
     937       23363 :     if (!Err.empty())
     938       16699 :       io.setError(Err);
     939       27967 :   }
     940       39488 :   if (has_FlowTraits<MappingTraits<T>>::value)
     941       17246 :     io.endFlowMapping();
     942        2190 :   else
     943        5452 :     io.endMapping();
     944       25258 : }
     945       58694 : 
     946         819 : template <typename T, typename Context>
     947        7354 : typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
     948      100620 : yamlize(IO &io, T &Val, bool, Context &Ctx) {
     949        6350 :   if (has_FlowTraits<MappingTraits<T>>::value) {
     950         354 :     io.beginFlowMapping();
     951       66768 :     detail::doMapping(io, Val, Ctx);
     952       39372 :     io.endFlowMapping();
     953       35977 :   } else {
     954       26365 :     io.beginMapping();
     955      119532 :     detail::doMapping(io, Val, Ctx);
     956       32078 :     io.endMapping();
     957        5512 :   }
     958       18176 : }
     959       49654 : 
     960       38876 : template <typename T>
     961        5299 : typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
     962       46842 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     963      122968 :   if ( io.outputting() ) {
     964        2715 :     io.beginMapping();
     965        1566 :     CustomMappingTraits<T>::output(io, Val);
     966       25176 :     io.endMapping();
     967      124499 :   } else {
     968      116970 :     io.beginMapping();
     969       39993 :     for (StringRef key : io.keys())
     970      106292 :       CustomMappingTraits<T>::inputOne(io, key, Val);
     971       89905 :     io.endMapping();
     972        7306 :   }
     973        7275 : }
     974       41849 : 
     975       34191 : template <typename T>
     976        4006 : typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
     977      111850 : yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
     978        6413 :   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
     979        3112 : }
     980        2361 : 
     981       17544 : template <typename T, typename Context>
     982       13402 : typename std::enable_if<has_SequenceTraits<T>::value, void>::type
     983       11693 : yamlize(IO &io, T &Seq, bool, Context &Ctx) {
     984       23556 :   if ( has_FlowTraits< SequenceTraits<T>>::value ) {
     985        7340 :     unsigned incnt = io.beginFlowSequence();
     986        6778 :     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
     987      105621 :     for(unsigned i=0; i < count; ++i) {
     988       62668 :       void *SaveInfo;
     989        1822 :       if ( io.preflightFlowElement(i, SaveInfo) ) {
     990      104792 :         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
     991      155012 :         io.postflightFlowElement(SaveInfo);
     992      129153 :       }
     993       33920 :     }
     994      107874 :     io.endFlowSequence();
     995       63791 :   }
     996        3181 :   else {
     997       49931 :     unsigned incnt = io.beginSequence();
     998       60388 :     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
     999       18902 :     for(unsigned i=0; i < count; ++i) {
    1000       44137 :       void *SaveInfo;
    1001       36375 :       if ( io.preflightElement(i, SaveInfo) ) {
    1002       12776 :         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true, Ctx);
    1003       28923 :         io.postflightElement(SaveInfo);
    1004        3494 :       }
    1005        2386 :     }
    1006       15903 :     io.endSequence();
    1007       22679 :   }
    1008       14330 : }
    1009       12523 : 
    1010        9805 : template<>
    1011        7251 : struct ScalarTraits<bool> {
    1012        2833 :   static void output(const bool &, void* , raw_ostream &);
    1013       47246 :   static StringRef input(StringRef, void *, bool &);
    1014       14913 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1015       17258 : };
    1016        8651 : 
    1017       11972 : template<>
    1018        7557 : struct ScalarTraits<StringRef> {
    1019       10510 :   static void output(const StringRef &, void *, raw_ostream &);
    1020        2016 :   static StringRef input(StringRef, void *, StringRef &);
    1021         517 :   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
    1022        8773 : };
    1023       18867 : 
    1024       10369 : template<>
    1025        2555 : struct ScalarTraits<std::string> {
    1026       11257 :   static void output(const std::string &, void *, raw_ostream &);
    1027       14596 :   static StringRef input(StringRef, void *, std::string &);
    1028       12319 :   static QuotingType mustQuote(StringRef S) { return needsQuotes(S); }
    1029         850 : };
    1030       12497 : 
    1031       12256 : template<>
    1032        3011 : struct ScalarTraits<uint8_t> {
    1033        3730 :   static void output(const uint8_t &, void *, raw_ostream &);
    1034        3427 :   static StringRef input(StringRef, void *, uint8_t &);
    1035        4609 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1036        2922 : };
    1037       11446 : 
    1038        8270 : template<>
    1039        4704 : struct ScalarTraits<uint16_t> {
    1040        4651 :   static void output(const uint16_t &, void *, raw_ostream &);
    1041        3083 :   static StringRef input(StringRef, void *, uint16_t &);
    1042        9943 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1043       19066 : };
    1044        9075 : 
    1045        7199 : template<>
    1046       18812 : struct ScalarTraits<uint32_t> {
    1047       20041 :   static void output(const uint32_t &, void *, raw_ostream &);
    1048       19358 :   static StringRef input(StringRef, void *, uint32_t &);
    1049        8195 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1050       12139 : };
    1051       13824 : 
    1052       14418 : template<>
    1053       11330 : struct ScalarTraits<uint64_t> {
    1054       14133 :   static void output(const uint64_t &, void *, raw_ostream &);
    1055       12259 :   static StringRef input(StringRef, void *, uint64_t &);
    1056       15703 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1057       17124 : };
    1058       25713 : 
    1059       29429 : template<>
    1060        9194 : struct ScalarTraits<int8_t> {
    1061       12173 :   static void output(const int8_t &, void *, raw_ostream &);
    1062       19258 :   static StringRef input(StringRef, void *, int8_t &);
    1063       16020 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1064       16794 : };
    1065        8204 : 
    1066       19694 : template<>
    1067       25178 : struct ScalarTraits<int16_t> {
    1068       21247 :   static void output(const int16_t &, void *, raw_ostream &);
    1069        2468 :   static StringRef input(StringRef, void *, int16_t &);
    1070       16355 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1071       15483 : };
    1072       26001 : 
    1073       12548 : template<>
    1074       16202 : struct ScalarTraits<int32_t> {
    1075       57634 :   static void output(const int32_t &, void *, raw_ostream &);
    1076        7170 :   static StringRef input(StringRef, void *, int32_t &);
    1077         662 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1078       48976 : };
    1079       59370 : 
    1080       53336 : template<>
    1081        2111 : struct ScalarTraits<int64_t> {
    1082       57911 :   static void output(const int64_t &, void *, raw_ostream &);
    1083       17370 :   static StringRef input(StringRef, void *, int64_t &);
    1084        7252 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1085        1972 : };
    1086        3633 : 
    1087       11983 : template<>
    1088       10639 : struct ScalarTraits<float> {
    1089        2146 :   static void output(const float &, void *, raw_ostream &);
    1090       11676 :   static StringRef input(StringRef, void *, float &);
    1091       10387 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1092        1225 : };
    1093        4506 : 
    1094        7501 : template<>
    1095        6197 : struct ScalarTraits<double> {
    1096       26563 :   static void output(const double &, void *, raw_ostream &);
    1097        9592 :   static StringRef input(StringRef, void *, double &);
    1098       13136 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1099        9933 : };
    1100       12602 : 
    1101        1603 : // For endian types, we just use the existing ScalarTraits for the underlying
    1102       17318 : // type.  This way endian aware types are supported whenever a ScalarTraits
    1103       25567 : // is defined for the underlying type.
    1104        8335 : template <typename value_type, support::endianness endian, size_t alignment>
    1105        8456 : struct ScalarTraits<support::detail::packed_endian_specific_integral<
    1106       17551 :     value_type, endian, alignment>> {
    1107       13605 :   using endian_type =
    1108        8078 :       support::detail::packed_endian_specific_integral<value_type, endian,
    1109        7287 :                                                        alignment>;
    1110       12689 : 
    1111        6878 :   static void output(const endian_type &E, void *Ctx, raw_ostream &Stream) {
    1112       13417 :     ScalarTraits<value_type>::output(static_cast<value_type>(E), Ctx, Stream);
    1113       11704 :   }
    1114        8530 : 
    1115        2254 :   static StringRef input(StringRef Str, void *Ctx, endian_type &E) {
    1116        2492 :     value_type V;
    1117       13505 :     auto R = ScalarTraits<value_type>::input(Str, Ctx, V);
    1118       12669 :     E = static_cast<endian_type>(V);
    1119        9047 :     return R;
    1120        7975 :   }
    1121       48411 : 
    1122       38670 :   static QuotingType mustQuote(StringRef Str) {
    1123       41061 :     return ScalarTraits<value_type>::mustQuote(Str);
    1124       45890 :   }
    1125       43070 : };
    1126        3182 : 
    1127       15037 : // Utility for use within MappingTraits<>::mapping() method
    1128       21324 : // to [de]normalize an object for use with YAML conversion.
    1129        5487 : template <typename TNorm, typename TFinal>
    1130        2381 : struct MappingNormalization {
    1131       14605 :   MappingNormalization(IO &i_o, TFinal &Obj)
    1132       18835 :       : io(i_o), BufPtr(nullptr), Result(Obj) {
    1133       18376 :     if ( io.outputting() ) {
    1134       11275 :       BufPtr = new (&Buffer) TNorm(io, Obj);
    1135       19701 :     }
    1136       22256 :     else {
    1137       15413 :       BufPtr = new (&Buffer) TNorm(io);
    1138       18706 :     }
    1139       22800 :   }
    1140       18706 : 
    1141       29452 :   ~MappingNormalization() {
    1142       25216 :     if ( ! io.outputting() ) {
    1143       21577 :       Result = BufPtr->denormalize(io);
    1144       34414 :     }
    1145       28432 :     BufPtr->~TNorm();
    1146       15958 :   }
    1147        6295 : 
    1148       22860 :   TNorm* operator->() { return BufPtr; }
    1149        5429 : 
    1150        9390 : private:
    1151       10205 :   using Storage = AlignedCharArrayUnion<TNorm>;
    1152       11778 : 
    1153        8908 :   Storage       Buffer;
    1154       15346 :   IO           &io;
    1155        2361 :   TNorm        *BufPtr;
    1156        3080 :   TFinal       &Result;
    1157       43857 : };
    1158        3388 : 
    1159        1461 : // Utility for use within MappingTraits<>::mapping() method
    1160       97503 : // to [de]normalize an object for use with YAML conversion.
    1161      249019 : template <typename TNorm, typename TFinal>
    1162      250008 : struct MappingNormalizationHeap {
    1163       96862 :   MappingNormalizationHeap(IO &i_o, TFinal &Obj, BumpPtrAllocator *allocator)
    1164      300197 :     : io(i_o), Result(Obj) {
    1165      295790 :     if ( io.outputting() ) {
    1166        1991 :       BufPtr = new (&Buffer) TNorm(io, Obj);
    1167      293818 :     }
    1168        5341 :     else if (allocator) {
    1169        4984 :       BufPtr = allocator->Allocate<TNorm>();
    1170       43763 :       new (BufPtr) TNorm(io);
    1171       42204 :     } else {
    1172       50759 :       BufPtr = new TNorm(io);
    1173       45539 :     }
    1174        1607 :   }
    1175       11395 : 
    1176       19462 :   ~MappingNormalizationHeap() {
    1177      251103 :     if ( io.outputting() ) {
    1178       14954 :       BufPtr->~TNorm();
    1179       31149 :     }
    1180       11684 :     else {
    1181       20651 :       Result = BufPtr->denormalize(io);
    1182       11286 :     }
    1183       12102 :   }
    1184       11949 : 
    1185        3002 :   TNorm* operator->() { return BufPtr; }
    1186        2534 : 
    1187        5333 : private:
    1188       13783 :   using Storage = AlignedCharArrayUnion<TNorm>;
    1189        6206 : 
    1190        3748 :   Storage       Buffer;
    1191        2125 :   IO           &io;
    1192        2218 :   TNorm        *BufPtr = nullptr;
    1193         587 :   TFinal       &Result;
    1194       16057 : };
    1195       90994 : 
    1196       90600 : ///
    1197       12791 : /// The Input class is used to parse a yaml document into in-memory structs
    1198       74002 : /// and vectors.
    1199       74936 : ///
    1200       53506 : /// It works by using YAMLParser to do a syntax parse of the entire yaml
    1201       81808 : /// document, then the Input class builds a graph of HNodes which wraps
    1202        8671 : /// each yaml Node.  The extra layer is buffering.  The low level yaml
    1203       42212 : /// parser only lets you look at each node once.  The buffering layer lets
    1204       69374 : /// you search and interate multiple times.  This is necessary because
    1205       59379 : /// the mapRequired() method calls may not be in the same order
    1206       18514 : /// as the keys in the document.
    1207       58259 : ///
    1208       52829 : class Input : public IO {
    1209        3328 : public:
    1210        2022 :   // Construct a yaml Input object from a StringRef and optional
    1211      126881 :   // user-data. The DiagHandler can be specified to provide
    1212       62826 :   // alternative error reporting.
    1213       62057 :   Input(StringRef InputContent,
    1214         214 :         void *Ctxt = nullptr,
    1215       60373 :         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
    1216       23684 :         void *DiagHandlerCtxt = nullptr);
    1217        1230 :   Input(MemoryBufferRef Input,
    1218       24166 :         void *Ctxt = nullptr,
    1219         279 :         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
    1220        1522 :         void *DiagHandlerCtxt = nullptr);
    1221        1579 :   ~Input() override;
    1222        1457 : 
    1223        2151 :   // Check if there was an syntax or semantic error during parsing.
    1224        1774 :   std::error_code error();
    1225        1235 : 
    1226        1250 : private:
    1227         934 :   bool outputting() override;
    1228       23475 :   bool mapTag(StringRef, bool) override;
    1229       72985 :   void beginMapping() override;
    1230       16144 :   void endMapping() override;
    1231        2553 :   bool preflightKey(const char *, bool, bool, bool &, void *&) override;
    1232       14185 :   void postflightKey(void *) override;
    1233       13887 :   std::vector<StringRef> keys() override;
    1234        3331 :   void beginFlowMapping() override;
    1235       15317 :   void endFlowMapping() override;
    1236        3242 :   unsigned beginSequence() override;
    1237         814 :   void endSequence() override;
    1238        5347 :   bool preflightElement(unsigned index, void *&) override;
    1239        3463 :   void postflightElement(void *) override;
    1240        3940 :   unsigned beginFlowSequence() override;
    1241        3909 :   bool preflightFlowElement(unsigned , void *&) override;
    1242         850 :   void postflightFlowElement(void *) override;
    1243         332 :   void endFlowSequence() override;
    1244         643 :   void beginEnumScalar() override;
    1245       16543 :   bool matchEnumScalar(const char*, bool) override;
    1246       99851 :   bool matchEnumFallback() override;
    1247       99814 :   void endEnumScalar() override;
    1248        1042 :   bool beginBitSetScalar(bool &) override;
    1249       85794 :   bool bitSetMatch(const char *, bool ) override;
    1250       86050 :   void endBitSetScalar() override;
    1251        4165 :   void scalarString(StringRef &, QuotingType) override;
    1252       85577 :   void blockScalarString(StringRef &) override;
    1253        4410 :   void setError(const Twine &message) override;
    1254        3338 :   bool canElideEmptySequence() override;
    1255       18910 : 
    1256       16197 :   class HNode {
    1257       15973 :     virtual void anchor();
    1258       16776 : 
    1259         741 :   public:
    1260      179464 :     HNode(Node *n) : _node(n) { }
    1261        2170 :     virtual ~HNode() = default;
    1262      100168 : 
    1263        2110 :     static bool classof(const HNode *) { return true; }
    1264        4647 : 
    1265        3422 :     Node *_node;
    1266        4106 :   };
    1267        2011 : 
    1268        3191 :   class EmptyHNode : public HNode {
    1269        2222 :     void anchor() override;
    1270        2430 : 
    1271         615 :   public:
    1272        5986 :     EmptyHNode(Node *n) : HNode(n) { }
    1273        2580 : 
    1274        5029 :     static bool classof(const HNode *n) { return NullNode::classof(n->_node); }
    1275        1646 : 
    1276        2458 :     static bool classof(const EmptyHNode *) { return true; }
    1277        3761 :   };
    1278         874 : 
    1279         863 :   class ScalarHNode : public HNode {
    1280        1844 :     void anchor() override;
    1281        9498 : 
    1282        2073 :   public:
    1283      162230 :     ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
    1284        2027 : 
    1285         844 :     StringRef value() const { return _value; }
    1286         390 : 
    1287         795 :     static bool classof(const HNode *n) {
    1288      485427 :       return ScalarNode::classof(n->_node) ||
    1289         853 :              BlockScalarNode::classof(n->_node);
    1290         993 :     }
    1291         625 : 
    1292         738 :     static bool classof(const ScalarHNode *) { return true; }
    1293        1133 : 
    1294         656 :   protected:
    1295        1150 :     StringRef _value;
    1296         676 :   };
    1297        1120 : 
    1298      146715 :   class MapHNode : public HNode {
    1299      146502 :     void anchor() override;
    1300         279 : 
    1301      105279 :   public:
    1302      105216 :     MapHNode(Node *n) : HNode(n) { }
    1303         377 : 
    1304      105570 :     static bool classof(const HNode *n) {
    1305         378 :       return MappingNode::classof(n->_node);
    1306         723 :     }
    1307       41287 : 
    1308       42434 :     static bool classof(const MapHNode *) { return true; }
    1309       41601 : 
    1310       41224 :     using NameToNode = StringMap<std::unique_ptr<HNode>>;
    1311       26495 : 
    1312       13205 :     NameToNode Mapping;
    1313       13270 :     SmallVector<std::string, 6> ValidKeys;
    1314      147196 :   };
    1315        6979 : 
    1316        7994 :   class SequenceHNode : public HNode {
    1317       25505 :     void anchor() override;
    1318        6887 : 
    1319       25517 :   public:
    1320       14571 :     SequenceHNode(Node *n) : HNode(n) { }
    1321       34509 : 
    1322       14311 :     static bool classof(const HNode *n) {
    1323        8711 :       return SequenceNode::classof(n->_node);
    1324       10046 :     }
    1325        1860 : 
    1326         990 :     static bool classof(const SequenceHNode *) { return true; }
    1327         886 : 
    1328       19114 :     std::vector<std::unique_ptr<HNode>> Entries;
    1329        1789 :   };
    1330        7090 : 
    1331        1830 :   std::unique_ptr<Input::HNode> createHNodes(Node *node);
    1332       14709 :   void setError(HNode *hnode, const Twine &message);
    1333       29319 :   void setError(Node *node, const Twine &message);
    1334        6984 : 
    1335       12925 : public:
    1336       12851 :   // These are only used by operator>>. They could be private
    1337        6778 :   // if those templated things could be made friends.
    1338        6975 :   bool setCurrentDocument();
    1339       14759 :   bool nextDocument();
    1340        2605 : 
    1341       18718 :   /// Returns the current node that's being parsed by the YAML Parser.
    1342        3611 :   const Node *getCurrentNode() const;
    1343       23175 : 
    1344        9511 : private:
    1345        7450 :   SourceMgr                           SrcMgr; // must be before Strm
    1346        6928 :   std::unique_ptr<llvm::yaml::Stream> Strm;
    1347        6699 :   std::unique_ptr<HNode>              TopNode;
    1348        8803 :   std::error_code                     EC;
    1349        1402 :   BumpPtrAllocator                    StringAllocator;
    1350         842 :   document_iterator                   DocIterator;
    1351        1286 :   std::vector<bool>                   BitValuesUsed;
    1352        5069 :   HNode *CurrentNode = nullptr;
    1353         519 :   bool                                ScalarMatchFound;
    1354         926 : };
    1355        5753 : 
    1356        1676 : ///
    1357         468 : /// The Output class is used to generate a yaml document from in-memory structs
    1358         669 : /// and vectors.
    1359         481 : ///
    1360        7667 : class Output : public IO {
    1361        5329 : public:
    1362        7579 :   Output(raw_ostream &, void *Ctxt = nullptr, int WrapColumn = 70);
    1363        5687 :   ~Output() override;
    1364         634 : 
    1365        5411 :   /// Set whether or not to output optional values which are equal
    1366        8482 :   /// to the default value.  By default, when outputting if you attempt
    1367        8164 :   /// to write a value that is equal to the default, the value gets ignored.
    1368        1477 :   /// Sometimes, it is useful to be able to see these in the resulting YAML
    1369        8752 :   /// anyway.
    1370        7665 :   void setWriteDefaultValues(bool Write) { WriteDefaultValues = Write; }
    1371        6499 : 
    1372        8641 :   bool outputting() override;
    1373         393 :   bool mapTag(StringRef, bool) override;
    1374        6723 :   void beginMapping() override;
    1375       12016 :   void endMapping() override;
    1376       12153 :   bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
    1377        1839 :   void postflightKey(void *) override;
    1378       10178 :   std::vector<StringRef> keys() override;
    1379        4170 :   void beginFlowMapping() override;
    1380         880 :   void endFlowMapping() override;
    1381        3956 :   unsigned beginSequence() override;
    1382        8252 :   void endSequence() override;
    1383        1068 :   bool preflightElement(unsigned, void *&) override;
    1384        4976 :   void postflightElement(void *) override;
    1385        4329 :   unsigned beginFlowSequence() override;
    1386        3892 :   bool preflightFlowElement(unsigned, void *&) override;
    1387        4438 :   void postflightFlowElement(void *) override;
    1388        1304 :   void endFlowSequence() override;
    1389         488 :   void beginEnumScalar() override;
    1390         921 :   bool matchEnumScalar(const char*, bool) override;
    1391        7517 :   bool matchEnumFallback() override;
    1392         860 :   void endEnumScalar() override;
    1393         225 :   bool beginBitSetScalar(bool &) override;
    1394         518 :   bool bitSetMatch(const char *, bool ) override;
    1395         587 :   void endBitSetScalar() override;
    1396        5237 :   void scalarString(StringRef &, QuotingType) override;
    1397        5114 :   void blockScalarString(StringRef &) override;
    1398        1101 :   void setError(const Twine &message) override;
    1399        3486 :   bool canElideEmptySequence() override;
    1400        5840 : 
    1401        1913 :   // These are only used by operator<<. They could be private
    1402        3540 :   // if that templated operator could be made a friend.
    1403        1613 :   void beginDocuments();
    1404        1478 :   bool preflightDocument(unsigned);
    1405        1809 :   void postflightDocument();
    1406        3043 :   void endDocuments();
    1407        1941 : 
    1408        2629 : private:
    1409        1230 :   void output(StringRef s);
    1410        1154 :   void outputUpToEndOfLine(StringRef s);
    1411        6376 :   void newLineCheck();
    1412       18183 :   void outputNewLine();
    1413        7832 :   void paddedKey(StringRef key);
    1414       31403 :   void flowKey(StringRef Key);
    1415       17652 : 
    1416       20418 :   enum InState {
    1417       17655 :     inSeq,
    1418       20297 :     inFlowSeq,
    1419        8098 :     inMapFirstKey,
    1420       11815 :     inMapOtherKey,
    1421        5045 :     inFlowMapFirstKey,
    1422        4721 :     inFlowMapOtherKey
    1423       12952 :   };
    1424        9061 : 
    1425        8798 :   raw_ostream &Out;
    1426       13318 :   int WrapColumn;
    1427        7834 :   SmallVector<InState, 8> StateStack;
    1428       26000 :   int Column = 0;
    1429        3868 :   int ColumnAtFlowStart = 0;
    1430       32015 :   int ColumnAtMapFlowStart = 0;
    1431       21448 :   bool NeedBitValueComma = false;
    1432       22283 :   bool NeedFlowSequenceComma = false;
    1433        1607 :   bool EnumerationMatchFound = false;
    1434        3275 :   bool NeedsNewLine = false;
    1435        7512 :   bool WriteDefaultValues = false;
    1436        1973 : };
    1437        8003 : 
    1438         988 : /// YAML I/O does conversion based on types. But often native data types
    1439         478 : /// are just a typedef of built in intergral types (e.g. int).  But the C++
    1440        3362 : /// type matching system sees through the typedef and all the typedefed types
    1441        1773 : /// look like a built in type. This will cause the generic YAML I/O conversion
    1442         451 : /// to be used. To provide better control over the YAML conversion, you can
    1443        1124 : /// use this macro instead of typedef.  It will create a class with one field
    1444         591 : /// and automatic conversion operators to and from the base type.
    1445        1637 : /// Based on BOOST_STRONG_TYPEDEF
    1446        9609 : #define LLVM_YAML_STRONG_TYPEDEF(_base, _type)                                 \
    1447        1827 :     struct _type {                                                             \
    1448       10014 :         _type() = default;                                                     \
    1449         888 :         _type(const _base v) : value(v) {}                                     \
    1450        3733 :         _type(const _type &v) = default;                                       \
    1451       90107 :         _type &operator=(const _type &rhs) = default;                          \
    1452       91010 :         _type &operator=(const _base &rhs) { value = rhs; return *this; }      \
    1453        1102 :         operator const _base & () const { return value; }                      \
    1454       72827 :         bool operator==(const _type &rhs) const { return value == rhs.value; } \
    1455       67098 :         bool operator==(const _base &rhs) const { return value == rhs; }       \
    1456        5997 :         bool operator<(const _type &rhs) const { return value < rhs.value; }   \
    1457       72771 :         _base value;                                                           \
    1458        6101 :         using BaseType = _base;                                                \
    1459        2056 :     };
    1460       24197 : 
    1461       24908 : ///
    1462       26993 : /// Use these types instead of uintXX_t in any mapping to have
    1463       24776 : /// its yaml output formatted as hexadecimal.
    1464        1527 : ///
    1465        8976 : LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
    1466        2866 : LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
    1467       96781 : LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
    1468       50885 : LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
    1469       39538 : 
    1470        5155 : template<>
    1471       26181 : struct ScalarTraits<Hex8> {
    1472       27219 :   static void output(const Hex8 &, void *, raw_ostream &);
    1473        1895 :   static StringRef input(StringRef, void *, Hex8 &);
    1474       27715 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1475        2320 : };
    1476        2107 : 
    1477       15139 : template<>
    1478       14750 : struct ScalarTraits<Hex16> {
    1479       16085 :   static void output(const Hex16 &, void *, raw_ostream &);
    1480       16101 :   static StringRef input(StringRef, void *, Hex16 &);
    1481        5010 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1482        3856 : };
    1483        1329 : 
    1484       40087 : template<>
    1485        2473 : struct ScalarTraits<Hex32> {
    1486        1188 :   static void output(const Hex32 &, void *, raw_ostream &);
    1487        2583 :   static StringRef input(StringRef, void *, Hex32 &);
    1488       11092 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1489       10536 : };
    1490        6238 : 
    1491        7468 : template<>
    1492        6816 : struct ScalarTraits<Hex64> {
    1493        1250 :   static void output(const Hex64 &, void *, raw_ostream &);
    1494        8645 :   static StringRef input(StringRef, void *, Hex64 &);
    1495        2335 :   static QuotingType mustQuote(StringRef) { return QuotingType::None; }
    1496        5684 : };
    1497        7784 : 
    1498        1526 : // Define non-member operator>> so that Input can stream in a document list.
    1499        5753 : template <typename T>
    1500        6471 : inline
    1501        6355 : typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
    1502        7059 : operator>>(Input &yin, T &docList) {
    1503       12904 :   int i = 0;
    1504       20506 :   EmptyContext Ctx;
    1505       20871 :   while ( yin.setCurrentDocument() ) {
    1506       20029 :     yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true, Ctx);
    1507        9877 :     if ( yin.error() )
    1508       19252 :       return yin;
    1509       13739 :     yin.nextDocument();
    1510       21471 :     ++i;
    1511        6729 :   }
    1512       11549 :   return yin;
    1513       11384 : }
    1514        4492 : 
    1515       13634 : // Define non-member operator>> so that Input can stream in a map as a document.
    1516        6542 : template <typename T>
    1517        8354 : inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
    1518       17048 :                                Input &>::type
    1519       15947 : operator>>(Input &yin, T &docMap) {
    1520       17997 :   EmptyContext Ctx;
    1521       17810 :   yin.setCurrentDocument();
    1522       21099 :   yamlize(yin, docMap, true, Ctx);
    1523        7300 :   return yin;
    1524       12127 : }
    1525         192 : 
    1526        4110 : // Define non-member operator>> so that Input can stream in a sequence as
    1527        9339 : // a document.
    1528        4254 : template <typename T>
    1529        1276 : inline
    1530        1026 : typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
    1531        1117 : operator>>(Input &yin, T &docSeq) {
    1532         406 :   EmptyContext Ctx;
    1533        5390 :   if (yin.setCurrentDocument())
    1534        5988 :     yamlize(yin, docSeq, true, Ctx);
    1535        1361 :   return yin;
    1536         247 : }
    1537         157 : 
    1538         309 : // Define non-member operator>> so that Input can stream in a block scalar.
    1539        4900 : template <typename T>
    1540         650 : inline
    1541        6586 : typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
    1542         966 : operator>>(Input &In, T &Val) {
    1543        5052 :   EmptyContext Ctx;
    1544        4244 :   if (In.setCurrentDocument())
    1545         302 :     yamlize(In, Val, true, Ctx);
    1546        2687 :   return In;
    1547        1143 : }
    1548        1296 : 
    1549         433 : // Define non-member operator>> so that Input can stream in a string map.
    1550         876 : template <typename T>
    1551         425 : inline
    1552        2077 : typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
    1553         601 : operator>>(Input &In, T &Val) {
    1554        2017 :   EmptyContext Ctx;
    1555          70 :   if (In.setCurrentDocument())
    1556        2035 :     yamlize(In, Val, true, Ctx);
    1557         637 :   return In;
    1558         438 : }
    1559         646 : 
    1560         438 : // Provide better error message about types missing a trait specialization
    1561       23511 : template <typename T>
    1562         496 : inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
    1563         445 :                                Input &>::type
    1564         496 : operator>>(Input &yin, T &docSeq) {
    1565       51897 :   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
    1566         542 :   return yin;
    1567       41274 : }
    1568         499 : 
    1569       41601 : // Define non-member operator<< so that Output can stream out document list.
    1570         620 : template <typename T>
    1571       10409 : inline
    1572         154 : typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
    1573       10643 : operator<<(Output &yout, T &docList) {
    1574         859 :   EmptyContext Ctx;
    1575       54628 :   yout.beginDocuments();
    1576        4826 :   const size_t count = DocumentListTraits<T>::size(yout, docList);
    1577        3929 :   for(size_t i=0; i < count; ++i) {
    1578        3969 :     if ( yout.preflightDocument(i) ) {
    1579        4070 :       yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true,
    1580         897 :               Ctx);
    1581          42 :       yout.postflightDocument();
    1582         912 :     }
    1583         201 :   }
    1584         119 :   yout.endDocuments();
    1585         559 :   return yout;
    1586         339 : }
    1587        2360 : 
    1588         399 : // Define non-member operator<< so that Output can stream out a map.
    1589        2303 : template <typename T>
    1590         298 : inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
    1591        1075 :                                Output &>::type
    1592         867 : operator<<(Output &yout, T &map) {
    1593         227 :   EmptyContext Ctx;
    1594         940 :   yout.beginDocuments();
    1595         689 :   if ( yout.preflightDocument(0) ) {
    1596         800 :     yamlize(yout, map, true, Ctx);
    1597        1533 :     yout.postflightDocument();
    1598         645 :   }
    1599         698 :   yout.endDocuments();
    1600        1268 :   return yout;
    1601         183 : }
    1602         646 : 
    1603         262 : // Define non-member operator<< so that Output can stream out a sequence.
    1604         255 : template <typename T>
    1605         128 : inline
    1606         199 : typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
    1607         273 : operator<<(Output &yout, T &seq) {
    1608         639 :   EmptyContext Ctx;
    1609        3568 :   yout.beginDocuments();
    1610        1844 :   if ( yout.preflightDocument(0) ) {
    1611        3943 :     yamlize(yout, seq, true, Ctx);
    1612        1687 :     yout.postflightDocument();
    1613        4118 :   }
    1614         629 :   yout.endDocuments();
    1615         411 :   return yout;
    1616        1634 : }
    1617          63 : 
    1618        2688 : // Define non-member operator<< so that Output can stream out a block scalar.
    1619        3694 : template <typename T>
    1620       38763 : inline
    1621         624 : typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
    1622       37878 : operator<<(Output &Out, T &Val) {
    1623         488 :   EmptyContext Ctx;
    1624       36763 :   Out.beginDocuments();
    1625         429 :   if (Out.preflightDocument(0)) {
    1626          92 :     yamlize(Out, Val, true, Ctx);
    1627         517 :     Out.postflightDocument();
    1628         125 :   }
    1629         271 :   Out.endDocuments();
    1630       37304 :   return Out;
    1631       13465 : }
    1632       17850 : 
    1633        1111 : // Define non-member operator<< so that Output can stream out a string map.
    1634        2399 : template <typename T>
    1635        1350 : inline
    1636          61 : typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
    1637        1854 : operator<<(Output &Out, T &Val) {
    1638        6025 :   EmptyContext Ctx;
    1639         181 :   Out.beginDocuments();
    1640       16621 :   if (Out.preflightDocument(0)) {
    1641       12110 :     yamlize(Out, Val, true, Ctx);
    1642       16877 :     Out.postflightDocument();
    1643       11709 :   }
    1644        1136 :   Out.endDocuments();
    1645        1121 :   return Out;
    1646        1065 : }
    1647       12484 : 
    1648        6547 : // Provide better error message about types missing a trait specialization
    1649        6865 : template <typename T>
    1650         420 : inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
    1651         402 :                                Output &>::type
    1652         909 : operator<<(Output &yout, T &seq) {
    1653        6905 :   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
    1654       10706 :   return yout;
    1655         375 : }
    1656        2547 : 
    1657        8637 : template <bool B> struct IsFlowSequenceBase {};
    1658        8712 : template <> struct IsFlowSequenceBase<true> { static const bool flow = true; };
    1659       11961 : 
    1660       13728 : template <typename T, bool Flow>
    1661        6071 : struct SequenceTraitsImpl : IsFlowSequenceBase<Flow> {
    1662        7654 : private:
    1663        7044 :   using type = typename T::value_type;
    1664       18861 : 
    1665         789 : public:
    1666        1048 :   static size_t size(IO &io, T &seq) { return seq.size(); }
    1667         892 : 
    1668        8767 :   static type &element(IO &io, T &seq, size_t index) {
    1669         592 :     if (index >= seq.size())
    1670        5486 :       seq.resize(index + 1);
    1671        1399 :     return seq[index];
    1672        5576 :   }
    1673         213 : };
    1674       12027 : 
    1675         537 : // Simple helper to check an expression can be used as a bool-valued template
    1676        7751 : // argument.
    1677          75 : template <bool> struct CheckIsBool { static const bool value = true; };
    1678        7144 : 
    1679         763 : // If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
    1680           5 : // SequenceTraits that do the obvious thing.
    1681         145 : template <typename T>
    1682         582 : struct SequenceTraits<std::vector<T>,
    1683         110 :                       typename std::enable_if<CheckIsBool<
    1684         648 :                           SequenceElementTraits<T>::flow>::value>::type>
    1685        1034 :     : SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
    1686         579 : template <typename T, unsigned N>
    1687        1159 : struct SequenceTraits<SmallVector<T, N>,
    1688          26 :                       typename std::enable_if<CheckIsBool<
    1689        1129 :                           SequenceElementTraits<T>::flow>::value>::type>
    1690        7455 :     : SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
    1691           7 : 
    1692         479 : // Sequences of fundamental types use flow formatting.
    1693         798 : template <typename T>
    1694         347 : struct SequenceElementTraits<
    1695         791 :     T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
    1696        7421 :   static const bool flow = true;
    1697         386 : };
    1698       13922 : 
    1699       29707 : // Sequences of strings use block formatting.
    1700        7375 : template<> struct SequenceElementTraits<std::string> {
    1701         673 :   static const bool flow = false;
    1702        1706 : };
    1703        1536 : template<> struct SequenceElementTraits<StringRef> {
    1704        6769 :   static const bool flow = false;
    1705        1529 : };
    1706        8216 : template<> struct SequenceElementTraits<std::pair<std::string, std::string>> {
    1707        2021 :   static const bool flow = false;
    1708        8059 : };
    1709        1139 : 
    1710        1702 : /// Implementation of CustomMappingTraits for std::map<std::string, T>.
    1711         795 : template <typename T> struct StdMapStringCustomMappingTraitsImpl {
    1712        2724 :   using map_type = std::map<std::string, T>;
    1713       30169 : 
    1714       29516 :   static void inputOne(IO &io, StringRef key, map_type &v) {
    1715       70731 :     io.mapRequired(key.str().c_str(), v[key]);
    1716         223 :   }
    1717       41398 : 
    1718       44183 :   static void output(IO &io, map_type &v) {
    1719       41702 :     for (auto &p : v)
    1720        3526 :       io.mapRequired(p.first.c_str(), p.second);
    1721        2024 :   }
    1722       32544 : };
    1723        1439 : 
    1724       29507 : } // end namespace yaml
    1725        5586 : } // end namespace llvm
    1726         514 : 
    1727         325 : #define LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(TYPE, FLOW)                          \
    1728         489 :   namespace llvm {                                                             \
    1729         865 :   namespace yaml {                                                             \
    1730         450 :   static_assert(                                                               \
    1731        1344 :       !std::is_fundamental<TYPE>::value &&                                     \
    1732          25 :       !std::is_same<TYPE, std::string>::value &&                               \
    1733         862 :       !std::is_same<TYPE, llvm::StringRef>::value,                             \
    1734         299 :       "only use LLVM_YAML_IS_SEQUENCE_VECTOR for types you control");          \
    1735           2 :   template <> struct SequenceElementTraits<TYPE> {                             \
    1736           0 :     static const bool flow = FLOW;                                             \
    1737         484 :   };                                                                           \
    1738           0 :   }                                                                            \
    1739        5770 :   }
    1740        5583 : 
    1741        5859 : /// Utility for declaring that a std::vector of a particular type
    1742         323 : /// should be considered a YAML sequence.
    1743         108 : #define LLVM_YAML_IS_SEQUENCE_VECTOR(type)                                     \
    1744         439 :   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, false)
    1745         194 : 
    1746          52 : /// Utility for declaring that a std::vector of a particular type
    1747          38 : /// should be considered a YAML flow sequence.
    1748        5333 : #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)                                \
    1749           7 :   LLVM_YAML_IS_SEQUENCE_VECTOR_IMPL(type, true)
    1750        5297 : 
    1751        5479 : #define LLVM_YAML_DECLARE_MAPPING_TRAITS(Type)                                 \
    1752          36 :   namespace llvm {                                                             \
    1753         170 :   namespace yaml {                                                             \
    1754          43 :   template <> struct MappingTraits<Type> {                                     \
    1755         100 :     static void mapping(IO &IO, Type &Obj);                                    \
    1756         484 :   };                                                                           \
    1757          51 :   }                                                                            \
    1758           3 :   }
    1759          59 : 
    1760           1 : #define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)                                    \
    1761          60 :   namespace llvm {                                                             \
    1762         464 :   namespace yaml {                                                             \
    1763         108 :   template <> struct ScalarEnumerationTraits<Type> {                           \
    1764         486 :     static void enumeration(IO &io, Type &Value);                              \
    1765        5413 :   };                                                                           \
    1766        5831 :   }                                                                            \
    1767        7763 :   }
    1768        1128 : 
    1769         893 : #define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)                                  \
    1770        1440 :   namespace llvm {                                                             \
    1771        1358 :   namespace yaml {                                                             \
    1772          63 :   template <> struct ScalarBitSetTraits<Type> {                                \
    1773        1202 :     static void bitset(IO &IO, Type &Options);                                 \
    1774        5769 :   };                                                                           \
    1775         759 :   }                                                                            \
    1776        6023 :   }
    1777        6379 : 
    1778         683 : #define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)                       \
    1779         685 :   namespace llvm {                                                             \
    1780          16 :   namespace yaml {                                                             \
    1781          56 :   template <> struct ScalarTraits<Type> {                                      \
    1782          16 :     static void output(const Type &Value, void *ctx, raw_ostream &Out);        \
    1783         831 :     static StringRef input(StringRef Scalar, void *ctxt, Type &Value);         \
    1784         924 :     static QuotingType mustQuote(StringRef) { return MustQuote; }              \
    1785        1259 :   };                                                                           \
    1786          39 :   }                                                                            \
    1787         353 :   }
    1788         492 : 
    1789         345 : /// Utility for declaring that a std::vector of a particular type
    1790          19 : /// should be considered a YAML document list.
    1791        5346 : #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                               \
    1792        5466 :   namespace llvm {                                                             \
    1793        6722 :   namespace yaml {                                                             \
    1794        1005 :   template <unsigned N>                                                        \
    1795        1552 :   struct DocumentListTraits<SmallVector<_type, N>>                             \
    1796        1546 :       : public SequenceTraitsImpl<SmallVector<_type, N>, false> {};            \
    1797         665 :   template <>                                                                  \
    1798          57 :   struct DocumentListTraits<std::vector<_type>>                                \
    1799          42 :       : public SequenceTraitsImpl<std::vector<_type>, false> {};               \
    1800        7004 :   }                                                                            \
    1801         773 :   }
    1802        6927 : 
    1803        6374 : /// Utility for declaring that std::map<std::string, _type> should be considered
    1804        1805 : /// a YAML map.
    1805        3020 : #define LLVM_YAML_IS_STRING_MAP(_type)                                         \
    1806        2178 :   namespace llvm {                                                             \
    1807        1391 :   namespace yaml {                                                             \
    1808        2139 :   template <>                                                                  \
    1809           3 :   struct CustomMappingTraits<std::map<std::string, _type>>                     \
    1810        1528 :       : public StdMapStringCustomMappingTraitsImpl<_type> {};                  \
    1811        1209 :   }                                                                            \
    1812         746 :   }
    1813        1198 : 
    1814         584 : #endif // LLVM_SUPPORT_YAMLTRAITS_H

Generated by: LCOV version 1.13