[C++11] Use 'nullptr'.
[oota-llvm.git] / unittests / Support / YAMLIOTest.cpp
1 //===- unittest/Support/YAMLIOTest.cpp ------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/Support/Casting.h"
13 #include "llvm/Support/Format.h"
14 #include "llvm/Support/YAMLTraits.h"
15 #include "gtest/gtest.h"
16
17
18 using llvm::yaml::Input;
19 using llvm::yaml::Output;
20 using llvm::yaml::IO;
21 using llvm::yaml::MappingTraits;
22 using llvm::yaml::MappingNormalization;
23 using llvm::yaml::ScalarTraits;
24 using llvm::yaml::Hex8;
25 using llvm::yaml::Hex16;
26 using llvm::yaml::Hex32;
27 using llvm::yaml::Hex64;
28
29
30
31
32 static void suppressErrorMessages(const llvm::SMDiagnostic &, void *) {
33 }
34
35
36
37 //===----------------------------------------------------------------------===//
38 //  Test MappingTraits
39 //===----------------------------------------------------------------------===//
40
41 struct FooBar {
42   int foo;
43   int bar;
44 };
45 typedef std::vector<FooBar> FooBarSequence;
46
47 LLVM_YAML_IS_SEQUENCE_VECTOR(FooBar)
48
49
50 namespace llvm {
51 namespace yaml {
52   template <>
53   struct MappingTraits<FooBar> {
54     static void mapping(IO &io, FooBar& fb) {
55       io.mapRequired("foo",    fb.foo);
56       io.mapRequired("bar",    fb.bar);
57     }
58   };
59 }
60 }
61
62
63 //
64 // Test the reading of a yaml mapping
65 //
66 TEST(YAMLIO, TestMapRead) {
67   FooBar doc;
68   {
69     Input yin("---\nfoo:  3\nbar:  5\n...\n");
70     yin >> doc;
71
72     EXPECT_FALSE(yin.error());
73     EXPECT_EQ(doc.foo, 3);
74     EXPECT_EQ(doc.bar, 5);
75   }
76
77   {
78     Input yin("{foo: 3, bar: 5}");
79     yin >> doc;
80
81     EXPECT_FALSE(yin.error());
82     EXPECT_EQ(doc.foo, 3);
83     EXPECT_EQ(doc.bar, 5);
84   }
85 }
86
87 //
88 // Test the reading of a yaml sequence of mappings
89 //
90 TEST(YAMLIO, TestSequenceMapRead) {
91   FooBarSequence seq;
92   Input yin("---\n - foo:  3\n   bar:  5\n - foo:  7\n   bar:  9\n...\n");
93   yin >> seq;
94
95   EXPECT_FALSE(yin.error());
96   EXPECT_EQ(seq.size(), 2UL);
97   FooBar& map1 = seq[0];
98   FooBar& map2 = seq[1];
99   EXPECT_EQ(map1.foo, 3);
100   EXPECT_EQ(map1.bar, 5);
101   EXPECT_EQ(map2.foo, 7);
102   EXPECT_EQ(map2.bar, 9);
103 }
104
105
106 //
107 // Test writing then reading back a sequence of mappings
108 //
109 TEST(YAMLIO, TestSequenceMapWriteAndRead) {
110   std::string intermediate;
111   {
112     FooBar entry1;
113     entry1.foo = 10;
114     entry1.bar = -3;
115     FooBar entry2;
116     entry2.foo = 257;
117     entry2.bar = 0;
118     FooBarSequence seq;
119     seq.push_back(entry1);
120     seq.push_back(entry2);
121
122     llvm::raw_string_ostream ostr(intermediate);
123     Output yout(ostr);
124     yout << seq;
125   }
126
127   {
128     Input yin(intermediate);
129     FooBarSequence seq2;
130     yin >> seq2;
131
132     EXPECT_FALSE(yin.error());
133     EXPECT_EQ(seq2.size(), 2UL);
134     FooBar& map1 = seq2[0];
135     FooBar& map2 = seq2[1];
136     EXPECT_EQ(map1.foo, 10);
137     EXPECT_EQ(map1.bar, -3);
138     EXPECT_EQ(map2.foo, 257);
139     EXPECT_EQ(map2.bar, 0);
140   }
141 }
142
143
144 //===----------------------------------------------------------------------===//
145 //  Test built-in types
146 //===----------------------------------------------------------------------===//
147
148 struct BuiltInTypes {
149   llvm::StringRef str;
150   std::string stdstr;
151   uint64_t        u64;
152   uint32_t        u32;
153   uint16_t        u16;
154   uint8_t         u8;
155   bool            b;
156   int64_t         s64;
157   int32_t         s32;
158   int16_t         s16;
159   int8_t          s8;
160   float           f;
161   double          d;
162   Hex8            h8;
163   Hex16           h16;
164   Hex32           h32;
165   Hex64           h64;
166 };
167
168 namespace llvm {
169 namespace yaml {
170   template <>
171   struct MappingTraits<BuiltInTypes> {
172     static void mapping(IO &io, BuiltInTypes& bt) {
173       io.mapRequired("str",      bt.str);
174       io.mapRequired("stdstr",   bt.stdstr);
175       io.mapRequired("u64",      bt.u64);
176       io.mapRequired("u32",      bt.u32);
177       io.mapRequired("u16",      bt.u16);
178       io.mapRequired("u8",       bt.u8);
179       io.mapRequired("b",        bt.b);
180       io.mapRequired("s64",      bt.s64);
181       io.mapRequired("s32",      bt.s32);
182       io.mapRequired("s16",      bt.s16);
183       io.mapRequired("s8",       bt.s8);
184       io.mapRequired("f",        bt.f);
185       io.mapRequired("d",        bt.d);
186       io.mapRequired("h8",       bt.h8);
187       io.mapRequired("h16",      bt.h16);
188       io.mapRequired("h32",      bt.h32);
189       io.mapRequired("h64",      bt.h64);
190     }
191   };
192 }
193 }
194
195
196 //
197 // Test the reading of all built-in scalar conversions
198 //
199 TEST(YAMLIO, TestReadBuiltInTypes) {
200   BuiltInTypes map;
201   Input yin("---\n"
202             "str:      hello there\n"
203             "stdstr:   hello where?\n"
204             "u64:      5000000000\n"
205             "u32:      4000000000\n"
206             "u16:      65000\n"
207             "u8:       255\n"
208             "b:        false\n"
209             "s64:      -5000000000\n"
210             "s32:      -2000000000\n"
211             "s16:      -32000\n"
212             "s8:       -127\n"
213             "f:        137.125\n"
214             "d:        -2.8625\n"
215             "h8:       0xFF\n"
216             "h16:      0x8765\n"
217             "h32:      0xFEDCBA98\n"
218             "h64:      0xFEDCBA9876543210\n"
219            "...\n");
220   yin >> map;
221
222   EXPECT_FALSE(yin.error());
223   EXPECT_TRUE(map.str.equals("hello there"));
224   EXPECT_TRUE(map.stdstr == "hello where?");
225   EXPECT_EQ(map.u64, 5000000000ULL);
226   EXPECT_EQ(map.u32, 4000000000U);
227   EXPECT_EQ(map.u16, 65000);
228   EXPECT_EQ(map.u8,  255);
229   EXPECT_EQ(map.b,   false);
230   EXPECT_EQ(map.s64, -5000000000LL);
231   EXPECT_EQ(map.s32, -2000000000L);
232   EXPECT_EQ(map.s16, -32000);
233   EXPECT_EQ(map.s8,  -127);
234   EXPECT_EQ(map.f,   137.125);
235   EXPECT_EQ(map.d,   -2.8625);
236   EXPECT_EQ(map.h8,  Hex8(255));
237   EXPECT_EQ(map.h16, Hex16(0x8765));
238   EXPECT_EQ(map.h32, Hex32(0xFEDCBA98));
239   EXPECT_EQ(map.h64, Hex64(0xFEDCBA9876543210LL));
240 }
241
242
243 //
244 // Test writing then reading back all built-in scalar types
245 //
246 TEST(YAMLIO, TestReadWriteBuiltInTypes) {
247   std::string intermediate;
248   {
249     BuiltInTypes map;
250     map.str = "one two";
251     map.stdstr = "three four";
252     map.u64 = 6000000000ULL;
253     map.u32 = 3000000000U;
254     map.u16 = 50000;
255     map.u8  = 254;
256     map.b   = true;
257     map.s64 = -6000000000LL;
258     map.s32 = -2000000000;
259     map.s16 = -32000;
260     map.s8  = -128;
261     map.f   = 3.25;
262     map.d   = -2.8625;
263     map.h8  = 254;
264     map.h16 = 50000;
265     map.h32 = 3000000000U;
266     map.h64 = 6000000000LL;
267
268     llvm::raw_string_ostream ostr(intermediate);
269     Output yout(ostr);
270     yout << map;
271   }
272
273   {
274     Input yin(intermediate);
275     BuiltInTypes map;
276     yin >> map;
277
278     EXPECT_FALSE(yin.error());
279     EXPECT_TRUE(map.str.equals("one two"));
280     EXPECT_TRUE(map.stdstr == "three four");
281     EXPECT_EQ(map.u64,      6000000000ULL);
282     EXPECT_EQ(map.u32,      3000000000U);
283     EXPECT_EQ(map.u16,      50000);
284     EXPECT_EQ(map.u8,       254);
285     EXPECT_EQ(map.b,        true);
286     EXPECT_EQ(map.s64,      -6000000000LL);
287     EXPECT_EQ(map.s32,      -2000000000L);
288     EXPECT_EQ(map.s16,      -32000);
289     EXPECT_EQ(map.s8,       -128);
290     EXPECT_EQ(map.f,        3.25);
291     EXPECT_EQ(map.d,        -2.8625);
292     EXPECT_EQ(map.h8,       Hex8(254));
293     EXPECT_EQ(map.h16,      Hex16(50000));
294     EXPECT_EQ(map.h32,      Hex32(3000000000U));
295     EXPECT_EQ(map.h64,      Hex64(6000000000LL));
296   }
297 }
298
299 struct StringTypes {
300   llvm::StringRef str1;
301   llvm::StringRef str2;
302   llvm::StringRef str3;
303   llvm::StringRef str4;
304   llvm::StringRef str5;
305   llvm::StringRef str6;
306   llvm::StringRef str7;
307   llvm::StringRef str8;
308   llvm::StringRef str9;
309   llvm::StringRef str10;
310   llvm::StringRef str11;
311   std::string stdstr1;
312   std::string stdstr2;
313   std::string stdstr3;
314   std::string stdstr4;
315   std::string stdstr5;
316   std::string stdstr6;
317   std::string stdstr7;
318   std::string stdstr8;
319   std::string stdstr9;
320   std::string stdstr10;
321   std::string stdstr11;
322 };
323
324 namespace llvm {
325 namespace yaml {
326   template <>
327   struct MappingTraits<StringTypes> {
328     static void mapping(IO &io, StringTypes& st) {
329       io.mapRequired("str1",      st.str1);
330       io.mapRequired("str2",      st.str2);
331       io.mapRequired("str3",      st.str3);
332       io.mapRequired("str4",      st.str4);
333       io.mapRequired("str5",      st.str5);
334       io.mapRequired("str6",      st.str6);
335       io.mapRequired("str7",      st.str7);
336       io.mapRequired("str8",      st.str8);
337       io.mapRequired("str9",      st.str9);
338       io.mapRequired("str10",     st.str10);
339       io.mapRequired("str11",     st.str11);
340       io.mapRequired("stdstr1",   st.stdstr1);
341       io.mapRequired("stdstr2",   st.stdstr2);
342       io.mapRequired("stdstr3",   st.stdstr3);
343       io.mapRequired("stdstr4",   st.stdstr4);
344       io.mapRequired("stdstr5",   st.stdstr5);
345       io.mapRequired("stdstr6",   st.stdstr6);
346       io.mapRequired("stdstr7",   st.stdstr7);
347       io.mapRequired("stdstr8",   st.stdstr8);
348       io.mapRequired("stdstr9",   st.stdstr9);
349       io.mapRequired("stdstr10",  st.stdstr10);
350       io.mapRequired("stdstr11",  st.stdstr11);
351     }
352   };
353 }
354 }
355
356 TEST(YAMLIO, TestReadWriteStringTypes) {
357   std::string intermediate;
358   {
359     StringTypes map;
360     map.str1 = "'aaa";
361     map.str2 = "\"bbb";
362     map.str3 = "`ccc";
363     map.str4 = "@ddd";
364     map.str5 = "";
365     map.str6 = "0000000004000000";
366     map.str7 = "true";
367     map.str8 = "FALSE";
368     map.str9 = "~";
369     map.str10 = "0.2e20";
370     map.str11 = "0x30";
371     map.stdstr1 = "'eee";
372     map.stdstr2 = "\"fff";
373     map.stdstr3 = "`ggg";
374     map.stdstr4 = "@hhh";
375     map.stdstr5 = "";
376     map.stdstr6 = "0000000004000000";
377     map.stdstr7 = "true";
378     map.stdstr8 = "FALSE";
379     map.stdstr9 = "~";
380     map.stdstr10 = "0.2e20";
381     map.stdstr11 = "0x30";
382
383     llvm::raw_string_ostream ostr(intermediate);
384     Output yout(ostr);
385     yout << map;
386   }
387
388   llvm::StringRef flowOut(intermediate);
389   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'''aaa"));
390   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'\"bbb'"));
391   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'"));
392   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'"));
393   EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n"));
394   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0000000004000000'\n"));
395   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'true'\n"));
396   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'FALSE'\n"));
397   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'~'\n"));
398   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0.2e20'\n"));
399   EXPECT_NE(llvm::StringRef::npos, flowOut.find("'0x30'\n"));
400   EXPECT_NE(std::string::npos, flowOut.find("'''eee"));
401   EXPECT_NE(std::string::npos, flowOut.find("'\"fff'"));
402   EXPECT_NE(std::string::npos, flowOut.find("'`ggg'"));
403   EXPECT_NE(std::string::npos, flowOut.find("'@hhh'"));
404   EXPECT_NE(std::string::npos, flowOut.find("''\n"));
405   EXPECT_NE(std::string::npos, flowOut.find("'0000000004000000'\n"));
406
407   {
408     Input yin(intermediate);
409     StringTypes map;
410     yin >> map;
411
412     EXPECT_FALSE(yin.error());
413     EXPECT_TRUE(map.str1.equals("'aaa"));
414     EXPECT_TRUE(map.str2.equals("\"bbb"));
415     EXPECT_TRUE(map.str3.equals("`ccc"));
416     EXPECT_TRUE(map.str4.equals("@ddd"));
417     EXPECT_TRUE(map.str5.equals(""));
418     EXPECT_TRUE(map.str6.equals("0000000004000000"));
419     EXPECT_TRUE(map.stdstr1 == "'eee");
420     EXPECT_TRUE(map.stdstr2 == "\"fff");
421     EXPECT_TRUE(map.stdstr3 == "`ggg");
422     EXPECT_TRUE(map.stdstr4 == "@hhh");
423     EXPECT_TRUE(map.stdstr5 == "");
424     EXPECT_TRUE(map.stdstr6 == "0000000004000000");
425   }
426 }
427
428 //===----------------------------------------------------------------------===//
429 //  Test ScalarEnumerationTraits
430 //===----------------------------------------------------------------------===//
431
432 enum Colors {
433     cRed,
434     cBlue,
435     cGreen,
436     cYellow
437 };
438
439 struct ColorMap {
440   Colors      c1;
441   Colors      c2;
442   Colors      c3;
443   Colors      c4;
444   Colors      c5;
445   Colors      c6;
446 };
447
448 namespace llvm {
449 namespace yaml {
450   template <>
451   struct ScalarEnumerationTraits<Colors> {
452     static void enumeration(IO &io, Colors &value) {
453       io.enumCase(value, "red",   cRed);
454       io.enumCase(value, "blue",  cBlue);
455       io.enumCase(value, "green", cGreen);
456       io.enumCase(value, "yellow",cYellow);
457     }
458   };
459   template <>
460   struct MappingTraits<ColorMap> {
461     static void mapping(IO &io, ColorMap& c) {
462       io.mapRequired("c1", c.c1);
463       io.mapRequired("c2", c.c2);
464       io.mapRequired("c3", c.c3);
465       io.mapOptional("c4", c.c4, cBlue);   // supplies default
466       io.mapOptional("c5", c.c5, cYellow); // supplies default
467       io.mapOptional("c6", c.c6, cRed);    // supplies default
468     }
469   };
470 }
471 }
472
473
474 //
475 // Test reading enumerated scalars
476 //
477 TEST(YAMLIO, TestEnumRead) {
478   ColorMap map;
479   Input yin("---\n"
480             "c1:  blue\n"
481             "c2:  red\n"
482             "c3:  green\n"
483             "c5:  yellow\n"
484             "...\n");
485   yin >> map;
486
487   EXPECT_FALSE(yin.error());
488   EXPECT_EQ(cBlue,  map.c1);
489   EXPECT_EQ(cRed,   map.c2);
490   EXPECT_EQ(cGreen, map.c3);
491   EXPECT_EQ(cBlue,  map.c4);  // tests default
492   EXPECT_EQ(cYellow,map.c5);  // tests overridden
493   EXPECT_EQ(cRed,   map.c6);  // tests default
494 }
495
496
497
498 //===----------------------------------------------------------------------===//
499 //  Test ScalarBitSetTraits
500 //===----------------------------------------------------------------------===//
501
502 enum MyFlags {
503   flagNone    = 0,
504   flagBig     = 1 << 0,
505   flagFlat    = 1 << 1,
506   flagRound   = 1 << 2,
507   flagPointy  = 1 << 3
508 };
509 inline MyFlags operator|(MyFlags a, MyFlags b) {
510   return static_cast<MyFlags>(
511                       static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
512 }
513
514 struct FlagsMap {
515   MyFlags     f1;
516   MyFlags     f2;
517   MyFlags     f3;
518   MyFlags     f4;
519 };
520
521
522 namespace llvm {
523 namespace yaml {
524   template <>
525   struct ScalarBitSetTraits<MyFlags> {
526     static void bitset(IO &io, MyFlags &value) {
527       io.bitSetCase(value, "big",   flagBig);
528       io.bitSetCase(value, "flat",  flagFlat);
529       io.bitSetCase(value, "round", flagRound);
530       io.bitSetCase(value, "pointy",flagPointy);
531     }
532   };
533   template <>
534   struct MappingTraits<FlagsMap> {
535     static void mapping(IO &io, FlagsMap& c) {
536       io.mapRequired("f1", c.f1);
537       io.mapRequired("f2", c.f2);
538       io.mapRequired("f3", c.f3);
539       io.mapOptional("f4", c.f4, MyFlags(flagRound));
540      }
541   };
542 }
543 }
544
545
546 //
547 // Test reading flow sequence representing bit-mask values
548 //
549 TEST(YAMLIO, TestFlagsRead) {
550   FlagsMap map;
551   Input yin("---\n"
552             "f1:  [ big ]\n"
553             "f2:  [ round, flat ]\n"
554             "f3:  []\n"
555             "...\n");
556   yin >> map;
557
558   EXPECT_FALSE(yin.error());
559   EXPECT_EQ(flagBig,              map.f1);
560   EXPECT_EQ(flagRound|flagFlat,   map.f2);
561   EXPECT_EQ(flagNone,             map.f3);  // check empty set
562   EXPECT_EQ(flagRound,            map.f4);  // check optional key
563 }
564
565
566 //
567 // Test writing then reading back bit-mask values
568 //
569 TEST(YAMLIO, TestReadWriteFlags) {
570   std::string intermediate;
571   {
572     FlagsMap map;
573     map.f1 = flagBig;
574     map.f2 = flagRound | flagFlat;
575     map.f3 = flagNone;
576     map.f4 = flagNone;
577
578     llvm::raw_string_ostream ostr(intermediate);
579     Output yout(ostr);
580     yout << map;
581   }
582
583   {
584     Input yin(intermediate);
585     FlagsMap map2;
586     yin >> map2;
587
588     EXPECT_FALSE(yin.error());
589     EXPECT_EQ(flagBig,              map2.f1);
590     EXPECT_EQ(flagRound|flagFlat,   map2.f2);
591     EXPECT_EQ(flagNone,             map2.f3);
592     //EXPECT_EQ(flagRound,            map2.f4);  // check optional key
593   }
594 }
595
596
597
598 //===----------------------------------------------------------------------===//
599 //  Test ScalarTraits
600 //===----------------------------------------------------------------------===//
601
602 struct MyCustomType {
603   int length;
604   int width;
605 };
606
607 struct MyCustomTypeMap {
608   MyCustomType     f1;
609   MyCustomType     f2;
610   int              f3;
611 };
612
613
614 namespace llvm {
615 namespace yaml {
616   template <>
617   struct MappingTraits<MyCustomTypeMap> {
618     static void mapping(IO &io, MyCustomTypeMap& s) {
619       io.mapRequired("f1", s.f1);
620       io.mapRequired("f2", s.f2);
621       io.mapRequired("f3", s.f3);
622      }
623   };
624   // MyCustomType is formatted as a yaml scalar.  A value of
625   // {length=3, width=4} would be represented in yaml as "3 by 4".
626   template<>
627   struct ScalarTraits<MyCustomType> {
628     static void output(const MyCustomType &value, void* ctxt, llvm::raw_ostream &out) {
629       out << llvm::format("%d by %d", value.length, value.width);
630     }
631     static StringRef input(StringRef scalar, void* ctxt, MyCustomType &value) {
632       size_t byStart = scalar.find("by");
633       if ( byStart != StringRef::npos ) {
634         StringRef lenStr = scalar.slice(0, byStart);
635         lenStr = lenStr.rtrim();
636         if ( lenStr.getAsInteger(0, value.length) ) {
637           return "malformed length";
638         }
639         StringRef widthStr = scalar.drop_front(byStart+2);
640         widthStr = widthStr.ltrim();
641         if ( widthStr.getAsInteger(0, value.width) ) {
642           return "malformed width";
643         }
644         return StringRef();
645       }
646       else {
647           return "malformed by";
648       }
649     }
650     static bool mustQuote(StringRef) { return true; }
651   };
652 }
653 }
654
655
656 //
657 // Test writing then reading back custom values
658 //
659 TEST(YAMLIO, TestReadWriteMyCustomType) {
660   std::string intermediate;
661   {
662     MyCustomTypeMap map;
663     map.f1.length = 1;
664     map.f1.width  = 4;
665     map.f2.length = 100;
666     map.f2.width  = 400;
667     map.f3 = 10;
668
669     llvm::raw_string_ostream ostr(intermediate);
670     Output yout(ostr);
671     yout << map;
672   }
673
674   {
675     Input yin(intermediate);
676     MyCustomTypeMap map2;
677     yin >> map2;
678
679     EXPECT_FALSE(yin.error());
680     EXPECT_EQ(1,      map2.f1.length);
681     EXPECT_EQ(4,      map2.f1.width);
682     EXPECT_EQ(100,    map2.f2.length);
683     EXPECT_EQ(400,    map2.f2.width);
684     EXPECT_EQ(10,     map2.f3);
685   }
686 }
687
688
689 //===----------------------------------------------------------------------===//
690 //  Test flow sequences
691 //===----------------------------------------------------------------------===//
692
693 LLVM_YAML_STRONG_TYPEDEF(int, MyNumber)
694 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(MyNumber)
695 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(llvm::StringRef)
696
697 namespace llvm {
698 namespace yaml {
699   template<>
700   struct ScalarTraits<MyNumber> {
701     static void output(const MyNumber &value, void *, llvm::raw_ostream &out) {
702       out << value;
703     }
704
705     static StringRef input(StringRef scalar, void *, MyNumber &value) {
706       long long n;
707       if ( getAsSignedInteger(scalar, 0, n) )
708         return "invalid number";
709       value = n;
710       return StringRef();
711     }
712
713     static bool mustQuote(StringRef) { return false; }
714   };
715 }
716 }
717
718 struct NameAndNumbers {
719   llvm::StringRef               name;
720   std::vector<llvm::StringRef>  strings;
721   std::vector<MyNumber>         single;
722   std::vector<MyNumber>         numbers;
723 };
724
725 namespace llvm {
726 namespace yaml {
727   template <>
728   struct MappingTraits<NameAndNumbers> {
729     static void mapping(IO &io, NameAndNumbers& nn) {
730       io.mapRequired("name",     nn.name);
731       io.mapRequired("strings",  nn.strings);
732       io.mapRequired("single",   nn.single);
733       io.mapRequired("numbers",  nn.numbers);
734     }
735   };
736 }
737 }
738
739
740 //
741 // Test writing then reading back custom values
742 //
743 TEST(YAMLIO, TestReadWriteMyFlowSequence) {
744   std::string intermediate;
745   {
746     NameAndNumbers map;
747     map.name  = "hello";
748     map.strings.push_back(llvm::StringRef("one"));
749     map.strings.push_back(llvm::StringRef("two"));
750     map.single.push_back(1);
751     map.numbers.push_back(10);
752     map.numbers.push_back(-30);
753     map.numbers.push_back(1024);
754
755     llvm::raw_string_ostream ostr(intermediate);
756     Output yout(ostr);
757     yout << map;
758
759     // Verify sequences were written in flow style
760     ostr.flush();
761     llvm::StringRef flowOut(intermediate);
762     EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two"));
763     EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024"));
764   }
765
766   {
767     Input yin(intermediate);
768     NameAndNumbers map2;
769     yin >> map2;
770
771     EXPECT_FALSE(yin.error());
772     EXPECT_TRUE(map2.name.equals("hello"));
773     EXPECT_EQ(map2.strings.size(), 2UL);
774     EXPECT_TRUE(map2.strings[0].equals("one"));
775     EXPECT_TRUE(map2.strings[1].equals("two"));
776     EXPECT_EQ(map2.single.size(), 1UL);
777     EXPECT_EQ(1,       map2.single[0]);
778     EXPECT_EQ(map2.numbers.size(), 3UL);
779     EXPECT_EQ(10,      map2.numbers[0]);
780     EXPECT_EQ(-30,     map2.numbers[1]);
781     EXPECT_EQ(1024,    map2.numbers[2]);
782   }
783 }
784
785
786 //===----------------------------------------------------------------------===//
787 //  Test normalizing/denormalizing
788 //===----------------------------------------------------------------------===//
789
790 LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds)
791
792 typedef std::vector<TotalSeconds> SecondsSequence;
793
794 LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
795
796
797 namespace llvm {
798 namespace yaml {
799   template <>
800   struct MappingTraits<TotalSeconds> {
801
802     class NormalizedSeconds {
803     public:
804       NormalizedSeconds(IO &io)
805         : hours(0), minutes(0), seconds(0) {
806       }
807       NormalizedSeconds(IO &, TotalSeconds &secs)
808         : hours(secs/3600),
809           minutes((secs - (hours*3600))/60),
810           seconds(secs % 60) {
811       }
812       TotalSeconds denormalize(IO &) {
813         return TotalSeconds(hours*3600 + minutes*60 + seconds);
814       }
815
816       uint32_t     hours;
817       uint8_t      minutes;
818       uint8_t      seconds;
819     };
820
821     static void mapping(IO &io, TotalSeconds &secs) {
822       MappingNormalization<NormalizedSeconds, TotalSeconds> keys(io, secs);
823
824       io.mapOptional("hours",    keys->hours,    (uint32_t)0);
825       io.mapOptional("minutes",  keys->minutes,  (uint8_t)0);
826       io.mapRequired("seconds",  keys->seconds);
827     }
828   };
829 }
830 }
831
832
833 //
834 // Test the reading of a yaml sequence of mappings
835 //
836 TEST(YAMLIO, TestReadMySecondsSequence) {
837   SecondsSequence seq;
838   Input yin("---\n - hours:  1\n   seconds:  5\n - seconds:  59\n...\n");
839   yin >> seq;
840
841   EXPECT_FALSE(yin.error());
842   EXPECT_EQ(seq.size(), 2UL);
843   EXPECT_EQ(seq[0], 3605U);
844   EXPECT_EQ(seq[1], 59U);
845 }
846
847
848 //
849 // Test writing then reading back custom values
850 //
851 TEST(YAMLIO, TestReadWriteMySecondsSequence) {
852   std::string intermediate;
853   {
854     SecondsSequence seq;
855     seq.push_back(4000);
856     seq.push_back(500);
857     seq.push_back(59);
858
859     llvm::raw_string_ostream ostr(intermediate);
860     Output yout(ostr);
861     yout << seq;
862   }
863   {
864     Input yin(intermediate);
865     SecondsSequence seq2;
866     yin >> seq2;
867
868     EXPECT_FALSE(yin.error());
869     EXPECT_EQ(seq2.size(), 3UL);
870     EXPECT_EQ(seq2[0], 4000U);
871     EXPECT_EQ(seq2[1], 500U);
872     EXPECT_EQ(seq2[2], 59U);
873   }
874 }
875
876
877 //===----------------------------------------------------------------------===//
878 //  Test dynamic typing
879 //===----------------------------------------------------------------------===//
880
881 enum AFlags {
882     a1,
883     a2,
884     a3
885 };
886
887 enum BFlags {
888     b1,
889     b2,
890     b3
891 };
892
893 enum Kind {
894     kindA,
895     kindB
896 };
897
898 struct KindAndFlags {
899   KindAndFlags() : kind(kindA), flags(0) { }
900   KindAndFlags(Kind k, uint32_t f) : kind(k), flags(f) { }
901   Kind        kind;
902   uint32_t    flags;
903 };
904
905 typedef std::vector<KindAndFlags> KindAndFlagsSequence;
906
907 LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
908
909 namespace llvm {
910 namespace yaml {
911   template <>
912   struct ScalarEnumerationTraits<AFlags> {
913     static void enumeration(IO &io, AFlags &value) {
914       io.enumCase(value, "a1",  a1);
915       io.enumCase(value, "a2",  a2);
916       io.enumCase(value, "a3",  a3);
917     }
918   };
919   template <>
920   struct ScalarEnumerationTraits<BFlags> {
921     static void enumeration(IO &io, BFlags &value) {
922       io.enumCase(value, "b1",  b1);
923       io.enumCase(value, "b2",  b2);
924       io.enumCase(value, "b3",  b3);
925     }
926   };
927   template <>
928   struct ScalarEnumerationTraits<Kind> {
929     static void enumeration(IO &io, Kind &value) {
930       io.enumCase(value, "A",  kindA);
931       io.enumCase(value, "B",  kindB);
932     }
933   };
934   template <>
935   struct MappingTraits<KindAndFlags> {
936     static void mapping(IO &io, KindAndFlags& kf) {
937       io.mapRequired("kind",  kf.kind);
938       // Type of "flags" field varies depending on "kind" field.
939       // Use memcpy here to avoid breaking strict aliasing rules.
940       if (kf.kind == kindA) {
941         AFlags aflags = static_cast<AFlags>(kf.flags);
942         io.mapRequired("flags", aflags);
943         kf.flags = aflags;
944       } else {
945         BFlags bflags = static_cast<BFlags>(kf.flags);
946         io.mapRequired("flags", bflags);
947         kf.flags = bflags;
948       }
949     }
950   };
951 }
952 }
953
954
955 //
956 // Test the reading of a yaml sequence dynamic types
957 //
958 TEST(YAMLIO, TestReadKindAndFlagsSequence) {
959   KindAndFlagsSequence seq;
960   Input yin("---\n - kind:  A\n   flags:  a2\n - kind:  B\n   flags:  b1\n...\n");
961   yin >> seq;
962
963   EXPECT_FALSE(yin.error());
964   EXPECT_EQ(seq.size(), 2UL);
965   EXPECT_EQ(seq[0].kind,  kindA);
966   EXPECT_EQ(seq[0].flags, (uint32_t)a2);
967   EXPECT_EQ(seq[1].kind,  kindB);
968   EXPECT_EQ(seq[1].flags, (uint32_t)b1);
969 }
970
971 //
972 // Test writing then reading back dynamic types
973 //
974 TEST(YAMLIO, TestReadWriteKindAndFlagsSequence) {
975   std::string intermediate;
976   {
977     KindAndFlagsSequence seq;
978     seq.push_back(KindAndFlags(kindA,a1));
979     seq.push_back(KindAndFlags(kindB,b1));
980     seq.push_back(KindAndFlags(kindA,a2));
981     seq.push_back(KindAndFlags(kindB,b2));
982     seq.push_back(KindAndFlags(kindA,a3));
983
984     llvm::raw_string_ostream ostr(intermediate);
985     Output yout(ostr);
986     yout << seq;
987   }
988   {
989     Input yin(intermediate);
990     KindAndFlagsSequence seq2;
991     yin >> seq2;
992
993     EXPECT_FALSE(yin.error());
994     EXPECT_EQ(seq2.size(), 5UL);
995     EXPECT_EQ(seq2[0].kind,  kindA);
996     EXPECT_EQ(seq2[0].flags, (uint32_t)a1);
997     EXPECT_EQ(seq2[1].kind,  kindB);
998     EXPECT_EQ(seq2[1].flags, (uint32_t)b1);
999     EXPECT_EQ(seq2[2].kind,  kindA);
1000     EXPECT_EQ(seq2[2].flags, (uint32_t)a2);
1001     EXPECT_EQ(seq2[3].kind,  kindB);
1002     EXPECT_EQ(seq2[3].flags, (uint32_t)b2);
1003     EXPECT_EQ(seq2[4].kind,  kindA);
1004     EXPECT_EQ(seq2[4].flags, (uint32_t)a3);
1005   }
1006 }
1007
1008
1009 //===----------------------------------------------------------------------===//
1010 //  Test document list
1011 //===----------------------------------------------------------------------===//
1012
1013 struct FooBarMap {
1014   int foo;
1015   int bar;
1016 };
1017 typedef std::vector<FooBarMap> FooBarMapDocumentList;
1018
1019 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(FooBarMap)
1020
1021
1022 namespace llvm {
1023 namespace yaml {
1024   template <>
1025   struct MappingTraits<FooBarMap> {
1026     static void mapping(IO &io, FooBarMap& fb) {
1027       io.mapRequired("foo",    fb.foo);
1028       io.mapRequired("bar",    fb.bar);
1029     }
1030   };
1031 }
1032 }
1033
1034
1035 //
1036 // Test the reading of a yaml mapping
1037 //
1038 TEST(YAMLIO, TestDocRead) {
1039   FooBarMap doc;
1040   Input yin("---\nfoo:  3\nbar:  5\n...\n");
1041   yin >> doc;
1042
1043   EXPECT_FALSE(yin.error());
1044   EXPECT_EQ(doc.foo, 3);
1045   EXPECT_EQ(doc.bar,5);
1046 }
1047
1048
1049
1050 //
1051 // Test writing then reading back a sequence of mappings
1052 //
1053 TEST(YAMLIO, TestSequenceDocListWriteAndRead) {
1054   std::string intermediate;
1055   {
1056     FooBarMap doc1;
1057     doc1.foo = 10;
1058     doc1.bar = -3;
1059     FooBarMap doc2;
1060     doc2.foo = 257;
1061     doc2.bar = 0;
1062     std::vector<FooBarMap> docList;
1063     docList.push_back(doc1);
1064     docList.push_back(doc2);
1065
1066     llvm::raw_string_ostream ostr(intermediate);
1067     Output yout(ostr);
1068     yout << docList;
1069   }
1070
1071
1072   {
1073     Input yin(intermediate);
1074     std::vector<FooBarMap> docList2;
1075     yin >> docList2;
1076
1077     EXPECT_FALSE(yin.error());
1078     EXPECT_EQ(docList2.size(), 2UL);
1079     FooBarMap& map1 = docList2[0];
1080     FooBarMap& map2 = docList2[1];
1081     EXPECT_EQ(map1.foo, 10);
1082     EXPECT_EQ(map1.bar, -3);
1083     EXPECT_EQ(map2.foo, 257);
1084     EXPECT_EQ(map2.bar, 0);
1085   }
1086 }
1087
1088 //===----------------------------------------------------------------------===//
1089 //  Test document tags
1090 //===----------------------------------------------------------------------===//
1091
1092 struct MyDouble {
1093   MyDouble() : value(0.0) { }
1094   MyDouble(double x) : value(x) { }
1095   double value;
1096 };
1097
1098 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble)
1099
1100
1101 namespace llvm {
1102 namespace yaml {
1103   template <>
1104   struct MappingTraits<MyDouble> {
1105     static void mapping(IO &io, MyDouble &d) {
1106       if (io.mapTag("!decimal", true)) {
1107         mappingDecimal(io, d);
1108       } else if (io.mapTag("!fraction")) {
1109         mappingFraction(io, d);
1110       }
1111     }
1112     static void mappingDecimal(IO &io, MyDouble &d) {
1113       io.mapRequired("value", d.value);
1114     }
1115     static void mappingFraction(IO &io, MyDouble &d) {
1116         double num, denom;
1117         io.mapRequired("numerator",      num);
1118         io.mapRequired("denominator",    denom);
1119         // convert fraction to double
1120         d.value = num/denom;
1121     }
1122   };
1123  }
1124 }
1125
1126
1127 //
1128 // Test the reading of two different tagged yaml documents.
1129 //
1130 TEST(YAMLIO, TestTaggedDocuments) {
1131   std::vector<MyDouble> docList;
1132   Input yin("--- !decimal\nvalue:  3.0\n"
1133             "--- !fraction\nnumerator:  9.0\ndenominator:  2\n...\n");
1134   yin >> docList;
1135   EXPECT_FALSE(yin.error());
1136   EXPECT_EQ(docList.size(), 2UL);
1137   EXPECT_EQ(docList[0].value, 3.0);
1138   EXPECT_EQ(docList[1].value, 4.5);
1139 }
1140
1141
1142
1143 //
1144 // Test writing then reading back tagged documents
1145 //
1146 TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
1147   std::string intermediate;
1148   {
1149     MyDouble a(10.25);
1150     MyDouble b(-3.75);
1151     std::vector<MyDouble> docList;
1152     docList.push_back(a);
1153     docList.push_back(b);
1154
1155     llvm::raw_string_ostream ostr(intermediate);
1156     Output yout(ostr);
1157     yout << docList;
1158   }
1159
1160   {
1161     Input yin(intermediate);
1162     std::vector<MyDouble> docList2;
1163     yin >> docList2;
1164
1165     EXPECT_FALSE(yin.error());
1166     EXPECT_EQ(docList2.size(), 2UL);
1167     EXPECT_EQ(docList2[0].value, 10.25);
1168     EXPECT_EQ(docList2[1].value, -3.75);
1169   }
1170 }
1171
1172
1173 //===----------------------------------------------------------------------===//
1174 //  Test mapping validation
1175 //===----------------------------------------------------------------------===//
1176
1177 struct MyValidation {
1178   double value;
1179 };
1180
1181 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyValidation)
1182
1183 namespace llvm {
1184 namespace yaml {
1185   template <>
1186   struct MappingTraits<MyValidation> {
1187     static void mapping(IO &io, MyValidation &d) {
1188         io.mapRequired("value", d.value);
1189     }
1190     static StringRef validate(IO &io, MyValidation &d) {
1191         if (d.value < 0)
1192           return "negative value";
1193         return StringRef();
1194     }
1195   };
1196  }
1197 }
1198
1199
1200 //
1201 // Test that validate() is called and complains about the negative value.
1202 //
1203 TEST(YAMLIO, TestValidatingInput) {
1204   std::vector<MyValidation> docList;
1205   Input yin("--- \nvalue:  3.0\n"
1206             "--- \nvalue:  -1.0\n...\n",
1207             nullptr, suppressErrorMessages);
1208   yin >> docList;
1209   EXPECT_TRUE(!!yin.error());
1210 }
1211
1212
1213 //===----------------------------------------------------------------------===//
1214 //  Test error handling
1215 //===----------------------------------------------------------------------===//
1216
1217 //
1218 // Test error handling of unknown enumerated scalar
1219 //
1220 TEST(YAMLIO, TestColorsReadError) {
1221   ColorMap map;
1222   Input yin("---\n"
1223             "c1:  blue\n"
1224             "c2:  purple\n"
1225             "c3:  green\n"
1226             "...\n",
1227             /*Ctxt=*/nullptr,
1228             suppressErrorMessages);
1229   yin >> map;
1230   EXPECT_TRUE(!!yin.error());
1231 }
1232
1233
1234 //
1235 // Test error handling of flow sequence with unknown value
1236 //
1237 TEST(YAMLIO, TestFlagsReadError) {
1238   FlagsMap map;
1239   Input yin("---\n"
1240             "f1:  [ big ]\n"
1241             "f2:  [ round, hollow ]\n"
1242             "f3:  []\n"
1243             "...\n",
1244             /*Ctxt=*/nullptr,
1245             suppressErrorMessages);
1246   yin >> map;
1247
1248   EXPECT_TRUE(!!yin.error());
1249 }
1250
1251
1252 //
1253 // Test error handling reading built-in uint8_t type
1254 //
1255 LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t)
1256 TEST(YAMLIO, TestReadBuiltInTypesUint8Error) {
1257   std::vector<uint8_t> seq;
1258   Input yin("---\n"
1259             "- 255\n"
1260             "- 0\n"
1261             "- 257\n"
1262             "...\n",
1263             /*Ctxt=*/nullptr,
1264             suppressErrorMessages);
1265   yin >> seq;
1266
1267   EXPECT_TRUE(!!yin.error());
1268 }
1269
1270
1271 //
1272 // Test error handling reading built-in uint16_t type
1273 //
1274 LLVM_YAML_IS_SEQUENCE_VECTOR(uint16_t)
1275 TEST(YAMLIO, TestReadBuiltInTypesUint16Error) {
1276   std::vector<uint16_t> seq;
1277   Input yin("---\n"
1278             "- 65535\n"
1279             "- 0\n"
1280             "- 66000\n"
1281             "...\n",
1282             /*Ctxt=*/nullptr,
1283             suppressErrorMessages);
1284   yin >> seq;
1285
1286   EXPECT_TRUE(!!yin.error());
1287 }
1288
1289
1290 //
1291 // Test error handling reading built-in uint32_t type
1292 //
1293 LLVM_YAML_IS_SEQUENCE_VECTOR(uint32_t)
1294 TEST(YAMLIO, TestReadBuiltInTypesUint32Error) {
1295   std::vector<uint32_t> seq;
1296   Input yin("---\n"
1297             "- 4000000000\n"
1298             "- 0\n"
1299             "- 5000000000\n"
1300             "...\n",
1301             /*Ctxt=*/nullptr,
1302             suppressErrorMessages);
1303   yin >> seq;
1304
1305   EXPECT_TRUE(!!yin.error());
1306 }
1307
1308
1309 //
1310 // Test error handling reading built-in uint64_t type
1311 //
1312 LLVM_YAML_IS_SEQUENCE_VECTOR(uint64_t)
1313 TEST(YAMLIO, TestReadBuiltInTypesUint64Error) {
1314   std::vector<uint64_t> seq;
1315   Input yin("---\n"
1316             "- 18446744073709551615\n"
1317             "- 0\n"
1318             "- 19446744073709551615\n"
1319             "...\n",
1320             /*Ctxt=*/nullptr,
1321             suppressErrorMessages);
1322   yin >> seq;
1323
1324   EXPECT_TRUE(!!yin.error());
1325 }
1326
1327
1328 //
1329 // Test error handling reading built-in int8_t type
1330 //
1331 LLVM_YAML_IS_SEQUENCE_VECTOR(int8_t)
1332 TEST(YAMLIO, TestReadBuiltInTypesint8OverError) {
1333   std::vector<int8_t> seq;
1334   Input yin("---\n"
1335             "- -128\n"
1336             "- 0\n"
1337             "- 127\n"
1338             "- 128\n"
1339            "...\n",
1340             /*Ctxt=*/nullptr,
1341             suppressErrorMessages);
1342   yin >> seq;
1343
1344   EXPECT_TRUE(!!yin.error());
1345 }
1346
1347 //
1348 // Test error handling reading built-in int8_t type
1349 //
1350 TEST(YAMLIO, TestReadBuiltInTypesint8UnderError) {
1351   std::vector<int8_t> seq;
1352   Input yin("---\n"
1353             "- -128\n"
1354             "- 0\n"
1355             "- 127\n"
1356             "- -129\n"
1357             "...\n",
1358             /*Ctxt=*/nullptr,
1359             suppressErrorMessages);
1360   yin >> seq;
1361
1362   EXPECT_TRUE(!!yin.error());
1363 }
1364
1365
1366 //
1367 // Test error handling reading built-in int16_t type
1368 //
1369 LLVM_YAML_IS_SEQUENCE_VECTOR(int16_t)
1370 TEST(YAMLIO, TestReadBuiltInTypesint16UnderError) {
1371   std::vector<int16_t> seq;
1372   Input yin("---\n"
1373             "- 32767\n"
1374             "- 0\n"
1375             "- -32768\n"
1376             "- -32769\n"
1377             "...\n",
1378             /*Ctxt=*/nullptr,
1379             suppressErrorMessages);
1380   yin >> seq;
1381
1382   EXPECT_TRUE(!!yin.error());
1383 }
1384
1385
1386 //
1387 // Test error handling reading built-in int16_t type
1388 //
1389 TEST(YAMLIO, TestReadBuiltInTypesint16OverError) {
1390   std::vector<int16_t> seq;
1391   Input yin("---\n"
1392             "- 32767\n"
1393             "- 0\n"
1394             "- -32768\n"
1395             "- 32768\n"
1396             "...\n",
1397             /*Ctxt=*/nullptr,
1398             suppressErrorMessages);
1399   yin >> seq;
1400
1401   EXPECT_TRUE(!!yin.error());
1402 }
1403
1404
1405 //
1406 // Test error handling reading built-in int32_t type
1407 //
1408 LLVM_YAML_IS_SEQUENCE_VECTOR(int32_t)
1409 TEST(YAMLIO, TestReadBuiltInTypesint32UnderError) {
1410   std::vector<int32_t> seq;
1411   Input yin("---\n"
1412             "- 2147483647\n"
1413             "- 0\n"
1414             "- -2147483648\n"
1415             "- -2147483649\n"
1416             "...\n",
1417             /*Ctxt=*/nullptr,
1418             suppressErrorMessages);
1419   yin >> seq;
1420
1421   EXPECT_TRUE(!!yin.error());
1422 }
1423
1424 //
1425 // Test error handling reading built-in int32_t type
1426 //
1427 TEST(YAMLIO, TestReadBuiltInTypesint32OverError) {
1428   std::vector<int32_t> seq;
1429   Input yin("---\n"
1430             "- 2147483647\n"
1431             "- 0\n"
1432             "- -2147483648\n"
1433             "- 2147483649\n"
1434             "...\n",
1435             /*Ctxt=*/nullptr,
1436             suppressErrorMessages);
1437   yin >> seq;
1438
1439   EXPECT_TRUE(!!yin.error());
1440 }
1441
1442
1443 //
1444 // Test error handling reading built-in int64_t type
1445 //
1446 LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
1447 TEST(YAMLIO, TestReadBuiltInTypesint64UnderError) {
1448   std::vector<int64_t> seq;
1449   Input yin("---\n"
1450             "- -9223372036854775808\n"
1451             "- 0\n"
1452             "- 9223372036854775807\n"
1453             "- -9223372036854775809\n"
1454             "...\n",
1455             /*Ctxt=*/nullptr,
1456             suppressErrorMessages);
1457   yin >> seq;
1458
1459   EXPECT_TRUE(!!yin.error());
1460 }
1461
1462 //
1463 // Test error handling reading built-in int64_t type
1464 //
1465 TEST(YAMLIO, TestReadBuiltInTypesint64OverError) {
1466   std::vector<int64_t> seq;
1467   Input yin("---\n"
1468             "- -9223372036854775808\n"
1469             "- 0\n"
1470             "- 9223372036854775807\n"
1471             "- 9223372036854775809\n"
1472             "...\n",
1473             /*Ctxt=*/nullptr,
1474             suppressErrorMessages);
1475   yin >> seq;
1476
1477   EXPECT_TRUE(!!yin.error());
1478 }
1479
1480 //
1481 // Test error handling reading built-in float type
1482 //
1483 LLVM_YAML_IS_SEQUENCE_VECTOR(float)
1484 TEST(YAMLIO, TestReadBuiltInTypesFloatError) {
1485   std::vector<float> seq;
1486   Input yin("---\n"
1487             "- 0.0\n"
1488             "- 1000.1\n"
1489             "- -123.456\n"
1490             "- 1.2.3\n"
1491             "...\n",
1492             /*Ctxt=*/nullptr,
1493             suppressErrorMessages);
1494   yin >> seq;
1495
1496   EXPECT_TRUE(!!yin.error());
1497 }
1498
1499 //
1500 // Test error handling reading built-in float type
1501 //
1502 LLVM_YAML_IS_SEQUENCE_VECTOR(double)
1503 TEST(YAMLIO, TestReadBuiltInTypesDoubleError) {
1504   std::vector<double> seq;
1505   Input yin("---\n"
1506             "- 0.0\n"
1507             "- 1000.1\n"
1508             "- -123.456\n"
1509             "- 1.2.3\n"
1510             "...\n",
1511             /*Ctxt=*/nullptr,
1512             suppressErrorMessages);
1513   yin >> seq;
1514
1515   EXPECT_TRUE(!!yin.error());
1516 }
1517
1518 //
1519 // Test error handling reading built-in Hex8 type
1520 //
1521 LLVM_YAML_IS_SEQUENCE_VECTOR(Hex8)
1522 TEST(YAMLIO, TestReadBuiltInTypesHex8Error) {
1523   std::vector<Hex8> seq;
1524   Input yin("---\n"
1525             "- 0x12\n"
1526             "- 0xFE\n"
1527             "- 0x123\n"
1528             "...\n",
1529             /*Ctxt=*/nullptr,
1530             suppressErrorMessages);
1531   yin >> seq;
1532
1533   EXPECT_TRUE(!!yin.error());
1534 }
1535
1536
1537 //
1538 // Test error handling reading built-in Hex16 type
1539 //
1540 LLVM_YAML_IS_SEQUENCE_VECTOR(Hex16)
1541 TEST(YAMLIO, TestReadBuiltInTypesHex16Error) {
1542   std::vector<Hex16> seq;
1543   Input yin("---\n"
1544             "- 0x0012\n"
1545             "- 0xFEFF\n"
1546             "- 0x12345\n"
1547             "...\n",
1548             /*Ctxt=*/nullptr,
1549             suppressErrorMessages);
1550   yin >> seq;
1551
1552   EXPECT_TRUE(!!yin.error());
1553 }
1554
1555 //
1556 // Test error handling reading built-in Hex32 type
1557 //
1558 LLVM_YAML_IS_SEQUENCE_VECTOR(Hex32)
1559 TEST(YAMLIO, TestReadBuiltInTypesHex32Error) {
1560   std::vector<Hex32> seq;
1561   Input yin("---\n"
1562             "- 0x0012\n"
1563             "- 0xFEFF0000\n"
1564             "- 0x1234556789\n"
1565             "...\n",
1566             /*Ctxt=*/nullptr,
1567             suppressErrorMessages);
1568   yin >> seq;
1569
1570   EXPECT_TRUE(!!yin.error());
1571 }
1572
1573 //
1574 // Test error handling reading built-in Hex64 type
1575 //
1576 LLVM_YAML_IS_SEQUENCE_VECTOR(Hex64)
1577 TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
1578   std::vector<Hex64> seq;
1579   Input yin("---\n"
1580             "- 0x0012\n"
1581             "- 0xFFEEDDCCBBAA9988\n"
1582             "- 0x12345567890ABCDEF0\n"
1583             "...\n",
1584             /*Ctxt=*/nullptr,
1585             suppressErrorMessages);
1586   yin >> seq;
1587
1588   EXPECT_TRUE(!!yin.error());
1589 }
1590
1591 TEST(YAMLIO, TestMalformedMapFailsGracefully) {
1592   FooBar doc;
1593   {
1594     // We pass the suppressErrorMessages handler to handle the error
1595     // message generated in the constructor of Input.
1596     Input yin("{foo:3, bar: 5}", /*Ctxt=*/nullptr, suppressErrorMessages);
1597     yin >> doc;
1598     EXPECT_TRUE(!!yin.error());
1599   }
1600
1601   {
1602     Input yin("---\nfoo:3\nbar: 5\n...\n", /*Ctxt=*/nullptr, suppressErrorMessages);
1603     yin >> doc;
1604     EXPECT_TRUE(!!yin.error());
1605   }
1606 }
1607
1608 struct OptionalTest {
1609   std::vector<int> Numbers;
1610 };
1611
1612 struct OptionalTestSeq {
1613   std::vector<OptionalTest> Tests;
1614 };
1615
1616 LLVM_YAML_IS_SEQUENCE_VECTOR(OptionalTest)
1617 namespace llvm {
1618 namespace yaml {
1619   template <>
1620   struct MappingTraits<OptionalTest> {
1621     static void mapping(IO& IO, OptionalTest &OT) {
1622       IO.mapOptional("Numbers", OT.Numbers);
1623     }
1624   };
1625
1626   template <>
1627   struct MappingTraits<OptionalTestSeq> {
1628     static void mapping(IO &IO, OptionalTestSeq &OTS) {
1629       IO.mapOptional("Tests", OTS.Tests);
1630     }
1631   };
1632 }
1633 }
1634
1635 TEST(YAMLIO, SequenceElideTest) {
1636   // Test that writing out a purely optional structure with its fields set to
1637   // default followed by other data is properly read back in.
1638   OptionalTestSeq Seq;
1639   OptionalTest One, Two, Three, Four;
1640   int N[] = {1, 2, 3};
1641   Three.Numbers.assign(N, N + 3);
1642   Seq.Tests.push_back(One);
1643   Seq.Tests.push_back(Two);
1644   Seq.Tests.push_back(Three);
1645   Seq.Tests.push_back(Four);
1646
1647   std::string intermediate;
1648   {
1649     llvm::raw_string_ostream ostr(intermediate);
1650     Output yout(ostr);
1651     yout << Seq;
1652   }
1653
1654   Input yin(intermediate);
1655   OptionalTestSeq Seq2;
1656   yin >> Seq2;
1657
1658   EXPECT_FALSE(yin.error());
1659
1660   EXPECT_EQ(4UL, Seq2.Tests.size());
1661
1662   EXPECT_TRUE(Seq2.Tests[0].Numbers.empty());
1663   EXPECT_TRUE(Seq2.Tests[1].Numbers.empty());
1664
1665   EXPECT_EQ(1, Seq2.Tests[2].Numbers[0]);
1666   EXPECT_EQ(2, Seq2.Tests[2].Numbers[1]);
1667   EXPECT_EQ(3, Seq2.Tests[2].Numbers[2]);
1668
1669   EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
1670 }
1671
1672 TEST(YAMLIO, TestEmptyStringFailsForMapWithRequiredFields) {
1673   FooBar doc;
1674   Input yin("");
1675   yin >> doc;
1676   EXPECT_TRUE(!!yin.error());
1677 }
1678
1679 TEST(YAMLIO, TestEmptyStringSucceedsForMapWithOptionalFields) {
1680   OptionalTest doc;
1681   Input yin("");
1682   yin >> doc;
1683   EXPECT_FALSE(yin.error());
1684 }
1685
1686 TEST(YAMLIO, TestEmptyStringSucceedsForSequence) {
1687   std::vector<uint8_t> seq;
1688   Input yin("", /*Ctxt=*/nullptr, suppressErrorMessages);
1689   yin >> seq;
1690
1691   EXPECT_FALSE(yin.error());
1692   EXPECT_TRUE(seq.empty());
1693 }