1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[YAML I/O] Fix bug in emission of empty sequence

Don't emit an output dash for an empty sequence. Take emitting a vector
of strings for example:

  std::vector<std::string> Strings = {"foo", "bar"};
  LLVM_YAML_IS_SEQUENCE_VECTOR(std::string)
  yout << Strings;

This emits the following YAML document.

  ---
  - foo
  - bar
  ...

When the vector is empty, this generates the following result:

  ---
  - []
  ...

Although this is valid YAML, it does not match what we meant to emit.
The result is a one-element sequence consisting of an empty list.
Indeed, if we were to try to read this again we get an error:

  YAML:2:4: error: not a mapping
  - []

The problem is the output dash before the empty list. The correct output
would be:

  ---
  []
  ...

This patch fixes that by not emitting the output dash for an empty
sequence.

Differential revision: https://reviews.llvm.org/D95280
This commit is contained in:
Jonas Devlieghere 2021-01-25 13:02:20 -08:00
parent b139438d21
commit ba9adaa9dd
3 changed files with 21 additions and 11 deletions

View File

@ -1586,7 +1586,7 @@ public:
private: private:
void output(StringRef s); void output(StringRef s);
void outputUpToEndOfLine(StringRef s); void outputUpToEndOfLine(StringRef s);
void newLineCheck(); void newLineCheck(bool EmptySequence = false);
void outputNewLine(); void outputNewLine();
void paddedKey(StringRef key); void paddedKey(StringRef key);
void flowKey(StringRef Key); void flowKey(StringRef Key);

View File

@ -592,7 +592,7 @@ void Output::endSequence() {
// If we did not emit anything, we should explicitly emit an empty sequence // If we did not emit anything, we should explicitly emit an empty sequence
if (StateStack.back() == inSeqFirstElement) { if (StateStack.back() == inSeqFirstElement) {
Padding = PaddingBeforeContainer; Padding = PaddingBeforeContainer;
newLineCheck(); newLineCheck(/*EmptySequence=*/true);
output("[]"); output("[]");
Padding = "\n"; Padding = "\n";
} }
@ -798,7 +798,7 @@ void Output::outputNewLine() {
// if seq in middle, use "- " if firstKey, else use " " // if seq in middle, use "- " if firstKey, else use " "
// //
void Output::newLineCheck() { void Output::newLineCheck(bool EmptySequence) {
if (Padding != "\n") { if (Padding != "\n") {
output(Padding); output(Padding);
Padding = {}; Padding = {};
@ -807,7 +807,7 @@ void Output::newLineCheck() {
outputNewLine(); outputNewLine();
Padding = {}; Padding = {};
if (StateStack.size() == 0) if (StateStack.size() == 0 || EmptySequence)
return; return;
unsigned Indent = StateStack.size() - 1; unsigned Indent = StateStack.size() - 1;
@ -831,7 +831,6 @@ void Output::newLineCheck() {
if (OutputDash) { if (OutputDash) {
output("- "); output("- ");
} }
} }
void Output::paddedKey(StringRef key) { void Output::paddedKey(StringRef key) {

View File

@ -2691,12 +2691,23 @@ TEST(YAMLIO, TestEmptyMapWrite) {
} }
TEST(YAMLIO, TestEmptySequenceWrite) { TEST(YAMLIO, TestEmptySequenceWrite) {
FooBarContainer cont; {
std::string str; FooBarContainer cont;
llvm::raw_string_ostream OS(str); std::string str;
Output yout(OS); llvm::raw_string_ostream OS(str);
yout << cont; Output yout(OS);
EXPECT_EQ(OS.str(), "---\nfbs: []\n...\n"); yout << cont;
EXPECT_EQ(OS.str(), "---\nfbs: []\n...\n");
}
{
FooBarSequence seq;
std::string str;
llvm::raw_string_ostream OS(str);
Output yout(OS);
yout << seq;
EXPECT_EQ(OS.str(), "---\n[]\n...\n");
}
} }
static void TestEscaped(llvm::StringRef Input, llvm::StringRef Expected) { static void TestEscaped(llvm::StringRef Input, llvm::StringRef Expected) {