Skip to content

Commit 27f5479

Browse files
authored
[clang-format] Break after string literals with trailing line breaks (#76795)
This restores a subset of functionality that was forego in d68826d. Streaming multiple string literals is rare enough in practice, hence that change makes sense in general. But it seems people were incidentally relying on this for having line breaks after string literals that ended with `\n`. This patch tries to restore that behavior to prevent regressions in the upcoming LLVM release, until we can implement some configuration based approach as proposed in #69859.
1 parent 0ba868d commit 27f5479

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

clang/lib/Format/TokenAnnotator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5151,6 +5151,14 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
51515151
return true;
51525152
if (Left.IsUnterminatedLiteral)
51535153
return true;
5154+
// FIXME: Breaking after newlines seems useful in general. Turn this into an
5155+
// option and recognize more cases like endl etc, and break independent of
5156+
// what comes after operator lessless.
5157+
if (Right.is(tok::lessless) && Right.Next &&
5158+
Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
5159+
Left.TokenText.ends_with("\\n\"")) {
5160+
return true;
5161+
}
51545162
if (Right.is(TT_RequiresClause)) {
51555163
switch (Style.RequiresClausePosition) {
51565164
case FormatStyle::RCPS_OwnLine:

clang/unittests/Format/FormatTest.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26708,6 +26708,8 @@ TEST_F(FormatTest, PPBranchesInBracedInit) {
2670826708

2670926709
TEST_F(FormatTest, StreamOutputOperator) {
2671026710
verifyFormat("std::cout << \"foo\" << \"bar\" << baz;");
26711+
verifyFormat("std::cout << \"foo\\n\"\n"
26712+
" << \"bar\";");
2671126713
}
2671226714

2671326715
TEST_F(FormatTest, BreakAdjacentStringLiterals) {

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2499,6 +2499,15 @@ TEST_F(TokenAnnotatorTest, BraceKind) {
24992499
EXPECT_BRACE_KIND(Tokens[6], BK_Block);
25002500
}
25012501

2502+
TEST_F(TokenAnnotatorTest, StreamOperator) {
2503+
auto Tokens = annotate("\"foo\\n\" << aux << \"foo\\n\" << \"foo\";");
2504+
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
2505+
EXPECT_FALSE(Tokens[1]->MustBreakBefore);
2506+
EXPECT_FALSE(Tokens[3]->MustBreakBefore);
2507+
// Only break between string literals if the former ends with \n.
2508+
EXPECT_TRUE(Tokens[5]->MustBreakBefore);
2509+
}
2510+
25022511
} // namespace
25032512
} // namespace format
25042513
} // namespace clang

0 commit comments

Comments
 (0)