[llvm] [YAML] Fix incorrect dash output in nested sequences (PR #116488)

NAKAMURA Takumi via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 20 23:17:43 PST 2024


https://github.com/chapuni updated https://github.com/llvm/llvm-project/pull/116488

>From d04d8b4ca279eb7570b1baca8aae0c57ae7824f1 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 17 Nov 2024 00:25:24 +0900
Subject: [PATCH 1/3] [YAML] Fix incorrect dash output in nested sequences

---
 llvm/lib/Support/YAMLTraits.cpp       | 46 +++++++++-----
 llvm/unittests/Support/YAMLIOTest.cpp | 89 +++++++++++++++++++++++++++
 2 files changed, 119 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp
index 56b557646100b1..0d694d5b9d45b5 100644
--- a/llvm/lib/Support/YAMLTraits.cpp
+++ b/llvm/lib/Support/YAMLTraits.cpp
@@ -838,26 +838,40 @@ void Output::newLineCheck(bool EmptySequence) {
     return;
 
   unsigned Indent = StateStack.size() - 1;
-  bool OutputDash = false;
-
-  if (StateStack.back() == inSeqFirstElement ||
-      StateStack.back() == inSeqOtherElement) {
-    OutputDash = true;
-  } else if ((StateStack.size() > 1) &&
-             ((StateStack.back() == inMapFirstKey) ||
-              inFlowSeqAnyElement(StateStack.back()) ||
-              (StateStack.back() == inFlowMapFirstKey)) &&
-             inSeqAnyElement(StateStack[StateStack.size() - 2])) {
-    --Indent;
-    OutputDash = true;
+  bool PossiblyNestedSeq = false;
+  auto I = StateStack.rbegin(), E = StateStack.rend();
+
+  if (inSeqAnyElement(*I)) {
+    PossiblyNestedSeq = true; // Not possibly but always.
+    ++Indent;
+  } else if (*I == inMapFirstKey || *I == inFlowMapFirstKey ||
+             inFlowSeqAnyElement(*I)) {
+    PossiblyNestedSeq = true;
+    ++I; // Skip back().
   }
 
-  for (unsigned i = 0; i < Indent; ++i) {
-    output("  ");
+  unsigned OutputDashCount = 0;
+  if (PossiblyNestedSeq) {
+    // Count up consecutive inSeqFirstElement from the end, unless
+    // inSeqFirstElement is the top of nested sequence.
+    while (I != E) {
+      // Don't count the top of nested sequence.
+      if (!inSeqAnyElement(*I))
+        break;
+
+      ++OutputDashCount;
+
+      // Stop counting if consecutive inSeqFirstElement ends.
+      if (*I++ != inSeqFirstElement)
+        break;
+    }
   }
-  if (OutputDash) {
+
+  for (unsigned I = OutputDashCount; I < Indent; ++I)
+    output("  ");
+
+  for (unsigned I = 0; I < OutputDashCount; ++I)
     output("- ");
-  }
 }
 
 void Output::paddedKey(StringRef key) {
diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp
index e10fe099a30adb..be592559e03cda 100644
--- a/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/llvm/unittests/Support/YAMLIOTest.cpp
@@ -1538,6 +1538,95 @@ TEST(YAMLIO, TestReadWriteMySecondsSequence) {
 }
 
 
+//===----------------------------------------------------------------------===//
+//  Test nested sequence
+//===----------------------------------------------------------------------===//
+using NestedStringSeq1 = std::array<std::string, 2>;
+using NestedStringSeq2 = std::array<NestedStringSeq1, 2>;
+using NestedStringSeq3 = std::array<NestedStringSeq2, 2>;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(NestedStringSeq1)
+LLVM_YAML_IS_SEQUENCE_VECTOR(NestedStringSeq2)
+
+struct MappedStringSeq3 {
+  NestedStringSeq3 Seq3;
+};
+
+template <> struct llvm::yaml::MappingTraits<MappedStringSeq3> {
+  static void mapping(IO &io, MappedStringSeq3 &seq) {
+    io.mapRequired("Seq3", seq.Seq3);
+  }
+};
+
+using NestedIntSeq1 = std::array<int, 2>;
+using NestedIntSeq2 = std::array<NestedIntSeq1, 2>;
+using NestedIntSeq3 = std::array<NestedIntSeq2, 2>;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq1)
+LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq2)
+LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq3)
+
+template <typename Ty> std::string ParseAndEmit(llvm::StringRef YAML) {
+  Ty seq3;
+  Input yin(YAML);
+  yin >> seq3;
+  std::string out;
+  llvm::raw_string_ostream ostr(out);
+  Output yout(ostr);
+  yout << seq3;
+  return out;
+}
+
+TEST(YAMLIO, TestNestedSequence) {
+  {
+    llvm::StringRef Seq3YAML(R"YAML(---
+- - [ 1000, 1001 ]
+  - [ 1010, 1011 ]
+- - [ 1100, 1101 ]
+  - [ 1110, 1111 ]
+...
+)YAML");
+
+    std::string out = ParseAndEmit<NestedIntSeq3>(Seq3YAML);
+    EXPECT_EQ(out, Seq3YAML);
+  }
+
+  {
+    llvm::StringRef Seq3YAML(R"YAML(---
+- - - '000'
+    - '001'
+  - - '010'
+    - '011'
+- - - '100'
+    - '101'
+  - - '110'
+    - '111'
+...
+)YAML");
+
+    std::string out = ParseAndEmit<NestedStringSeq3>(Seq3YAML);
+    EXPECT_EQ(out, Seq3YAML);
+  }
+
+  {
+    llvm::StringRef Seq3YAML(R"YAML(---
+Seq3:
+  - - - '000'
+      - '001'
+    - - '010'
+      - '011'
+  - - - '100'
+      - '101'
+    - - '110'
+      - '111'
+...
+)YAML");
+
+    std::string out = ParseAndEmit<MappedStringSeq3>(Seq3YAML);
+    EXPECT_EQ(out, Seq3YAML);
+  }
+}
+
 //===----------------------------------------------------------------------===//
 //  Test dynamic typing
 //===----------------------------------------------------------------------===//

>From 202d0ee02594447a4d955362e901a6738284afd2 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Sun, 17 Nov 2024 00:51:43 +0900
Subject: [PATCH 2/3] Reformat

---
 llvm/unittests/Support/YAMLIOTest.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp
index be592559e03cda..16b90fbb7a333b 100644
--- a/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/llvm/unittests/Support/YAMLIOTest.cpp
@@ -1537,7 +1537,6 @@ TEST(YAMLIO, TestReadWriteMySecondsSequence) {
   }
 }
 
-
 //===----------------------------------------------------------------------===//
 //  Test nested sequence
 //===----------------------------------------------------------------------===//

>From 44496aadfb67a0901c961d06fc9c4f93fa1224a1 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Thu, 21 Nov 2024 16:13:04 +0900
Subject: [PATCH 3/3] Little tweaks. Use other vetor types, not only
 std::array.

---
 llvm/unittests/Support/YAMLIOTest.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp
index 089ed962dcdee3..c0e9c57a77f193 100644
--- a/llvm/unittests/Support/YAMLIOTest.cpp
+++ b/llvm/unittests/Support/YAMLIOTest.cpp
@@ -1540,9 +1540,9 @@ TEST(YAMLIO, TestReadWriteMySecondsSequence) {
 //===----------------------------------------------------------------------===//
 //  Test nested sequence
 //===----------------------------------------------------------------------===//
-using NestedStringSeq1 = std::array<std::string, 2>;
+using NestedStringSeq1 = llvm::SmallVector<std::string, 2>;
 using NestedStringSeq2 = std::array<NestedStringSeq1, 2>;
-using NestedStringSeq3 = std::array<NestedStringSeq2, 2>;
+using NestedStringSeq3 = std::vector<NestedStringSeq2>;
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(NestedStringSeq1)
 LLVM_YAML_IS_SEQUENCE_VECTOR(NestedStringSeq2)
@@ -1563,7 +1563,6 @@ using NestedIntSeq3 = std::array<NestedIntSeq2, 2>;
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq1)
 LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq2)
-LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq3)
 
 template <typename Ty> std::string ParseAndEmit(llvm::StringRef YAML) {
   Ty seq3;



More information about the llvm-commits mailing list