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