Home | History | Annotate | Download | only in Support
      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 }
   1694