[clang] [clang-format] revert to string << string handling to previous default (PR #88490)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 13 04:15:39 PDT 2024
https://github.com/mydeveloperday updated https://github.com/llvm/llvm-project/pull/88490
>From 1c11c3edd0005a729561d84b9a815279b356e8db Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Fri, 12 Apr 2024 10:32:19 +0100
Subject: [PATCH 1/7] [clang-format] revery to string << string handling back
to previous default
Fixes 88433
A change made to the handling of chevron operators causes a large amount
of flux in code bases that were previously using clang-format, this fix
reverts that change to the default behaviour but adds that new behaviour
behind a new option.
---
clang/docs/ClangFormatStyleOptions.rst | 34 ++++++++++++++++++
clang/docs/ReleaseNotes.rst | 2 ++
clang/include/clang/Format/Format.h | 28 +++++++++++++++
clang/lib/Format/Format.cpp | 13 +++++++
clang/lib/Format/TokenAnnotator.cpp | 16 ++++++---
clang/unittests/Format/ConfigParseTest.cpp | 8 +++++
clang/unittests/Format/FormatTest.cpp | 42 ++++++++++++++++++++--
7 files changed, 136 insertions(+), 7 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 39f7cded36edbf..a40a940f39d860 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3258,6 +3258,40 @@ the configuration (without a prefix: ``Auto``).
firstValue :
SecondValueVeryVeryVeryVeryLong;
+.. _BreakChevronOperator:
+
+**BreakChevronOperator** (``BreakChevronOperatorStyle``) :versionbadge:`clang-format 19` :ref:`¶ <BreakChevronOperator>`
+ Break Between Chevron Operators
+
+ Possible values:
+
+ * ``BCOS_Never`` (in configuration: ``Never``)
+ Break using ColumnLimit rules.
+
+ .. code-block:: c++
+
+ os << "aaaaa" << "bbbbb" << "\n";
+
+ * ``BCOS_BetweenStrings`` (in configuration: ``BetweenStrings``)
+ Break between adjacent strings.
+
+ .. code-block:: c++
+
+ os << "aaaaa"
+ << "bbbbb"
+ << "\n";
+
+ * ``BCOS_BetweenNewlineStrings`` (in configuration: ``BetweenNewlineStrings``)
+ Break between adjacent strings that end with \n.
+
+ .. code-block:: c++
+
+ os << "aaaaa\n"
+ << "bbbbb" << "ccccc\n"
+ << "\n";
+
+
+
.. _BreakConstructorInitializers:
**BreakConstructorInitializers** (``BreakConstructorInitializersStyle``) :versionbadge:`clang-format 5` :ref:`¶ <BreakConstructorInitializers>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 45a9a79739a4eb..01838b0ccd653d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -671,6 +671,8 @@ clang-format
``BreakTemplateDeclarations``.
- ``AlwaysBreakAfterReturnType`` is deprecated and renamed to
``BreakAfterReturnType``.
+- ``BreakChevronOperator`` Style is added and the previous default
+ of breaking between strings is reverted.
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 48f5fb44157570..205c597af8fb0f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2193,6 +2193,33 @@ struct FormatStyle {
/// \version 3.7
bool BreakBeforeTernaryOperators;
+ /// Different ways to Break Between Chevrons
+ enum BreakChevronOperatorStyle : int8_t {
+ /// Break using ColumnLimit rules.
+ /// \code
+ /// os << "aaaaa" << "bbbbb" << "\n";
+ /// \endcode
+ BCOS_Never,
+ /// Break between adjacent strings.
+ /// \code
+ /// os << "aaaaa"
+ /// << "bbbbb"
+ /// << "\n";
+ /// \endcode
+ BCOS_BetweenStrings,
+ /// Break between adjacent strings that end with \n.
+ /// \code
+ /// os << "aaaaa\n"
+ /// << "bbbbb" << "ccccc\n"
+ /// << "\n";
+ /// \endcode
+ BCOS_BetweenNewlineStrings
+ };
+
+ /// Break Between Chevron Operators
+ /// \version 19
+ BreakChevronOperatorStyle BreakChevronOperator;
+
/// Different ways to break initializers.
enum BreakConstructorInitializersStyle : int8_t {
/// Break constructor initializers before the colon and after the commas.
@@ -4951,6 +4978,7 @@ struct FormatStyle {
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
+ BreakChevronOperator == R.BreakChevronOperator &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
BreakFunctionDefinitionParameters ==
R.BreakFunctionDefinitionParameters &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 89e6c19b0af45c..b781a7e161db78 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -243,6 +243,17 @@ struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {
}
};
+template <>
+struct ScalarEnumerationTraits<FormatStyle::BreakChevronOperatorStyle> {
+ static void enumeration(IO &IO,
+ FormatStyle::BreakChevronOperatorStyle &Value) {
+ IO.enumCase(Value, "Never", FormatStyle::BCOS_Never);
+ IO.enumCase(Value, "BetweenStrings", FormatStyle::BCOS_BetweenStrings);
+ IO.enumCase(Value, "BetweenNewlineStrings",
+ FormatStyle::BCOS_BetweenNewlineStrings);
+ }
+};
+
template <>
struct ScalarEnumerationTraits<FormatStyle::BreakConstructorInitializersStyle> {
static void
@@ -953,6 +964,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.BreakBeforeInlineASMColon);
IO.mapOptional("BreakBeforeTernaryOperators",
Style.BreakBeforeTernaryOperators);
+ IO.mapOptional("BreakChevronOperator", Style.BreakChevronOperator);
IO.mapOptional("BreakConstructorInitializers",
Style.BreakConstructorInitializers);
IO.mapOptional("BreakFunctionDefinitionParameters",
@@ -1466,6 +1478,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
LLVMStyle.BreakBeforeTernaryOperators = true;
+ LLVMStyle.BreakChevronOperator = FormatStyle::BCOS_BetweenStrings;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
LLVMStyle.BreakFunctionDefinitionParameters = false;
LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 628f70417866c3..ae4bda3511b58d 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5598,10 +5598,18 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// FIXME: Breaking after newlines seems useful in general. Turn this into an
// option and recognize more cases like endl etc, and break independent of
// what comes after operator lessless.
- if (Right.is(tok::lessless) && Right.Next &&
- Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
- Left.TokenText.ends_with("\\n\"")) {
- return true;
+ if (Style.BreakChevronOperator == FormatStyle::BCOS_BetweenStrings) {
+ if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
+ Right.Next->is(tok::string_literal)) {
+ return true;
+ }
+ }
+ if (Style.BreakChevronOperator == FormatStyle::BCOS_BetweenNewlineStrings) {
+ if (Right.is(tok::lessless) && Right.Next &&
+ Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
+ Left.TokenText.ends_with("\\n\"")) {
+ return true;
+ }
}
if (Right.is(TT_RequiresClause)) {
switch (Style.RequiresClausePosition) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 8c74ed2d119a3f..07c070b0338711 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -396,6 +396,14 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
FormatStyle::BOS_All);
+ Style.BreakChevronOperator = FormatStyle::BCOS_BetweenStrings;
+ CHECK_PARSE("BreakChevronOperator: BetweenNewlineStrings",
+ BreakChevronOperator, FormatStyle::BCOS_BetweenNewlineStrings);
+ CHECK_PARSE("BreakChevronOperator: Never", BreakChevronOperator,
+ FormatStyle::BCOS_Never);
+ CHECK_PARSE("BreakChevronOperator: BetweenStrings", BreakChevronOperator,
+ FormatStyle::BCOS_BetweenStrings);
+
Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 4906b3350b5b22..566bc9b472d21e 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -27340,9 +27340,44 @@ TEST_F(FormatTest, PPDirectivesAndCommentsInBracedInit) {
}
TEST_F(FormatTest, StreamOutputOperator) {
- verifyFormat("std::cout << \"foo\" << \"bar\" << baz;");
- verifyFormat("std::cout << \"foo\\n\"\n"
- " << \"bar\";");
+ auto Style = getLLVMStyle();
+
+ // This should be the default as it was the original style, thats
+ // been in place since the beginning.
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbbbb\";",
+ Style);
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbbbb\"\n"
+ " << \"ccc\";",
+ Style);
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbbbb\"\n"
+ " << \"cccc\"\n"
+ " << \"ddd\";",
+ Style);
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbbbb\" << baz << \"cccc\"\n"
+ " << \"ddd\";",
+ Style);
+
+ Style.BreakChevronOperator = FormatStyle::BCOS_Never;
+ verifyFormat("std::cout << \"aaaa\" << \"bbb\" << baz;", Style);
+ verifyFormat("std::cout << \"ccc\\n\" << \"dddd\";", Style);
+
+ Style.BreakChevronOperator = FormatStyle::BCOS_BetweenStrings;
+ verifyFormat("std::cout << \"eee\"\n"
+ " << \"ffff\";",
+ Style);
+ verifyFormat("std::cout << \"aa\\n\"\n"
+ " << \"bbbb\";",
+ Style);
+
+ Style.BreakChevronOperator = FormatStyle::BCOS_BetweenNewlineStrings;
+ verifyFormat("std::cout << \"aaaa\" << \"bbb\" << baz;", Style);
+ verifyFormat("std::cout << \"ggg\\n\"\n"
+ " << \"dddd\";",
+ Style);
}
TEST_F(FormatTest, BreakAdjacentStringLiterals) {
@@ -27363,3 +27398,4 @@ TEST_F(FormatTest, BreakAdjacentStringLiterals) {
} // namespace test
} // namespace format
} // namespace clang
+
>From cbb024ae6ab2e2064ffbee1f46e106a0c3e0b299 Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Fri, 12 Apr 2024 11:36:51 +0100
Subject: [PATCH 2/7] [clang-format] revery to string << string handling back
to previous default behaviour
---
clang/unittests/Format/FormatTest.cpp | 1 -
1 file changed, 1 deletion(-)
mode change 100644 => 100755 clang/unittests/Format/FormatTest.cpp
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
old mode 100644
new mode 100755
index 566bc9b472d21e..5e5583bf4b234f
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -27398,4 +27398,3 @@ TEST_F(FormatTest, BreakAdjacentStringLiterals) {
} // namespace test
} // namespace format
} // namespace clang
-
>From 20060add758ebcfd344ffe7aac28b8e2c1ed2c7e Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Fri, 12 Apr 2024 15:05:13 +0100
Subject: [PATCH 3/7] [clang-format] revery to string << string handling back
to previous default
Fixes #88433
A change made to the handling of chevron operators causes a large amount
of flux in code bases that were previously using clang-format, this fix
reverts that change to the default behaviour but adds that new
behaviours behind a new option.
---
clang/docs/ClangFormatStyleOptions.rst | 10 +++++
clang/include/clang/Format/Format.h | 10 ++++-
clang/lib/Format/Format.cpp | 2 +
clang/lib/Format/TokenAnnotator.cpp | 16 +++++++
clang/unittests/Format/FormatTest.cpp | 61 ++++++++++++++++++++++++++
5 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index a40a940f39d860..9b4187c3a40f64 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3290,6 +3290,16 @@ the configuration (without a prefix: ``Auto``).
<< "bbbbb" << "ccccc\n"
<< "\n";
+ * ``BCOS_Always`` (in configuration: ``Always``)
+ Break between adjacent items
+
+ .. code-block:: c++
+
+ os << "aaaaa\n"
+ << "bbbbb"
+ << "ccccc\n"
+ << "\n";
+
.. _BreakConstructorInitializers:
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 205c597af8fb0f..0ff9af81bb2f8f 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2213,7 +2213,15 @@ struct FormatStyle {
/// << "bbbbb" << "ccccc\n"
/// << "\n";
/// \endcode
- BCOS_BetweenNewlineStrings
+ BCOS_BetweenNewlineStrings,
+ /// Break between adjacent items
+ /// \code
+ /// os << "aaaaa\n"
+ /// << "bbbbb"
+ /// << "ccccc\n"
+ /// << "\n";
+ /// \endcode
+ BCOS_Always
};
/// Break Between Chevron Operators
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index b781a7e161db78..27a12f5ef18f47 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -251,6 +251,7 @@ struct ScalarEnumerationTraits<FormatStyle::BreakChevronOperatorStyle> {
IO.enumCase(Value, "BetweenStrings", FormatStyle::BCOS_BetweenStrings);
IO.enumCase(Value, "BetweenNewlineStrings",
FormatStyle::BCOS_BetweenNewlineStrings);
+ IO.enumCase(Value, "Always", FormatStyle::BCOS_Always);
}
};
@@ -4146,3 +4147,4 @@ bool isClangFormatOff(StringRef Comment) {
} // namespace format
} // namespace clang
+
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index ae4bda3511b58d..5ecceb218c5390 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5611,6 +5611,22 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
}
}
+ if (Style.BreakChevronOperator == FormatStyle::BCOS_Always) {
+ // can be std::os or os
+ auto *FirstChevron = Right.Previous;
+ while (FirstChevron) {
+ if (FirstChevron->isOneOf(tok::lessless, tok::greater))
+ break;
+ FirstChevron = FirstChevron->Previous;
+ }
+
+ if (Right.is(tok::lessless) && FirstChevron)
+ return true;
+ if (Right.is(tok::greater) && Right.Next && Right.Next->is(tok::greater) &&
+ FirstChevron) {
+ return true;
+ }
+ }
if (Right.is(TT_RequiresClause)) {
switch (Style.RequiresClausePosition) {
case FormatStyle::RCPS_OwnLine:
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 5e5583bf4b234f..ac620d0a264c48 100755
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -27378,6 +27378,67 @@ TEST_F(FormatTest, StreamOutputOperator) {
verifyFormat("std::cout << \"ggg\\n\"\n"
" << \"dddd\";",
Style);
+
+ Style.BreakChevronOperator = FormatStyle::BCOS_Always;
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbb\"\n"
+ " << baz;",
+ Style);
+ verifyFormat("std::cout << \"ggg\\n\"\n"
+ " << \"dddd\";",
+ Style);
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbbbb\"\n"
+ " << \"cccc\"\n"
+ " << \"ddd\";",
+ Style);
+ verifyFormat("std::cout << \"aaaa\"\n"
+ " << \"bbbbb\"\n"
+ " << baz\n"
+ " << \"cccc\"\n"
+ " << \"ddd\";",
+ Style);
+ verifyFormat("cout << \"aaaa\"\n"
+ " << \"bbbbb\"\n"
+ " << baz\n"
+ " << \"cccc\"\n"
+ " << \"ddd\";",
+ Style);
+}
+
+TEST_F(FormatTest, StreamInputOperator) {
+ auto Style = getLLVMStyle();
+
+ Style.BreakChevronOperator = FormatStyle::BCOS_Never;
+ verifyFormat("std::in >> aaaa >> bbb >> baz;", Style);
+ verifyFormat("std::in >> ccc >> dddd;", Style);
+
+ Style.BreakChevronOperator = FormatStyle::BCOS_Always;
+ verifyFormat("std::in >> ccc;", Style);
+ verifyFormat("std::in >> aaaa\n"
+ " >> bbb\n"
+ " >> baz;",
+ Style);
+ verifyFormat("std::in >> ggg\n"
+ " >> dddd;",
+ Style);
+ verifyFormat("std::in >> aaaa\n"
+ " >> bbbbb\n"
+ " >> cccc\n"
+ " >> ddd;",
+ Style);
+ verifyFormat("std::in >> aaaa\n"
+ " >> bbbbb\n"
+ " >> baz\n"
+ " >> cccc\n"
+ " >> ddd;",
+ Style);
+ verifyFormat("in >> aaaa\n"
+ " >> bbbbb\n"
+ " >> baz\n"
+ " >> cccc\n"
+ " >> ddd;",
+ Style);
}
TEST_F(FormatTest, BreakAdjacentStringLiterals) {
>From ada5b57dda2a818b9a6404e67fcbcdf66a4b5b28 Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Fri, 12 Apr 2024 15:09:29 +0100
Subject: [PATCH 4/7] [clang-format] revery to string << string handling to
previous default
Fixes #88433
A change made to the handling of chevron operators causes a large amount
of flux in code bases that were previously using clang-format, this fix
reverts that change to the default behaviour but adds that new
behaviours behind a new option BreakChevronOperator.
---
clang/docs/ClangFormatStyleOptions.rst | 2 +-
clang/include/clang/Format/Format.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 9b4187c3a40f64..8c8326285597db 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3291,7 +3291,7 @@ the configuration (without a prefix: ``Auto``).
<< "\n";
* ``BCOS_Always`` (in configuration: ``Always``)
- Break between adjacent items
+ Break between adjacent chevrons.
.. code-block:: c++
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 0ff9af81bb2f8f..b0bd6fea9b7904 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2193,7 +2193,7 @@ struct FormatStyle {
/// \version 3.7
bool BreakBeforeTernaryOperators;
- /// Different ways to Break Between Chevrons
+ /// Different ways to Break Between Chevrons.
enum BreakChevronOperatorStyle : int8_t {
/// Break using ColumnLimit rules.
/// \code
@@ -2214,7 +2214,7 @@ struct FormatStyle {
/// << "\n";
/// \endcode
BCOS_BetweenNewlineStrings,
- /// Break between adjacent items
+ /// Break between adjacent chevrons.
/// \code
/// os << "aaaaa\n"
/// << "bbbbb"
>From 182788791a60ea2e1ecf15222c5889e69ed06b9f Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Fri, 12 Apr 2024 15:11:56 +0100
Subject: [PATCH 5/7] [clang-format] revert to string << string handling to
previous default
Fixes #88433
A change made to the handling of chevron operators causes a large amount
of flux in code bases that were previously using clang-format, this fix
reverts that change to the default behaviour but adds that new
behaviours behind a new option BreakChevronOperator.
---
clang/unittests/Format/ConfigParseTest.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 07c070b0338711..0458f28e7d1c32 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -403,6 +403,8 @@ TEST(ConfigParseTest, ParsesConfiguration) {
FormatStyle::BCOS_Never);
CHECK_PARSE("BreakChevronOperator: BetweenStrings", BreakChevronOperator,
FormatStyle::BCOS_BetweenStrings);
+ CHECK_PARSE("BreakChevronOperator: Always", BreakChevronOperator,
+ FormatStyle::BCOS_Always);
Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
CHECK_PARSE("BreakConstructorInitializers: BeforeComma",
@@ -1459,3 +1461,4 @@ TEST(ConfigParseTest, GetStyleOfSpecificFile) {
} // namespace
} // namespace format
} // namespace clang
+
>From 6579ddd1c34c28c0061d10287ae67ce020615170 Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Fri, 12 Apr 2024 16:45:42 +0100
Subject: [PATCH 6/7] [clang-format] revert to string << string handling to
previous default
Fixes #88433
A change made to the handling of chevron operators causes a large amount
of flux in code bases that were previously using clang-format, this fix
reverts that change to the default behaviour but adds that new
behaviours behind a new option BreakChevronOperator.
---
clang/lib/Format/Format.cpp | 1 -
clang/unittests/Format/ConfigParseTest.cpp | 1 -
2 files changed, 2 deletions(-)
mode change 100644 => 100755 clang/lib/Format/Format.cpp
mode change 100644 => 100755 clang/unittests/Format/ConfigParseTest.cpp
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
old mode 100644
new mode 100755
index 27a12f5ef18f47..da02f5f0bd9d26
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -4147,4 +4147,3 @@ bool isClangFormatOff(StringRef Comment) {
} // namespace format
} // namespace clang
-
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
old mode 100644
new mode 100755
index 0458f28e7d1c32..b38fad31a27c92
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -1461,4 +1461,3 @@ TEST(ConfigParseTest, GetStyleOfSpecificFile) {
} // namespace
} // namespace format
} // namespace clang
-
>From 6729d8193e9651a42bb772787e47e57c51637ae5 Mon Sep 17 00:00:00 2001
From: mydeveloperday <mydeveloperday at gmail.com>
Date: Sat, 13 Apr 2024 12:14:55 +0100
Subject: [PATCH 7/7] [clang-format] revert to string << string handling to
previous default
Fixes #88433
A change made to the handling of streaming operators causes a large amount
of flux in code bases that were previously using clang-format, this fix
reverts that change to the default behaviour but adds that new
behaviours behind a new option BreakStreamOperator.
---
clang/docs/ClangFormatStyleOptions.rst | 88 +++++++++++-----------
clang/docs/ReleaseNotes.rst | 2 +-
clang/include/clang/Format/Format.h | 14 ++--
clang/lib/Format/Format.cpp | 10 +--
clang/lib/Format/TokenAnnotator.cpp | 30 +++++---
clang/unittests/Format/ConfigParseTest.cpp | 14 ++--
clang/unittests/Format/FormatTest.cpp | 12 +--
7 files changed, 90 insertions(+), 80 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index 8c8326285597db..bbc2b6dd176d4f 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -3258,50 +3258,6 @@ the configuration (without a prefix: ``Auto``).
firstValue :
SecondValueVeryVeryVeryVeryLong;
-.. _BreakChevronOperator:
-
-**BreakChevronOperator** (``BreakChevronOperatorStyle``) :versionbadge:`clang-format 19` :ref:`¶ <BreakChevronOperator>`
- Break Between Chevron Operators
-
- Possible values:
-
- * ``BCOS_Never`` (in configuration: ``Never``)
- Break using ColumnLimit rules.
-
- .. code-block:: c++
-
- os << "aaaaa" << "bbbbb" << "\n";
-
- * ``BCOS_BetweenStrings`` (in configuration: ``BetweenStrings``)
- Break between adjacent strings.
-
- .. code-block:: c++
-
- os << "aaaaa"
- << "bbbbb"
- << "\n";
-
- * ``BCOS_BetweenNewlineStrings`` (in configuration: ``BetweenNewlineStrings``)
- Break between adjacent strings that end with \n.
-
- .. code-block:: c++
-
- os << "aaaaa\n"
- << "bbbbb" << "ccccc\n"
- << "\n";
-
- * ``BCOS_Always`` (in configuration: ``Always``)
- Break between adjacent chevrons.
-
- .. code-block:: c++
-
- os << "aaaaa\n"
- << "bbbbb"
- << "ccccc\n"
- << "\n";
-
-
-
.. _BreakConstructorInitializers:
**BreakConstructorInitializers** (``BreakConstructorInitializersStyle``) :versionbadge:`clang-format 5` :ref:`¶ <BreakConstructorInitializers>`
@@ -3403,6 +3359,50 @@ the configuration (without a prefix: ``Auto``).
+.. _BreakStreamOperator:
+
+**BreakStreamOperator** (``BreakStreamOperatorStyle``) :versionbadge:`clang-format 19` :ref:`¶ <BreakStreamOperator>`
+ Break Between Stream Operators.
+
+ Possible values:
+
+ * ``BCOS_Normal`` (in configuration: ``Normal``)
+ Break using ColumnLimit rules.
+
+ .. code-block:: c++
+
+ os << "aaaaa" << "bbbbb" << "\n";
+
+ * ``BCOS_BetweenStrings`` (in configuration: ``BetweenStrings``)
+ Break between adjacent strings.
+
+ .. code-block:: c++
+
+ os << "aaaaa"
+ << "bbbbb"
+ << "\n";
+
+ * ``BCOS_BetweenNewlineStrings`` (in configuration: ``BetweenNewlineStrings``)
+ Break between adjacent strings that end with \n.
+
+ .. code-block:: c++
+
+ os << "aaaaa\n"
+ << "bbbbb" << "ccccc\n"
+ << "\n";
+
+ * ``BCOS_Always`` (in configuration: ``Always``)
+ Break between adjacent stream operations.
+
+ .. code-block:: c++
+
+ os << "aaaaa\n"
+ << "bbbbb"
+ << "ccccc\n"
+ << "\n";
+
+
+
.. _BreakStringLiterals:
**BreakStringLiterals** (``Boolean``) :versionbadge:`clang-format 3.9` :ref:`¶ <BreakStringLiterals>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 01838b0ccd653d..b4c2c00f1a0229 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -671,7 +671,7 @@ clang-format
``BreakTemplateDeclarations``.
- ``AlwaysBreakAfterReturnType`` is deprecated and renamed to
``BreakAfterReturnType``.
-- ``BreakChevronOperator`` Style is added and the previous default
+- ``BreakStreamOperator`` Style is added and the previous default
of breaking between strings is reverted.
libclang
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index b0bd6fea9b7904..4f7d9c80571762 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2193,13 +2193,13 @@ struct FormatStyle {
/// \version 3.7
bool BreakBeforeTernaryOperators;
- /// Different ways to Break Between Chevrons.
- enum BreakChevronOperatorStyle : int8_t {
+ /// Different ways to Break Between Stream Operators.
+ enum BreakStreamOperatorStyle : int8_t {
/// Break using ColumnLimit rules.
/// \code
/// os << "aaaaa" << "bbbbb" << "\n";
/// \endcode
- BCOS_Never,
+ BCOS_Normal,
/// Break between adjacent strings.
/// \code
/// os << "aaaaa"
@@ -2214,7 +2214,7 @@ struct FormatStyle {
/// << "\n";
/// \endcode
BCOS_BetweenNewlineStrings,
- /// Break between adjacent chevrons.
+ /// Break between adjacent stream operations.
/// \code
/// os << "aaaaa\n"
/// << "bbbbb"
@@ -2224,9 +2224,9 @@ struct FormatStyle {
BCOS_Always
};
- /// Break Between Chevron Operators
+ /// Break Between Stream Operators.
/// \version 19
- BreakChevronOperatorStyle BreakChevronOperator;
+ BreakStreamOperatorStyle BreakStreamOperator;
/// Different ways to break initializers.
enum BreakConstructorInitializersStyle : int8_t {
@@ -4986,7 +4986,7 @@ struct FormatStyle {
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
- BreakChevronOperator == R.BreakChevronOperator &&
+ BreakStreamOperator == R.BreakStreamOperator &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
BreakFunctionDefinitionParameters ==
R.BreakFunctionDefinitionParameters &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index da02f5f0bd9d26..9573c59b363c23 100755
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -244,10 +244,10 @@ struct ScalarEnumerationTraits<FormatStyle::BreakBeforeInlineASMColonStyle> {
};
template <>
-struct ScalarEnumerationTraits<FormatStyle::BreakChevronOperatorStyle> {
+struct ScalarEnumerationTraits<FormatStyle::BreakStreamOperatorStyle> {
static void enumeration(IO &IO,
- FormatStyle::BreakChevronOperatorStyle &Value) {
- IO.enumCase(Value, "Never", FormatStyle::BCOS_Never);
+ FormatStyle::BreakStreamOperatorStyle &Value) {
+ IO.enumCase(Value, "Normal", FormatStyle::BCOS_Normal);
IO.enumCase(Value, "BetweenStrings", FormatStyle::BCOS_BetweenStrings);
IO.enumCase(Value, "BetweenNewlineStrings",
FormatStyle::BCOS_BetweenNewlineStrings);
@@ -965,7 +965,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.BreakBeforeInlineASMColon);
IO.mapOptional("BreakBeforeTernaryOperators",
Style.BreakBeforeTernaryOperators);
- IO.mapOptional("BreakChevronOperator", Style.BreakChevronOperator);
+ IO.mapOptional("BreakStreamOperator", Style.BreakStreamOperator);
IO.mapOptional("BreakConstructorInitializers",
Style.BreakConstructorInitializers);
IO.mapOptional("BreakFunctionDefinitionParameters",
@@ -1479,7 +1479,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakBeforeConceptDeclarations = FormatStyle::BBCDS_Always;
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
LLVMStyle.BreakBeforeTernaryOperators = true;
- LLVMStyle.BreakChevronOperator = FormatStyle::BCOS_BetweenStrings;
+ LLVMStyle.BreakStreamOperator = FormatStyle::BCOS_BetweenStrings;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
LLVMStyle.BreakFunctionDefinitionParameters = false;
LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 5ecceb218c5390..d5f8989369b395 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5598,35 +5598,45 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// FIXME: Breaking after newlines seems useful in general. Turn this into an
// option and recognize more cases like endl etc, and break independent of
// what comes after operator lessless.
- if (Style.BreakChevronOperator == FormatStyle::BCOS_BetweenStrings) {
+ switch (Style.BreakStreamOperator) {
+ case FormatStyle::BCOS_BetweenStrings: {
if (Right.is(tok::lessless) && Right.Next && Left.is(tok::string_literal) &&
Right.Next->is(tok::string_literal)) {
return true;
}
+ break;
}
- if (Style.BreakChevronOperator == FormatStyle::BCOS_BetweenNewlineStrings) {
+ case FormatStyle::BCOS_BetweenNewlineStrings: {
if (Right.is(tok::lessless) && Right.Next &&
Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
Left.TokenText.ends_with("\\n\"")) {
return true;
}
+ break;
}
- if (Style.BreakChevronOperator == FormatStyle::BCOS_Always) {
- // can be std::os or os
- auto *FirstChevron = Right.Previous;
- while (FirstChevron) {
- if (FirstChevron->isOneOf(tok::lessless, tok::greater))
+ case FormatStyle::BCOS_Always: {
+ // Don't break after the very first << or >>
+ // but the Left token can be os or std::os so
+ // scan back
+ auto *FirstStream = Right.Previous;
+ while (FirstStream) {
+ if (FirstStream->isOneOf(tok::lessless, tok::greater))
break;
- FirstChevron = FirstChevron->Previous;
+ FirstStream = FirstStream->Previous;
}
- if (Right.is(tok::lessless) && FirstChevron)
+ if (Right.is(tok::lessless) && FirstStream)
return true;
if (Right.is(tok::greater) && Right.Next && Right.Next->is(tok::greater) &&
- FirstChevron) {
+ FirstStream) {
return true;
}
+ break;
}
+ case FormatStyle::BCOS_Normal:
+ break;
+ }
+
if (Right.is(TT_RequiresClause)) {
switch (Style.RequiresClausePosition) {
case FormatStyle::RCPS_OwnLine:
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index b38fad31a27c92..3cb9b62a856266 100755
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -396,14 +396,14 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE("BreakBeforeBinaryOperators: true", BreakBeforeBinaryOperators,
FormatStyle::BOS_All);
- Style.BreakChevronOperator = FormatStyle::BCOS_BetweenStrings;
- CHECK_PARSE("BreakChevronOperator: BetweenNewlineStrings",
- BreakChevronOperator, FormatStyle::BCOS_BetweenNewlineStrings);
- CHECK_PARSE("BreakChevronOperator: Never", BreakChevronOperator,
- FormatStyle::BCOS_Never);
- CHECK_PARSE("BreakChevronOperator: BetweenStrings", BreakChevronOperator,
+ Style.BreakStreamOperator = FormatStyle::BCOS_BetweenStrings;
+ CHECK_PARSE("BreakStreamOperator: BetweenNewlineStrings", BreakStreamOperator,
+ FormatStyle::BCOS_BetweenNewlineStrings);
+ CHECK_PARSE("BreakStreamOperator: Normal", BreakStreamOperator,
+ FormatStyle::BCOS_Normal);
+ CHECK_PARSE("BreakStreamOperator: BetweenStrings", BreakStreamOperator,
FormatStyle::BCOS_BetweenStrings);
- CHECK_PARSE("BreakChevronOperator: Always", BreakChevronOperator,
+ CHECK_PARSE("BreakStreamOperator: Always", BreakStreamOperator,
FormatStyle::BCOS_Always);
Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index ac620d0a264c48..514ffa9e97b7dd 100755
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -27361,11 +27361,11 @@ TEST_F(FormatTest, StreamOutputOperator) {
" << \"ddd\";",
Style);
- Style.BreakChevronOperator = FormatStyle::BCOS_Never;
+ Style.BreakStreamOperator = FormatStyle::BCOS_Normal;
verifyFormat("std::cout << \"aaaa\" << \"bbb\" << baz;", Style);
verifyFormat("std::cout << \"ccc\\n\" << \"dddd\";", Style);
- Style.BreakChevronOperator = FormatStyle::BCOS_BetweenStrings;
+ Style.BreakStreamOperator = FormatStyle::BCOS_BetweenStrings;
verifyFormat("std::cout << \"eee\"\n"
" << \"ffff\";",
Style);
@@ -27373,13 +27373,13 @@ TEST_F(FormatTest, StreamOutputOperator) {
" << \"bbbb\";",
Style);
- Style.BreakChevronOperator = FormatStyle::BCOS_BetweenNewlineStrings;
+ Style.BreakStreamOperator = FormatStyle::BCOS_BetweenNewlineStrings;
verifyFormat("std::cout << \"aaaa\" << \"bbb\" << baz;", Style);
verifyFormat("std::cout << \"ggg\\n\"\n"
" << \"dddd\";",
Style);
- Style.BreakChevronOperator = FormatStyle::BCOS_Always;
+ Style.BreakStreamOperator = FormatStyle::BCOS_Always;
verifyFormat("std::cout << \"aaaa\"\n"
" << \"bbb\"\n"
" << baz;",
@@ -27409,11 +27409,11 @@ TEST_F(FormatTest, StreamOutputOperator) {
TEST_F(FormatTest, StreamInputOperator) {
auto Style = getLLVMStyle();
- Style.BreakChevronOperator = FormatStyle::BCOS_Never;
+ Style.BreakStreamOperator = FormatStyle::BCOS_Normal;
verifyFormat("std::in >> aaaa >> bbb >> baz;", Style);
verifyFormat("std::in >> ccc >> dddd;", Style);
- Style.BreakChevronOperator = FormatStyle::BCOS_Always;
+ Style.BreakStreamOperator = FormatStyle::BCOS_Always;
verifyFormat("std::in >> ccc;", Style);
verifyFormat("std::in >> aaaa\n"
" >> bbb\n"
More information about the cfe-commits
mailing list