diff --git a/clang/include/clang/Tooling/ReplacementsYaml.h b/clang/include/clang/Tooling/ReplacementsYaml.h --- a/clang/include/clang/Tooling/ReplacementsYaml.h +++ b/clang/include/clang/Tooling/ReplacementsYaml.h @@ -35,13 +35,7 @@ NormalizedReplacement(const IO &, const clang::tooling::Replacement &R) : FilePath(R.getFilePath()), Offset(R.getOffset()), - Length(R.getLength()), ReplacementText(R.getReplacementText()) { - size_t lineBreakPos = ReplacementText.find('\n'); - while (lineBreakPos != std::string::npos) { - ReplacementText.replace(lineBreakPos, 1, "\n\n"); - lineBreakPos = ReplacementText.find('\n', lineBreakPos + 2); - } - } + Length(R.getLength()), ReplacementText(R.getReplacementText()) {} clang::tooling::Replacement denormalize(const IO &) { return clang::tooling::Replacement(FilePath, Offset, Length, diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -887,13 +887,32 @@ } void ScalarTraits::output(const std::string &Val, void *, - raw_ostream &Out) { - Out << Val; + raw_ostream &Out) { + size_t CurrentPos = 0; + size_t LineBreakPos = Val.find('\n'); + while (LineBreakPos != std::string::npos) { + Out << StringRef(&Val[CurrentPos], LineBreakPos - CurrentPos + 1); + Out << '\n'; + CurrentPos = LineBreakPos + 1; + LineBreakPos = Val.find('\n', CurrentPos); + } + Out << StringRef(&Val[CurrentPos], Val.size() - CurrentPos); } StringRef ScalarTraits::input(StringRef Scalar, void *, - std::string &Val) { - Val = Scalar.str(); + std::string &Val) { + Val.clear(); + size_t CurrentPos = 0; + size_t LineBreakPos = Scalar.find('\n'); + while (LineBreakPos != std::string::npos) { + // '\n\n' convert to '\n' and don't copy single '\n'. + if (CurrentPos + 1 < Scalar.size() && Scalar[LineBreakPos + 1] == '\n') + ++LineBreakPos; + Val += Scalar.substr(CurrentPos, LineBreakPos - CurrentPos); + CurrentPos = LineBreakPos + 1; + LineBreakPos = Scalar.find('\n', CurrentPos); + } + Val += Scalar.substr(CurrentPos, Scalar.size() - CurrentPos); return StringRef(); } diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp --- a/llvm/unittests/Support/YAMLIOTest.cpp +++ b/llvm/unittests/Support/YAMLIOTest.cpp @@ -274,8 +274,8 @@ TEST(YAMLIO, MultilineStrings) { WithStringField Original; - Original.str1 = "a multiline string\nfoobarbaz"; - Original.str2 = "another one\rfoobarbaz"; + Original.str1 = "a\n\nmultiline\nstring\nfoobarbaz"; + Original.str2 = "another one\rfoobarbaz\n"; Original.str3 = "a one-line string"; std::string Serialized; @@ -285,10 +285,10 @@ YOut << Original; } auto Expected = "---\n" - "str1: 'a multiline string\n" + "str1: 'a\n\n\n\nmultiline\n\nstring\n\n" "foobarbaz'\n" "str2: 'another one\r" - "foobarbaz'\n" + "foobarbaz\n\n'\n" "str3: a one-line string\n" "...\n"; ASSERT_EQ(Serialized, Expected);