Revert "YAMLIO: Fix string quoting logic." (r190469)
[oota-llvm.git] / unittests / Support / YAMLIOTest.cpp
index 68436f8a9f9b7895e48f0b18f89a894825be4207..43d8397d1ed0346ed8aff87701ab09cc2a96b43d 100644 (file)
@@ -202,7 +202,7 @@ TEST(YAMLIO, TestReadBuiltInTypes) {
   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);
@@ -227,12 +227,12 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) {
   {
     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;
@@ -240,7 +240,7 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) {
     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);
@@ -256,7 +256,7 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) {
     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);
@@ -268,7 +268,7 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) {
     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));
   }
 }
@@ -602,6 +602,12 @@ TEST(YAMLIO, TestReadWriteMyFlowSequence) {
     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"));
   }
 
   {
@@ -632,7 +638,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, TotalSeconds)
 
 typedef std::vector<TotalSeconds> SecondsSequence;
 
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TotalSeconds)
+LLVM_YAML_IS_SEQUENCE_VECTOR(TotalSeconds)
 
 
 namespace llvm {
@@ -745,7 +751,7 @@ struct KindAndFlags {
 
 typedef std::vector<KindAndFlags> KindAndFlagsSequence;
 
-LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(KindAndFlags)
+LLVM_YAML_IS_SEQUENCE_VECTOR(KindAndFlags)
 
 namespace llvm {
 namespace yaml {
@@ -776,11 +782,17 @@ 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;
+      }
     }
   };
 }
@@ -1285,3 +1297,66 @@ TEST(YAMLIO, TestReadBuiltInTypesHex64Error) {
   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());
+}