Skip to content

Commit 18ef1d8

Browse files
committed
[clang-format] Break after string literals with trailing line breaks
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 5550e9c commit 18ef1d8

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-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+
if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
5155+
// FIXME: Breaking after newlines seems useful in general. Turn this into
5156+
// an option and Recognize more cases like endl etc, and break independent
5157+
// of what comes after operator lessless.
5158+
Right.Next->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/TokenAnnotatorTest.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "FormatTestUtils.h"
1212
#include "TestLexer.h"
13+
#include "clang/Basic/TokenKinds.h"
1314
#include "gtest/gtest.h"
1415

1516
namespace clang {
@@ -2499,6 +2500,15 @@ TEST_F(TokenAnnotatorTest, BraceKind) {
24992500
EXPECT_BRACE_KIND(Tokens[6], BK_Block);
25002501
}
25012502

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

0 commit comments

Comments
 (0)