EXPECT_FALSE(yin.error());
EXPECT_TRUE(map.str.equals("hello there"));
EXPECT_EQ(map.u64, 5000000000ULL);
- EXPECT_EQ(map.u32, 4000000000);
+ EXPECT_EQ(map.u32, 4000000000U);
EXPECT_EQ(map.u16, 65000);
EXPECT_EQ(map.u8, 255);
EXPECT_EQ(map.b, false);
{
BuiltInTypes map;
map.str = "one two";
- map.u64 = 6000000000;
- map.u32 = 3000000000;
+ map.u64 = 6000000000ULL;
+ map.u32 = 3000000000U;
map.u16 = 50000;
map.u8 = 254;
map.b = true;
- map.s64 = -6000000000;
+ map.s64 = -6000000000LL;
map.s32 = -2000000000;
map.s16 = -32000;
map.s8 = -128;
map.d = -2.8625;
map.h8 = 254;
map.h16 = 50000;
- map.h32 = 3000000000;
+ map.h32 = 3000000000U;
map.h64 = 6000000000LL;
llvm::raw_string_ostream ostr(intermediate);
EXPECT_FALSE(yin.error());
EXPECT_TRUE(map.str.equals("one two"));
EXPECT_EQ(map.u64, 6000000000ULL);
- EXPECT_EQ(map.u32, 3000000000UL);
+ EXPECT_EQ(map.u32, 3000000000U);
EXPECT_EQ(map.u16, 50000);
EXPECT_EQ(map.u8, 254);
EXPECT_EQ(map.b, true);
EXPECT_EQ(map.d, -2.8625);
EXPECT_EQ(map.h8, Hex8(254));
EXPECT_EQ(map.h16, Hex16(50000));
- EXPECT_EQ(map.h32, Hex32(3000000000));
+ EXPECT_EQ(map.h32, Hex32(3000000000U));
EXPECT_EQ(map.h64, Hex64(6000000000LL));
}
}
llvm::raw_string_ostream ostr(intermediate);
Output yout(ostr);
yout << map;
+
+ // Verify sequences were written in flow style
+ ostr.flush();
+ llvm::StringRef flowOut(intermediate);
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("one, two"));
+ EXPECT_NE(llvm::StringRef::npos, flowOut.find("10, -30, 1024"));
}
{
typedef std::vector<TotalSeconds> SecondsSequence;
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TotalSeconds)
+LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
namespace llvm {
typedef std::vector<KindAndFlags> KindAndFlagsSequence;
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(KindAndFlags)
+LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
namespace llvm {
namespace yaml {
struct MappingTraits<KindAndFlags> {
static void mapping(IO &io, KindAndFlags& kf) {
io.mapRequired("kind", kf.kind);
- // type of flags field varies depending on kind field
- if ( kf.kind == kindA )
- io.mapRequired("flags", *((AFlags*)&kf.flags));
- else
- io.mapRequired("flags", *((BFlags*)&kf.flags));
+ // Type of "flags" field varies depending on "kind" field.
+ // Use memcpy here to avoid breaking strict aliasing rules.
+ if (kf.kind == kindA) {
+ AFlags aflags = static_cast<AFlags>(kf.flags);
+ io.mapRequired("flags", aflags);
+ kf.flags = aflags;
+ } else {
+ BFlags bflags = static_cast<BFlags>(kf.flags);
+ io.mapRequired("flags", bflags);
+ kf.flags = bflags;
+ }
}
};
}
EXPECT_TRUE(yin.error());
}
+struct OptionalTest {
+ std::vector<int> Numbers;
+};
+
+struct OptionalTestSeq {
+ std::vector<OptionalTest> Tests;
+};
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(OptionalTest)
+namespace llvm {
+namespace yaml {
+ template <>
+ struct MappingTraits<OptionalTest> {
+ static void mapping(IO& IO, OptionalTest &OT) {
+ IO.mapOptional("Numbers", OT.Numbers);
+ }
+ };
+
+ template <>
+ struct MappingTraits<OptionalTestSeq> {
+ static void mapping(IO &IO, OptionalTestSeq &OTS) {
+ IO.mapOptional("Tests", OTS.Tests);
+ }
+ };
+}
+}
+
+TEST(YAMLIO, SequenceElideTest) {
+ // Test that writing out a purely optional structure with its fields set to
+ // default followed by other data is properly read back in.
+ OptionalTestSeq Seq;
+ OptionalTest One, Two, Three, Four;
+ int N[] = {1, 2, 3};
+ Three.Numbers.assign(N, N + 3);
+ Seq.Tests.push_back(One);
+ Seq.Tests.push_back(Two);
+ Seq.Tests.push_back(Three);
+ Seq.Tests.push_back(Four);
+
+ std::string intermediate;
+ {
+ llvm::raw_string_ostream ostr(intermediate);
+ Output yout(ostr);
+ yout << Seq;
+ }
+
+ Input yin(intermediate);
+ OptionalTestSeq Seq2;
+ yin >> Seq2;
+
+ EXPECT_FALSE(yin.error());
+
+ EXPECT_EQ(4UL, Seq2.Tests.size());
+
+ EXPECT_TRUE(Seq2.Tests[0].Numbers.empty());
+ EXPECT_TRUE(Seq2.Tests[1].Numbers.empty());
+
+ EXPECT_EQ(1, Seq2.Tests[2].Numbers[0]);
+ EXPECT_EQ(2, Seq2.Tests[2].Numbers[1]);
+ EXPECT_EQ(3, Seq2.Tests[2].Numbers[2]);
+
+ EXPECT_TRUE(Seq2.Tests[3].Numbers.empty());
+}