Skip to content

Commit d04d8b4

Browse files
committed
[YAML] Fix incorrect dash output in nested sequences
1 parent 4a011ac commit d04d8b4

File tree

2 files changed

+119
-16
lines changed

2 files changed

+119
-16
lines changed

llvm/lib/Support/YAMLTraits.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -838,26 +838,40 @@ void Output::newLineCheck(bool EmptySequence) {
838838
return;
839839

840840
unsigned Indent = StateStack.size() - 1;
841-
bool OutputDash = false;
842-
843-
if (StateStack.back() == inSeqFirstElement ||
844-
StateStack.back() == inSeqOtherElement) {
845-
OutputDash = true;
846-
} else if ((StateStack.size() > 1) &&
847-
((StateStack.back() == inMapFirstKey) ||
848-
inFlowSeqAnyElement(StateStack.back()) ||
849-
(StateStack.back() == inFlowMapFirstKey)) &&
850-
inSeqAnyElement(StateStack[StateStack.size() - 2])) {
851-
--Indent;
852-
OutputDash = true;
841+
bool PossiblyNestedSeq = false;
842+
auto I = StateStack.rbegin(), E = StateStack.rend();
843+
844+
if (inSeqAnyElement(*I)) {
845+
PossiblyNestedSeq = true; // Not possibly but always.
846+
++Indent;
847+
} else if (*I == inMapFirstKey || *I == inFlowMapFirstKey ||
848+
inFlowSeqAnyElement(*I)) {
849+
PossiblyNestedSeq = true;
850+
++I; // Skip back().
853851
}
854852

855-
for (unsigned i = 0; i < Indent; ++i) {
856-
output(" ");
853+
unsigned OutputDashCount = 0;
854+
if (PossiblyNestedSeq) {
855+
// Count up consecutive inSeqFirstElement from the end, unless
856+
// inSeqFirstElement is the top of nested sequence.
857+
while (I != E) {
858+
// Don't count the top of nested sequence.
859+
if (!inSeqAnyElement(*I))
860+
break;
861+
862+
++OutputDashCount;
863+
864+
// Stop counting if consecutive inSeqFirstElement ends.
865+
if (*I++ != inSeqFirstElement)
866+
break;
867+
}
857868
}
858-
if (OutputDash) {
869+
870+
for (unsigned I = OutputDashCount; I < Indent; ++I)
871+
output(" ");
872+
873+
for (unsigned I = 0; I < OutputDashCount; ++I)
859874
output("- ");
860-
}
861875
}
862876

863877
void Output::paddedKey(StringRef key) {

llvm/unittests/Support/YAMLIOTest.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,95 @@ TEST(YAMLIO, TestReadWriteMySecondsSequence) {
15381538
}
15391539

15401540

1541+
//===----------------------------------------------------------------------===//
1542+
// Test nested sequence
1543+
//===----------------------------------------------------------------------===//
1544+
using NestedStringSeq1 = std::array<std::string, 2>;
1545+
using NestedStringSeq2 = std::array<NestedStringSeq1, 2>;
1546+
using NestedStringSeq3 = std::array<NestedStringSeq2, 2>;
1547+
1548+
LLVM_YAML_IS_SEQUENCE_VECTOR(NestedStringSeq1)
1549+
LLVM_YAML_IS_SEQUENCE_VECTOR(NestedStringSeq2)
1550+
1551+
struct MappedStringSeq3 {
1552+
NestedStringSeq3 Seq3;
1553+
};
1554+
1555+
template <> struct llvm::yaml::MappingTraits<MappedStringSeq3> {
1556+
static void mapping(IO &io, MappedStringSeq3 &seq) {
1557+
io.mapRequired("Seq3", seq.Seq3);
1558+
}
1559+
};
1560+
1561+
using NestedIntSeq1 = std::array<int, 2>;
1562+
using NestedIntSeq2 = std::array<NestedIntSeq1, 2>;
1563+
using NestedIntSeq3 = std::array<NestedIntSeq2, 2>;
1564+
1565+
LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq1)
1566+
LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq2)
1567+
LLVM_YAML_IS_SEQUENCE_VECTOR(NestedIntSeq3)
1568+
1569+
template <typename Ty> std::string ParseAndEmit(llvm::StringRef YAML) {
1570+
Ty seq3;
1571+
Input yin(YAML);
1572+
yin >> seq3;
1573+
std::string out;
1574+
llvm::raw_string_ostream ostr(out);
1575+
Output yout(ostr);
1576+
yout << seq3;
1577+
return out;
1578+
}
1579+
1580+
TEST(YAMLIO, TestNestedSequence) {
1581+
{
1582+
llvm::StringRef Seq3YAML(R"YAML(---
1583+
- - [ 1000, 1001 ]
1584+
- [ 1010, 1011 ]
1585+
- - [ 1100, 1101 ]
1586+
- [ 1110, 1111 ]
1587+
...
1588+
)YAML");
1589+
1590+
std::string out = ParseAndEmit<NestedIntSeq3>(Seq3YAML);
1591+
EXPECT_EQ(out, Seq3YAML);
1592+
}
1593+
1594+
{
1595+
llvm::StringRef Seq3YAML(R"YAML(---
1596+
- - - '000'
1597+
- '001'
1598+
- - '010'
1599+
- '011'
1600+
- - - '100'
1601+
- '101'
1602+
- - '110'
1603+
- '111'
1604+
...
1605+
)YAML");
1606+
1607+
std::string out = ParseAndEmit<NestedStringSeq3>(Seq3YAML);
1608+
EXPECT_EQ(out, Seq3YAML);
1609+
}
1610+
1611+
{
1612+
llvm::StringRef Seq3YAML(R"YAML(---
1613+
Seq3:
1614+
- - - '000'
1615+
- '001'
1616+
- - '010'
1617+
- '011'
1618+
- - - '100'
1619+
- '101'
1620+
- - '110'
1621+
- '111'
1622+
...
1623+
)YAML");
1624+
1625+
std::string out = ParseAndEmit<MappedStringSeq3>(Seq3YAML);
1626+
EXPECT_EQ(out, Seq3YAML);
1627+
}
1628+
}
1629+
15411630
//===----------------------------------------------------------------------===//
15421631
// Test dynamic typing
15431632
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)