Re-landing "Refactoring cl::list_storage from "is a" to "has a" std::vector."
[oota-llvm.git] / include / llvm / Support / YAMLTraits.h
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
14 #include "llvm/ADT/DenseMap.h"
15 #include "llvm/ADT/DenseMapInfo.h"
16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/Regex.h"
24 #include "llvm/Support/SourceMgr.h"
25 #include "llvm/Support/YAMLParser.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include <system_error>
28
29 namespace llvm {
30 namespace yaml {
31
32
33 /// This class should be specialized by any type that needs to be converted
34 /// to/from a YAML mapping.  For example:
35 ///
36 ///     struct MappingTraits<MyStruct> {
37 ///       static void mapping(IO &io, MyStruct &s) {
38 ///         io.mapRequired("name", s.name);
39 ///         io.mapRequired("size", s.size);
40 ///         io.mapOptional("age",  s.age);
41 ///       }
42 ///     };
43 template<class T>
44 struct MappingTraits {
45   // Must provide:
46   // static void mapping(IO &io, T &fields);
47   // Optionally may provide:
48   // static StringRef validate(IO &io, T &fields);
49   //
50   // The optional flow flag will cause generated YAML to use a flow mapping
51   // (e.g. { a: 0, b: 1 }):
52   // static const bool flow = true;
53 };
54
55
56 /// This class should be specialized by any integral type that converts
57 /// to/from a YAML scalar where there is a one-to-one mapping between
58 /// in-memory values and a string in YAML.  For example:
59 ///
60 ///     struct ScalarEnumerationTraits<Colors> {
61 ///         static void enumeration(IO &io, Colors &value) {
62 ///           io.enumCase(value, "red",   cRed);
63 ///           io.enumCase(value, "blue",  cBlue);
64 ///           io.enumCase(value, "green", cGreen);
65 ///         }
66 ///       };
67 template<typename T>
68 struct ScalarEnumerationTraits {
69   // Must provide:
70   // static void enumeration(IO &io, T &value);
71 };
72
73
74 /// This class should be specialized by any integer type that is a union
75 /// of bit values and the YAML representation is a flow sequence of
76 /// strings.  For example:
77 ///
78 ///      struct ScalarBitSetTraits<MyFlags> {
79 ///        static void bitset(IO &io, MyFlags &value) {
80 ///          io.bitSetCase(value, "big",   flagBig);
81 ///          io.bitSetCase(value, "flat",  flagFlat);
82 ///          io.bitSetCase(value, "round", flagRound);
83 ///        }
84 ///      };
85 template<typename T>
86 struct ScalarBitSetTraits {
87   // Must provide:
88   // static void bitset(IO &io, T &value);
89 };
90
91
92 /// This class should be specialized by type that requires custom conversion
93 /// to/from a yaml scalar.  For example:
94 ///
95 ///    template<>
96 ///    struct ScalarTraits<MyType> {
97 ///      static void output(const MyType &val, void*, llvm::raw_ostream &out) {
98 ///        // stream out custom formatting
99 ///        out << llvm::format("%x", val);
100 ///      }
101 ///      static StringRef input(StringRef scalar, void*, MyType &value) {
102 ///        // parse scalar and set `value`
103 ///        // return empty string on success, or error string
104 ///        return StringRef();
105 ///      }
106 ///      static bool mustQuote(StringRef) { return true; }
107 ///    };
108 template<typename T>
109 struct ScalarTraits {
110   // Must provide:
111   //
112   // Function to write the value as a string:
113   //static void output(const T &value, void *ctxt, llvm::raw_ostream &out);
114   //
115   // Function to convert a string to a value.  Returns the empty
116   // StringRef on success or an error string if string is malformed:
117   //static StringRef input(StringRef scalar, void *ctxt, T &value);
118   //
119   // Function to determine if the value should be quoted.
120   //static bool mustQuote(StringRef);
121 };
122
123
124 /// This class should be specialized by type that requires custom conversion
125 /// to/from a YAML literal block scalar. For example:
126 ///
127 ///    template <>
128 ///    struct BlockScalarTraits<MyType> {
129 ///      static void output(const MyType &Value, void*, llvm::raw_ostream &Out)
130 ///      {
131 ///        // stream out custom formatting
132 ///        Out << Val;
133 ///      }
134 ///      static StringRef input(StringRef Scalar, void*, MyType &Value) {
135 ///        // parse scalar and set `value`
136 ///        // return empty string on success, or error string
137 ///        return StringRef();
138 ///      }
139 ///    };
140 template <typename T>
141 struct BlockScalarTraits {
142   // Must provide:
143   //
144   // Function to write the value as a string:
145   // static void output(const T &Value, void *ctx, llvm::raw_ostream &Out);
146   //
147   // Function to convert a string to a value.  Returns the empty
148   // StringRef on success or an error string if string is malformed:
149   // static StringRef input(StringRef Scalar, void *ctxt, T &Value);
150 };
151
152
153 /// This class should be specialized by any type that needs to be converted
154 /// to/from a YAML sequence.  For example:
155 ///
156 ///    template<>
157 ///    struct SequenceTraits< std::vector<MyType> > {
158 ///      static size_t size(IO &io, std::vector<MyType> &seq) {
159 ///        return seq.size();
160 ///      }
161 ///      static MyType& element(IO &, std::vector<MyType> &seq, size_t index) {
162 ///        if ( index >= seq.size() )
163 ///          seq.resize(index+1);
164 ///        return seq[index];
165 ///      }
166 ///    };
167 template<typename T>
168 struct SequenceTraits {
169   // Must provide:
170   // static size_t size(IO &io, T &seq);
171   // static T::value_type& element(IO &io, T &seq, size_t index);
172   //
173   // The following is option and will cause generated YAML to use
174   // a flow sequence (e.g. [a,b,c]).
175   // static const bool flow = true;
176 };
177
178
179 /// This class should be specialized by any type that needs to be converted
180 /// to/from a list of YAML documents.
181 template<typename T>
182 struct DocumentListTraits {
183   // Must provide:
184   // static size_t size(IO &io, T &seq);
185   // static T::value_type& element(IO &io, T &seq, size_t index);
186 };
187
188
189 // Only used by compiler if both template types are the same
190 template <typename T, T>
191 struct SameType;
192
193 // Only used for better diagnostics of missing traits
194 template <typename T>
195 struct MissingTrait;
196
197
198
199 // Test if ScalarEnumerationTraits<T> is defined on type T.
200 template <class T>
201 struct has_ScalarEnumerationTraits
202 {
203   typedef void (*Signature_enumeration)(class IO&, T&);
204
205   template <typename U>
206   static char test(SameType<Signature_enumeration, &U::enumeration>*);
207
208   template <typename U>
209   static double test(...);
210
211 public:
212   static bool const value =
213     (sizeof(test<ScalarEnumerationTraits<T> >(nullptr)) == 1);
214 };
215
216
217 // Test if ScalarBitSetTraits<T> is defined on type T.
218 template <class T>
219 struct has_ScalarBitSetTraits
220 {
221   typedef void (*Signature_bitset)(class IO&, T&);
222
223   template <typename U>
224   static char test(SameType<Signature_bitset, &U::bitset>*);
225
226   template <typename U>
227   static double test(...);
228
229 public:
230   static bool const value = (sizeof(test<ScalarBitSetTraits<T> >(nullptr)) == 1);
231 };
232
233
234 // Test if ScalarTraits<T> is defined on type T.
235 template <class T>
236 struct has_ScalarTraits
237 {
238   typedef StringRef (*Signature_input)(StringRef, void*, T&);
239   typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
240   typedef bool (*Signature_mustQuote)(StringRef);
241
242   template <typename U>
243   static char test(SameType<Signature_input, &U::input> *,
244                    SameType<Signature_output, &U::output> *,
245                    SameType<Signature_mustQuote, &U::mustQuote> *);
246
247   template <typename U>
248   static double test(...);
249
250 public:
251   static bool const value =
252       (sizeof(test<ScalarTraits<T>>(nullptr, nullptr, nullptr)) == 1);
253 };
254
255
256 // Test if BlockScalarTraits<T> is defined on type T.
257 template <class T>
258 struct has_BlockScalarTraits
259 {
260   typedef StringRef (*Signature_input)(StringRef, void *, T &);
261   typedef void (*Signature_output)(const T &, void *, llvm::raw_ostream &);
262
263   template <typename U>
264   static char test(SameType<Signature_input, &U::input> *,
265                    SameType<Signature_output, &U::output> *);
266
267   template <typename U>
268   static double test(...);
269
270 public:
271   static bool const value =
272       (sizeof(test<BlockScalarTraits<T>>(nullptr, nullptr)) == 1);
273 };
274
275
276 // Test if MappingTraits<T> is defined on type T.
277 template <class T>
278 struct has_MappingTraits
279 {
280   typedef void (*Signature_mapping)(class IO&, T&);
281
282   template <typename U>
283   static char test(SameType<Signature_mapping, &U::mapping>*);
284
285   template <typename U>
286   static double test(...);
287
288 public:
289   static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1);
290 };
291
292 // Test if MappingTraits<T>::validate() is defined on type T.
293 template <class T>
294 struct has_MappingValidateTraits
295 {
296   typedef StringRef (*Signature_validate)(class IO&, T&);
297
298   template <typename U>
299   static char test(SameType<Signature_validate, &U::validate>*);
300
301   template <typename U>
302   static double test(...);
303
304 public:
305   static bool const value = (sizeof(test<MappingTraits<T> >(nullptr)) == 1);
306 };
307
308
309
310 // Test if SequenceTraits<T> is defined on type T.
311 template <class T>
312 struct has_SequenceMethodTraits
313 {
314   typedef size_t (*Signature_size)(class IO&, T&);
315
316   template <typename U>
317   static char test(SameType<Signature_size, &U::size>*);
318
319   template <typename U>
320   static double test(...);
321
322 public:
323   static bool const value =  (sizeof(test<SequenceTraits<T> >(nullptr)) == 1);
324 };
325
326
327 // has_FlowTraits<int> will cause an error with some compilers because
328 // it subclasses int.  Using this wrapper only instantiates the
329 // real has_FlowTraits only if the template type is a class.
330 template <typename T, bool Enabled = std::is_class<T>::value>
331 class has_FlowTraits
332 {
333 public:
334    static const bool value = false;
335 };
336
337 // Some older gcc compilers don't support straight forward tests
338 // for members, so test for ambiguity cause by the base and derived
339 // classes both defining the member.
340 template <class T>
341 struct has_FlowTraits<T, true>
342 {
343   struct Fallback { bool flow; };
344   struct Derived : T, Fallback { };
345
346   template<typename C>
347   static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
348
349   template<typename C>
350   static char (&f(...))[2];
351
352 public:
353   static bool const value = sizeof(f<Derived>(nullptr)) == 2;
354 };
355
356
357
358 // Test if SequenceTraits<T> is defined on type T
359 template<typename T>
360 struct has_SequenceTraits : public std::integral_constant<bool,
361                                       has_SequenceMethodTraits<T>::value > { };
362
363
364 // Test if DocumentListTraits<T> is defined on type T
365 template <class T>
366 struct has_DocumentListTraits
367 {
368   typedef size_t (*Signature_size)(class IO&, T&);
369
370   template <typename U>
371   static char test(SameType<Signature_size, &U::size>*);
372
373   template <typename U>
374   static double test(...);
375
376 public:
377   static bool const value = (sizeof(test<DocumentListTraits<T> >(nullptr))==1);
378 };
379
380 inline bool isNumber(StringRef S) {
381   static const char OctalChars[] = "01234567";
382   if (S.startswith("0") &&
383       S.drop_front().find_first_not_of(OctalChars) == StringRef::npos)
384     return true;
385
386   if (S.startswith("0o") &&
387       S.drop_front(2).find_first_not_of(OctalChars) == StringRef::npos)
388     return true;
389
390   static const char HexChars[] = "0123456789abcdefABCDEF";
391   if (S.startswith("0x") &&
392       S.drop_front(2).find_first_not_of(HexChars) == StringRef::npos)
393     return true;
394
395   static const char DecChars[] = "0123456789";
396   if (S.find_first_not_of(DecChars) == StringRef::npos)
397     return true;
398
399   if (S.equals(".inf") || S.equals(".Inf") || S.equals(".INF"))
400     return true;
401
402   Regex FloatMatcher("^(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$");
403   if (FloatMatcher.match(S))
404     return true;
405
406   return false;
407 }
408
409 inline bool isNumeric(StringRef S) {
410   if ((S.front() == '-' || S.front() == '+') && isNumber(S.drop_front()))
411     return true;
412
413   if (isNumber(S))
414     return true;
415
416   if (S.equals(".nan") || S.equals(".NaN") || S.equals(".NAN"))
417     return true;
418
419   return false;
420 }
421
422 inline bool isNull(StringRef S) {
423   return S.equals("null") || S.equals("Null") || S.equals("NULL") ||
424          S.equals("~");
425 }
426
427 inline bool isBool(StringRef S) {
428   return S.equals("true") || S.equals("True") || S.equals("TRUE") ||
429          S.equals("false") || S.equals("False") || S.equals("FALSE");
430 }
431
432 inline bool needsQuotes(StringRef S) {
433   if (S.empty())
434     return true;
435   if (isspace(S.front()) || isspace(S.back()))
436     return true;
437   if (S.front() == ',')
438     return true;
439
440   static const char ScalarSafeChars[] =
441       "abcdefghijklmnopqrstuvwxyz"
442       "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t";
443   if (S.find_first_not_of(ScalarSafeChars) != StringRef::npos)
444     return true;
445
446   if (isNull(S))
447     return true;
448   if (isBool(S))
449     return true;
450   if (isNumeric(S))
451     return true;
452
453   return false;
454 }
455
456
457 template<typename T>
458 struct missingTraits : public std::integral_constant<bool,
459                                          !has_ScalarEnumerationTraits<T>::value
460                                       && !has_ScalarBitSetTraits<T>::value
461                                       && !has_ScalarTraits<T>::value
462                                       && !has_BlockScalarTraits<T>::value
463                                       && !has_MappingTraits<T>::value
464                                       && !has_SequenceTraits<T>::value
465                                       && !has_DocumentListTraits<T>::value >  {};
466
467 template<typename T>
468 struct validatedMappingTraits : public std::integral_constant<bool,
469                                        has_MappingTraits<T>::value
470                                     && has_MappingValidateTraits<T>::value> {};
471
472 template<typename T>
473 struct unvalidatedMappingTraits : public std::integral_constant<bool,
474                                         has_MappingTraits<T>::value
475                                     && !has_MappingValidateTraits<T>::value> {};
476 // Base class for Input and Output.
477 class IO {
478 public:
479
480   IO(void *Ctxt=nullptr);
481   virtual ~IO();
482
483   virtual bool outputting() = 0;
484
485   virtual unsigned beginSequence() = 0;
486   virtual bool preflightElement(unsigned, void *&) = 0;
487   virtual void postflightElement(void*) = 0;
488   virtual void endSequence() = 0;
489   virtual bool canElideEmptySequence() = 0;
490
491   virtual unsigned beginFlowSequence() = 0;
492   virtual bool preflightFlowElement(unsigned, void *&) = 0;
493   virtual void postflightFlowElement(void*) = 0;
494   virtual void endFlowSequence() = 0;
495
496   virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
497   virtual void beginMapping() = 0;
498   virtual void endMapping() = 0;
499   virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
500   virtual void postflightKey(void*) = 0;
501
502   virtual void beginFlowMapping() = 0;
503   virtual void endFlowMapping() = 0;
504
505   virtual void beginEnumScalar() = 0;
506   virtual bool matchEnumScalar(const char*, bool) = 0;
507   virtual bool matchEnumFallback() = 0;
508   virtual void endEnumScalar() = 0;
509
510   virtual bool beginBitSetScalar(bool &) = 0;
511   virtual bool bitSetMatch(const char*, bool) = 0;
512   virtual void endBitSetScalar() = 0;
513
514   virtual void scalarString(StringRef &, bool) = 0;
515   virtual void blockScalarString(StringRef &) = 0;
516
517   virtual void setError(const Twine &) = 0;
518
519   template <typename T>
520   void enumCase(T &Val, const char* Str, const T ConstVal) {
521     if ( matchEnumScalar(Str, outputting() && Val == ConstVal) ) {
522       Val = ConstVal;
523     }
524   }
525
526   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
527   template <typename T>
528   void enumCase(T &Val, const char* Str, const uint32_t ConstVal) {
529     if ( matchEnumScalar(Str, outputting() && Val == static_cast<T>(ConstVal)) ) {
530       Val = ConstVal;
531     }
532   }
533
534   template <typename FBT, typename T>
535   void enumFallback(T &Val) {
536     if ( matchEnumFallback() ) {
537       // FIXME: Force integral conversion to allow strong typedefs to convert.
538       FBT Res = (uint64_t)Val;
539       yamlize(*this, Res, true);
540       Val = (uint64_t)Res;
541     }
542   }
543
544   template <typename T>
545   void bitSetCase(T &Val, const char* Str, const T ConstVal) {
546     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
547       Val = Val | ConstVal;
548     }
549   }
550
551   // allow anonymous enum values to be used with LLVM_YAML_STRONG_TYPEDEF
552   template <typename T>
553   void bitSetCase(T &Val, const char* Str, const uint32_t ConstVal) {
554     if ( bitSetMatch(Str, outputting() && (Val & ConstVal) == ConstVal) ) {
555       Val = Val | ConstVal;
556     }
557   }
558
559   template <typename T>
560   void maskedBitSetCase(T &Val, const char *Str, T ConstVal, T Mask) {
561     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
562       Val = Val | ConstVal;
563   }
564
565   template <typename T>
566   void maskedBitSetCase(T &Val, const char *Str, uint32_t ConstVal,
567                         uint32_t Mask) {
568     if (bitSetMatch(Str, outputting() && (Val & Mask) == ConstVal))
569       Val = Val | ConstVal;
570   }
571
572   void *getContext();
573   void setContext(void *);
574
575   template <typename T>
576   void mapRequired(const char* Key, T& Val) {
577     this->processKey(Key, Val, true);
578   }
579
580   template <typename T>
581   typename std::enable_if<has_SequenceTraits<T>::value,void>::type
582   mapOptional(const char* Key, T& Val) {
583     // omit key/value instead of outputting empty sequence
584     if ( this->canElideEmptySequence() && !(Val.begin() != Val.end()) )
585       return;
586     this->processKey(Key, Val, false);
587   }
588
589   template <typename T>
590   void mapOptional(const char* Key, Optional<T> &Val) {
591     processKeyWithDefault(Key, Val, Optional<T>(), /*Required=*/false);
592   }
593
594   template <typename T>
595   typename std::enable_if<!has_SequenceTraits<T>::value,void>::type
596   mapOptional(const char* Key, T& Val) {
597     this->processKey(Key, Val, false);
598   }
599
600   template <typename T>
601   void mapOptional(const char* Key, T& Val, const T& Default) {
602     this->processKeyWithDefault(Key, Val, Default, false);
603   }
604
605 private:
606   template <typename T>
607   void processKeyWithDefault(const char *Key, Optional<T> &Val,
608                              const Optional<T> &DefaultValue, bool Required) {
609     assert(DefaultValue.hasValue() == false &&
610            "Optional<T> shouldn't have a value!");
611     void *SaveInfo;
612     bool UseDefault;
613     const bool sameAsDefault = outputting() && !Val.hasValue();
614     if (!outputting() && !Val.hasValue())
615       Val = T();
616     if (this->preflightKey(Key, Required, sameAsDefault, UseDefault,
617                            SaveInfo)) {
618       yamlize(*this, Val.getValue(), Required);
619       this->postflightKey(SaveInfo);
620     } else {
621       if (UseDefault)
622         Val = DefaultValue;
623     }
624   }
625
626   template <typename T>
627   void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
628                                                                 bool Required) {
629     void *SaveInfo;
630     bool UseDefault;
631     const bool sameAsDefault = outputting() && Val == DefaultValue;
632     if ( this->preflightKey(Key, Required, sameAsDefault, UseDefault,
633                                                                   SaveInfo) ) {
634       yamlize(*this, Val, Required);
635       this->postflightKey(SaveInfo);
636     }
637     else {
638       if ( UseDefault )
639         Val = DefaultValue;
640     }
641   }
642
643   template <typename T>
644   void processKey(const char *Key, T &Val, bool Required) {
645     void *SaveInfo;
646     bool UseDefault;
647     if ( this->preflightKey(Key, Required, false, UseDefault, SaveInfo) ) {
648       yamlize(*this, Val, Required);
649       this->postflightKey(SaveInfo);
650     }
651   }
652
653 private:
654   void  *Ctxt;
655 };
656
657
658
659 template<typename T>
660 typename std::enable_if<has_ScalarEnumerationTraits<T>::value,void>::type
661 yamlize(IO &io, T &Val, bool) {
662   io.beginEnumScalar();
663   ScalarEnumerationTraits<T>::enumeration(io, Val);
664   io.endEnumScalar();
665 }
666
667 template<typename T>
668 typename std::enable_if<has_ScalarBitSetTraits<T>::value,void>::type
669 yamlize(IO &io, T &Val, bool) {
670   bool DoClear;
671   if ( io.beginBitSetScalar(DoClear) ) {
672     if ( DoClear )
673       Val = static_cast<T>(0);
674     ScalarBitSetTraits<T>::bitset(io, Val);
675     io.endBitSetScalar();
676   }
677 }
678
679
680 template<typename T>
681 typename std::enable_if<has_ScalarTraits<T>::value,void>::type
682 yamlize(IO &io, T &Val, bool) {
683   if ( io.outputting() ) {
684     std::string Storage;
685     llvm::raw_string_ostream Buffer(Storage);
686     ScalarTraits<T>::output(Val, io.getContext(), Buffer);
687     StringRef Str = Buffer.str();
688     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
689   }
690   else {
691     StringRef Str;
692     io.scalarString(Str, ScalarTraits<T>::mustQuote(Str));
693     StringRef Result = ScalarTraits<T>::input(Str, io.getContext(), Val);
694     if ( !Result.empty() ) {
695       io.setError(llvm::Twine(Result));
696     }
697   }
698 }
699
700 template <typename T>
701 typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
702 yamlize(IO &YamlIO, T &Val, bool) {
703   if (YamlIO.outputting()) {
704     std::string Storage;
705     llvm::raw_string_ostream Buffer(Storage);
706     BlockScalarTraits<T>::output(Val, YamlIO.getContext(), Buffer);
707     StringRef Str = Buffer.str();
708     YamlIO.blockScalarString(Str);
709   } else {
710     StringRef Str;
711     YamlIO.blockScalarString(Str);
712     StringRef Result =
713         BlockScalarTraits<T>::input(Str, YamlIO.getContext(), Val);
714     if (!Result.empty())
715       YamlIO.setError(llvm::Twine(Result));
716   }
717 }
718
719 template<typename T>
720 typename std::enable_if<validatedMappingTraits<T>::value, void>::type
721 yamlize(IO &io, T &Val, bool) {
722   if (has_FlowTraits<MappingTraits<T>>::value)
723     io.beginFlowMapping();
724   else
725     io.beginMapping();
726   if (io.outputting()) {
727     StringRef Err = MappingTraits<T>::validate(io, Val);
728     if (!Err.empty()) {
729       llvm::errs() << Err << "\n";
730       assert(Err.empty() && "invalid struct trying to be written as yaml");
731     }
732   }
733   MappingTraits<T>::mapping(io, Val);
734   if (!io.outputting()) {
735     StringRef Err = MappingTraits<T>::validate(io, Val);
736     if (!Err.empty())
737       io.setError(Err);
738   }
739   if (has_FlowTraits<MappingTraits<T>>::value)
740     io.endFlowMapping();
741   else
742     io.endMapping();
743 }
744
745 template<typename T>
746 typename std::enable_if<unvalidatedMappingTraits<T>::value, void>::type
747 yamlize(IO &io, T &Val, bool) {
748   if (has_FlowTraits<MappingTraits<T>>::value) {
749     io.beginFlowMapping();
750     MappingTraits<T>::mapping(io, Val);
751     io.endFlowMapping();
752   } else {
753     io.beginMapping();
754     MappingTraits<T>::mapping(io, Val);
755     io.endMapping();
756   }
757 }
758
759 template<typename T>
760 typename std::enable_if<missingTraits<T>::value, void>::type
761 yamlize(IO &io, T &Val, bool) {
762   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
763 }
764
765 template<typename T>
766 typename std::enable_if<has_SequenceTraits<T>::value,void>::type
767 yamlize(IO &io, T &Seq, bool) {
768   if ( has_FlowTraits< SequenceTraits<T> >::value ) {
769     unsigned incnt = io.beginFlowSequence();
770     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
771     for(unsigned i=0; i < count; ++i) {
772       void *SaveInfo;
773       if ( io.preflightFlowElement(i, SaveInfo) ) {
774         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
775         io.postflightFlowElement(SaveInfo);
776       }
777     }
778     io.endFlowSequence();
779   }
780   else {
781     unsigned incnt = io.beginSequence();
782     unsigned count = io.outputting() ? SequenceTraits<T>::size(io, Seq) : incnt;
783     for(unsigned i=0; i < count; ++i) {
784       void *SaveInfo;
785       if ( io.preflightElement(i, SaveInfo) ) {
786         yamlize(io, SequenceTraits<T>::element(io, Seq, i), true);
787         io.postflightElement(SaveInfo);
788       }
789     }
790     io.endSequence();
791   }
792 }
793
794
795 template<>
796 struct ScalarTraits<bool> {
797   static void output(const bool &, void*, llvm::raw_ostream &);
798   static StringRef input(StringRef, void*, bool &);
799   static bool mustQuote(StringRef) { return false; }
800 };
801
802 template<>
803 struct ScalarTraits<StringRef> {
804   static void output(const StringRef &, void*, llvm::raw_ostream &);
805   static StringRef input(StringRef, void*, StringRef &);
806   static bool mustQuote(StringRef S) { return needsQuotes(S); }
807 };
808
809 template<>
810 struct ScalarTraits<std::string> {
811   static void output(const std::string &, void*, llvm::raw_ostream &);
812   static StringRef input(StringRef, void*, std::string &);
813   static bool mustQuote(StringRef S) { return needsQuotes(S); }
814 };
815
816 template<>
817 struct ScalarTraits<uint8_t> {
818   static void output(const uint8_t &, void*, llvm::raw_ostream &);
819   static StringRef input(StringRef, void*, uint8_t &);
820   static bool mustQuote(StringRef) { return false; }
821 };
822
823 template<>
824 struct ScalarTraits<uint16_t> {
825   static void output(const uint16_t &, void*, llvm::raw_ostream &);
826   static StringRef input(StringRef, void*, uint16_t &);
827   static bool mustQuote(StringRef) { return false; }
828 };
829
830 template<>
831 struct ScalarTraits<uint32_t> {
832   static void output(const uint32_t &, void*, llvm::raw_ostream &);
833   static StringRef input(StringRef, void*, uint32_t &);
834   static bool mustQuote(StringRef) { return false; }
835 };
836
837 template<>
838 struct ScalarTraits<uint64_t> {
839   static void output(const uint64_t &, void*, llvm::raw_ostream &);
840   static StringRef input(StringRef, void*, uint64_t &);
841   static bool mustQuote(StringRef) { return false; }
842 };
843
844 template<>
845 struct ScalarTraits<int8_t> {
846   static void output(const int8_t &, void*, llvm::raw_ostream &);
847   static StringRef input(StringRef, void*, int8_t &);
848   static bool mustQuote(StringRef) { return false; }
849 };
850
851 template<>
852 struct ScalarTraits<int16_t> {
853   static void output(const int16_t &, void*, llvm::raw_ostream &);
854   static StringRef input(StringRef, void*, int16_t &);
855   static bool mustQuote(StringRef) { return false; }
856 };
857
858 template<>
859 struct ScalarTraits<int32_t> {
860   static void output(const int32_t &, void*, llvm::raw_ostream &);
861   static StringRef input(StringRef, void*, int32_t &);
862   static bool mustQuote(StringRef) { return false; }
863 };
864
865 template<>
866 struct ScalarTraits<int64_t> {
867   static void output(const int64_t &, void*, llvm::raw_ostream &);
868   static StringRef input(StringRef, void*, int64_t &);
869   static bool mustQuote(StringRef) { return false; }
870 };
871
872 template<>
873 struct ScalarTraits<float> {
874   static void output(const float &, void*, llvm::raw_ostream &);
875   static StringRef input(StringRef, void*, float &);
876   static bool mustQuote(StringRef) { return false; }
877 };
878
879 template<>
880 struct ScalarTraits<double> {
881   static void output(const double &, void*, llvm::raw_ostream &);
882   static StringRef input(StringRef, void*, double &);
883   static bool mustQuote(StringRef) { return false; }
884 };
885
886
887
888 // Utility for use within MappingTraits<>::mapping() method
889 // to [de]normalize an object for use with YAML conversion.
890 template <typename TNorm, typename TFinal>
891 struct MappingNormalization {
892   MappingNormalization(IO &i_o, TFinal &Obj)
893       : io(i_o), BufPtr(nullptr), Result(Obj) {
894     if ( io.outputting() ) {
895       BufPtr = new (&Buffer) TNorm(io, Obj);
896     }
897     else {
898       BufPtr = new (&Buffer) TNorm(io);
899     }
900   }
901
902   ~MappingNormalization() {
903     if ( ! io.outputting() ) {
904       Result = BufPtr->denormalize(io);
905     }
906     BufPtr->~TNorm();
907   }
908
909   TNorm* operator->() { return BufPtr; }
910
911 private:
912   typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
913
914   Storage       Buffer;
915   IO           &io;
916   TNorm        *BufPtr;
917   TFinal       &Result;
918 };
919
920
921
922 // Utility for use within MappingTraits<>::mapping() method
923 // to [de]normalize an object for use with YAML conversion.
924 template <typename TNorm, typename TFinal>
925 struct MappingNormalizationHeap {
926   MappingNormalizationHeap(IO &i_o, TFinal &Obj)
927     : io(i_o), BufPtr(NULL), Result(Obj) {
928     if ( io.outputting() ) {
929       BufPtr = new (&Buffer) TNorm(io, Obj);
930     }
931     else {
932       BufPtr = new TNorm(io);
933     }
934   }
935
936   ~MappingNormalizationHeap() {
937     if ( io.outputting() ) {
938       BufPtr->~TNorm();
939     }
940     else {
941       Result = BufPtr->denormalize(io);
942     }
943   }
944
945   TNorm* operator->() { return BufPtr; }
946
947 private:
948   typedef llvm::AlignedCharArrayUnion<TNorm> Storage;
949
950   Storage       Buffer;
951   IO           &io;
952   TNorm        *BufPtr;
953   TFinal       &Result;
954 };
955
956
957
958 ///
959 /// The Input class is used to parse a yaml document into in-memory structs
960 /// and vectors.
961 ///
962 /// It works by using YAMLParser to do a syntax parse of the entire yaml
963 /// document, then the Input class builds a graph of HNodes which wraps
964 /// each yaml Node.  The extra layer is buffering.  The low level yaml
965 /// parser only lets you look at each node once.  The buffering layer lets
966 /// you search and interate multiple times.  This is necessary because
967 /// the mapRequired() method calls may not be in the same order
968 /// as the keys in the document.
969 ///
970 class Input : public IO {
971 public:
972   // Construct a yaml Input object from a StringRef and optional
973   // user-data. The DiagHandler can be specified to provide
974   // alternative error reporting.
975   Input(StringRef InputContent,
976         void *Ctxt = nullptr,
977         SourceMgr::DiagHandlerTy DiagHandler = nullptr,
978         void *DiagHandlerCtxt = nullptr);
979   ~Input() override;
980
981   // Check if there was an syntax or semantic error during parsing.
982   std::error_code error();
983
984 private:
985   bool outputting() override;
986   bool mapTag(StringRef, bool) override;
987   void beginMapping() override;
988   void endMapping() override;
989   bool preflightKey(const char *, bool, bool, bool &, void *&) override;
990   void postflightKey(void *) override;
991   void beginFlowMapping() override;
992   void endFlowMapping() override;
993   unsigned beginSequence() override;
994   void endSequence() override;
995   bool preflightElement(unsigned index, void *&) override;
996   void postflightElement(void *) override;
997   unsigned beginFlowSequence() override;
998   bool preflightFlowElement(unsigned , void *&) override;
999   void postflightFlowElement(void *) override;
1000   void endFlowSequence() override;
1001   void beginEnumScalar() override;
1002   bool matchEnumScalar(const char*, bool) override;
1003   bool matchEnumFallback() override;
1004   void endEnumScalar() override;
1005   bool beginBitSetScalar(bool &) override;
1006   bool bitSetMatch(const char *, bool ) override;
1007   void endBitSetScalar() override;
1008   void scalarString(StringRef &, bool) override;
1009   void blockScalarString(StringRef &) override;
1010   void setError(const Twine &message) override;
1011   bool canElideEmptySequence() override;
1012
1013   class HNode {
1014     virtual void anchor();
1015   public:
1016     HNode(Node *n) : _node(n) { }
1017     virtual ~HNode() { }
1018     static inline bool classof(const HNode *) { return true; }
1019
1020     Node *_node;
1021   };
1022
1023   class EmptyHNode : public HNode {
1024     void anchor() override;
1025   public:
1026     EmptyHNode(Node *n) : HNode(n) { }
1027     static inline bool classof(const HNode *n) {
1028       return NullNode::classof(n->_node);
1029     }
1030     static inline bool classof(const EmptyHNode *) { return true; }
1031   };
1032
1033   class ScalarHNode : public HNode {
1034     void anchor() override;
1035   public:
1036     ScalarHNode(Node *n, StringRef s) : HNode(n), _value(s) { }
1037
1038     StringRef value() const { return _value; }
1039
1040     static inline bool classof(const HNode *n) {
1041       return ScalarNode::classof(n->_node) ||
1042              BlockScalarNode::classof(n->_node);
1043     }
1044     static inline bool classof(const ScalarHNode *) { return true; }
1045   protected:
1046     StringRef _value;
1047   };
1048
1049   class MapHNode : public HNode {
1050     void anchor() override;
1051
1052   public:
1053     MapHNode(Node *n) : HNode(n) { }
1054
1055     static inline bool classof(const HNode *n) {
1056       return MappingNode::classof(n->_node);
1057     }
1058     static inline bool classof(const MapHNode *) { return true; }
1059
1060     typedef llvm::StringMap<std::unique_ptr<HNode>> NameToNode;
1061
1062     bool isValidKey(StringRef key);
1063
1064     NameToNode                        Mapping;
1065     llvm::SmallVector<const char*, 6> ValidKeys;
1066   };
1067
1068   class SequenceHNode : public HNode {
1069     void anchor() override;
1070
1071   public:
1072     SequenceHNode(Node *n) : HNode(n) { }
1073
1074     static inline bool classof(const HNode *n) {
1075       return SequenceNode::classof(n->_node);
1076     }
1077     static inline bool classof(const SequenceHNode *) { return true; }
1078
1079     std::vector<std::unique_ptr<HNode>> Entries;
1080   };
1081
1082   std::unique_ptr<Input::HNode> createHNodes(Node *node);
1083   void setError(HNode *hnode, const Twine &message);
1084   void setError(Node *node, const Twine &message);
1085
1086
1087 public:
1088   // These are only used by operator>>. They could be private
1089   // if those templated things could be made friends.
1090   bool setCurrentDocument();
1091   bool nextDocument();
1092
1093   /// Returns the current node that's being parsed by the YAML Parser.
1094   const Node *getCurrentNode() const;
1095
1096 private:
1097   llvm::SourceMgr                     SrcMgr; // must be before Strm
1098   std::unique_ptr<llvm::yaml::Stream> Strm;
1099   std::unique_ptr<HNode>              TopNode;
1100   std::error_code                     EC;
1101   llvm::BumpPtrAllocator              StringAllocator;
1102   llvm::yaml::document_iterator       DocIterator;
1103   std::vector<bool>                   BitValuesUsed;
1104   HNode                              *CurrentNode;
1105   bool                                ScalarMatchFound;
1106 };
1107
1108
1109
1110
1111 ///
1112 /// The Output class is used to generate a yaml document from in-memory structs
1113 /// and vectors.
1114 ///
1115 class Output : public IO {
1116 public:
1117   Output(llvm::raw_ostream &, void *Ctxt=nullptr);
1118   ~Output() override;
1119
1120   bool outputting() override;
1121   bool mapTag(StringRef, bool) override;
1122   void beginMapping() override;
1123   void endMapping() override;
1124   bool preflightKey(const char *key, bool, bool, bool &, void *&) override;
1125   void postflightKey(void *) override;
1126   void beginFlowMapping() override;
1127   void endFlowMapping() override;
1128   unsigned beginSequence() override;
1129   void endSequence() override;
1130   bool preflightElement(unsigned, void *&) override;
1131   void postflightElement(void *) override;
1132   unsigned beginFlowSequence() override;
1133   bool preflightFlowElement(unsigned, void *&) override;
1134   void postflightFlowElement(void *) override;
1135   void endFlowSequence() override;
1136   void beginEnumScalar() override;
1137   bool matchEnumScalar(const char*, bool) override;
1138   bool matchEnumFallback() override;
1139   void endEnumScalar() override;
1140   bool beginBitSetScalar(bool &) override;
1141   bool bitSetMatch(const char *, bool ) override;
1142   void endBitSetScalar() override;
1143   void scalarString(StringRef &, bool) override;
1144   void blockScalarString(StringRef &) override;
1145   void setError(const Twine &message) override;
1146   bool canElideEmptySequence() override;
1147 public:
1148   // These are only used by operator<<. They could be private
1149   // if that templated operator could be made a friend.
1150   void beginDocuments();
1151   bool preflightDocument(unsigned);
1152   void postflightDocument();
1153   void endDocuments();
1154
1155 private:
1156   void output(StringRef s);
1157   void outputUpToEndOfLine(StringRef s);
1158   void newLineCheck();
1159   void outputNewLine();
1160   void paddedKey(StringRef key);
1161   void flowKey(StringRef Key);
1162
1163   enum InState {
1164     inSeq,
1165     inFlowSeq,
1166     inMapFirstKey,
1167     inMapOtherKey,
1168     inFlowMapFirstKey,
1169     inFlowMapOtherKey
1170   };
1171
1172   llvm::raw_ostream       &Out;
1173   SmallVector<InState, 8>  StateStack;
1174   int                      Column;
1175   int                      ColumnAtFlowStart;
1176   int                      ColumnAtMapFlowStart;
1177   bool                     NeedBitValueComma;
1178   bool                     NeedFlowSequenceComma;
1179   bool                     EnumerationMatchFound;
1180   bool                     NeedsNewLine;
1181 };
1182
1183
1184
1185
1186 /// YAML I/O does conversion based on types. But often native data types
1187 /// are just a typedef of built in intergral types (e.g. int).  But the C++
1188 /// type matching system sees through the typedef and all the typedefed types
1189 /// look like a built in type. This will cause the generic YAML I/O conversion
1190 /// to be used. To provide better control over the YAML conversion, you can
1191 /// use this macro instead of typedef.  It will create a class with one field
1192 /// and automatic conversion operators to and from the base type.
1193 /// Based on BOOST_STRONG_TYPEDEF
1194 #define LLVM_YAML_STRONG_TYPEDEF(_base, _type)                                 \
1195     struct _type {                                                             \
1196         _type() { }                                                            \
1197         _type(const _base v) : value(v) { }                                    \
1198         _type(const _type &v) : value(v.value) {}                              \
1199         _type &operator=(const _type &rhs) { value = rhs.value; return *this; }\
1200         _type &operator=(const _base &rhs) { value = rhs; return *this; }      \
1201         operator const _base & () const { return value; }                      \
1202         bool operator==(const _type &rhs) const { return value == rhs.value; } \
1203         bool operator==(const _base &rhs) const { return value == rhs; }       \
1204         bool operator<(const _type &rhs) const { return value < rhs.value; }   \
1205         _base value;                                                           \
1206     };
1207
1208
1209
1210 ///
1211 /// Use these types instead of uintXX_t in any mapping to have
1212 /// its yaml output formatted as hexadecimal.
1213 ///
1214 LLVM_YAML_STRONG_TYPEDEF(uint8_t, Hex8)
1215 LLVM_YAML_STRONG_TYPEDEF(uint16_t, Hex16)
1216 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Hex32)
1217 LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
1218
1219
1220 template<>
1221 struct ScalarTraits<Hex8> {
1222   static void output(const Hex8 &, void*, llvm::raw_ostream &);
1223   static StringRef input(StringRef, void*, Hex8 &);
1224   static bool mustQuote(StringRef) { return false; }
1225 };
1226
1227 template<>
1228 struct ScalarTraits<Hex16> {
1229   static void output(const Hex16 &, void*, llvm::raw_ostream &);
1230   static StringRef input(StringRef, void*, Hex16 &);
1231   static bool mustQuote(StringRef) { return false; }
1232 };
1233
1234 template<>
1235 struct ScalarTraits<Hex32> {
1236   static void output(const Hex32 &, void*, llvm::raw_ostream &);
1237   static StringRef input(StringRef, void*, Hex32 &);
1238   static bool mustQuote(StringRef) { return false; }
1239 };
1240
1241 template<>
1242 struct ScalarTraits<Hex64> {
1243   static void output(const Hex64 &, void*, llvm::raw_ostream &);
1244   static StringRef input(StringRef, void*, Hex64 &);
1245   static bool mustQuote(StringRef) { return false; }
1246 };
1247
1248
1249 // Define non-member operator>> so that Input can stream in a document list.
1250 template <typename T>
1251 inline
1252 typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
1253 operator>>(Input &yin, T &docList) {
1254   int i = 0;
1255   while ( yin.setCurrentDocument() ) {
1256     yamlize(yin, DocumentListTraits<T>::element(yin, docList, i), true);
1257     if ( yin.error() )
1258       return yin;
1259     yin.nextDocument();
1260     ++i;
1261   }
1262   return yin;
1263 }
1264
1265 // Define non-member operator>> so that Input can stream in a map as a document.
1266 template <typename T>
1267 inline
1268 typename std::enable_if<has_MappingTraits<T>::value, Input &>::type
1269 operator>>(Input &yin, T &docMap) {
1270   yin.setCurrentDocument();
1271   yamlize(yin, docMap, true);
1272   return yin;
1273 }
1274
1275 // Define non-member operator>> so that Input can stream in a sequence as
1276 // a document.
1277 template <typename T>
1278 inline
1279 typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
1280 operator>>(Input &yin, T &docSeq) {
1281   if (yin.setCurrentDocument())
1282     yamlize(yin, docSeq, true);
1283   return yin;
1284 }
1285
1286 // Define non-member operator>> so that Input can stream in a block scalar.
1287 template <typename T>
1288 inline
1289 typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
1290 operator>>(Input &In, T &Val) {
1291   if (In.setCurrentDocument())
1292     yamlize(In, Val, true);
1293   return In;
1294 }
1295
1296 // Provide better error message about types missing a trait specialization
1297 template <typename T>
1298 inline
1299 typename std::enable_if<missingTraits<T>::value, Input &>::type
1300 operator>>(Input &yin, T &docSeq) {
1301   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1302   return yin;
1303 }
1304
1305
1306 // Define non-member operator<< so that Output can stream out document list.
1307 template <typename T>
1308 inline
1309 typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
1310 operator<<(Output &yout, T &docList) {
1311   yout.beginDocuments();
1312   const size_t count = DocumentListTraits<T>::size(yout, docList);
1313   for(size_t i=0; i < count; ++i) {
1314     if ( yout.preflightDocument(i) ) {
1315       yamlize(yout, DocumentListTraits<T>::element(yout, docList, i), true);
1316       yout.postflightDocument();
1317     }
1318   }
1319   yout.endDocuments();
1320   return yout;
1321 }
1322
1323 // Define non-member operator<< so that Output can stream out a map.
1324 template <typename T>
1325 inline
1326 typename std::enable_if<has_MappingTraits<T>::value, Output &>::type
1327 operator<<(Output &yout, T &map) {
1328   yout.beginDocuments();
1329   if ( yout.preflightDocument(0) ) {
1330     yamlize(yout, map, true);
1331     yout.postflightDocument();
1332   }
1333   yout.endDocuments();
1334   return yout;
1335 }
1336
1337 // Define non-member operator<< so that Output can stream out a sequence.
1338 template <typename T>
1339 inline
1340 typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
1341 operator<<(Output &yout, T &seq) {
1342   yout.beginDocuments();
1343   if ( yout.preflightDocument(0) ) {
1344     yamlize(yout, seq, true);
1345     yout.postflightDocument();
1346   }
1347   yout.endDocuments();
1348   return yout;
1349 }
1350
1351 // Define non-member operator<< so that Output can stream out a block scalar.
1352 template <typename T>
1353 inline
1354 typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
1355 operator<<(Output &Out, T &Val) {
1356   Out.beginDocuments();
1357   if (Out.preflightDocument(0)) {
1358     yamlize(Out, Val, true);
1359     Out.postflightDocument();
1360   }
1361   Out.endDocuments();
1362   return Out;
1363 }
1364
1365 // Provide better error message about types missing a trait specialization
1366 template <typename T>
1367 inline
1368 typename std::enable_if<missingTraits<T>::value, Output &>::type
1369 operator<<(Output &yout, T &seq) {
1370   char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
1371   return yout;
1372 }
1373
1374
1375 } // namespace yaml
1376 } // namespace llvm
1377
1378
1379 /// Utility for declaring that a std::vector of a particular type
1380 /// should be considered a YAML sequence.
1381 #define LLVM_YAML_IS_SEQUENCE_VECTOR(_type)                                 \
1382   namespace llvm {                                                          \
1383   namespace yaml {                                                          \
1384     template<>                                                              \
1385     struct SequenceTraits< std::vector<_type> > {                           \
1386       static size_t size(IO &io, std::vector<_type> &seq) {                 \
1387         return seq.size();                                                  \
1388       }                                                                     \
1389       static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
1390         if ( index >= seq.size() )                                          \
1391           seq.resize(index+1);                                              \
1392         return seq[index];                                                  \
1393       }                                                                     \
1394     };                                                                      \
1395   }                                                                         \
1396   }
1397
1398 /// Utility for declaring that a std::vector of a particular type
1399 /// should be considered a YAML flow sequence.
1400 #define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(_type)                            \
1401   namespace llvm {                                                          \
1402   namespace yaml {                                                          \
1403     template<>                                                              \
1404     struct SequenceTraits< std::vector<_type> > {                           \
1405       static size_t size(IO &io, std::vector<_type> &seq) {                 \
1406         return seq.size();                                                  \
1407       }                                                                     \
1408       static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
1409         (void)flow; /* Remove this workaround after PR17897 is fixed */     \
1410         if ( index >= seq.size() )                                          \
1411           seq.resize(index+1);                                              \
1412         return seq[index];                                                  \
1413       }                                                                     \
1414       static const bool flow = true;                                        \
1415     };                                                                      \
1416   }                                                                         \
1417   }
1418
1419 /// Utility for declaring that a std::vector of a particular type
1420 /// should be considered a YAML document list.
1421 #define LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(_type)                            \
1422   namespace llvm {                                                          \
1423   namespace yaml {                                                          \
1424     template<>                                                              \
1425     struct DocumentListTraits< std::vector<_type> > {                       \
1426       static size_t size(IO &io, std::vector<_type> &seq) {                 \
1427         return seq.size();                                                  \
1428       }                                                                     \
1429       static _type& element(IO &io, std::vector<_type> &seq, size_t index) {\
1430         if ( index >= seq.size() )                                          \
1431           seq.resize(index+1);                                              \
1432         return seq[index];                                                  \
1433       }                                                                     \
1434     };                                                                      \
1435   }                                                                         \
1436   }
1437
1438
1439
1440 #endif // LLVM_SUPPORT_YAMLTRAITS_H