[clang] [clang-format] Add BreakConcatenatedStrings option (PR #73432)
Owen Pan via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 26 00:00:45 PST 2023
https://github.com/owenca created https://github.com/llvm/llvm-project/pull/73432
Closes #70451.
>From def7bbb22cdd9269aa927d8dcf4247c88877503b Mon Sep 17 00:00:00 2001
From: Owen Pan <owenpiano at gmail.com>
Date: Sat, 25 Nov 2023 23:55:11 -0800
Subject: [PATCH] [clang-format] Add BreakConcatenatedStrings option
Closes #70451.
---
clang/docs/ClangFormatStyleOptions.rst | 15 +++++++++++++++
clang/docs/ReleaseNotes.rst | 1 +
clang/include/clang/Format/Format.h | 14 ++++++++++++++
clang/lib/Format/Format.cpp | 2 ++
clang/lib/Format/TokenAnnotator.cpp | 3 +--
clang/unittests/Format/ConfigParseTest.cpp | 1 +
clang/unittests/Format/FormatTest.cpp | 14 ++++++++++++++
7 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index ff424828ff63cdb..4ff9293b3de7a03 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2761,6 +2761,21 @@ the configuration (without a prefix: ``Auto``).
firstValue :
SecondValueVeryVeryVeryVeryLong;
+.. _BreakConcatenatedStrings:
+
+**BreakConcatenatedStrings** (``Boolean``) :versionbadge:`clang-format 18` :ref:`¶ <BreakConcatenatedStrings>`
+ Break between concatenated string literals in C, C++, and Objective-C.
+
+ .. code-block:: c++
+
+ true:
+ return "Code"
+ "\0\52\26\55\55\0"
+ "x013"
+ "\02\xBA";
+ false:
+ return "Code" "\0\52\26\55\55\0" "x013" "\02\xBA";
+
.. _BreakConstructorInitializers:
**BreakConstructorInitializers** (``BreakConstructorInitializersStyle``) :versionbadge:`clang-format 5` :ref:`¶ <BreakConstructorInitializers>`
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 52c9d6eb69617b0..3aa408496101ad3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -884,6 +884,7 @@ clang-format
- Add ``AllowBreakBeforeNoexceptSpecifier`` option.
- Add ``AllowShortCompoundRequirementOnASingleLine`` option.
- Change ``BreakAfterAttributes`` from ``Never`` to ``Leave`` in LLVM style.
+- Add ``BreakConcatenatedStrings`` option.
libclang
--------
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index bc412611ef62493..b5f7c16774cd96e 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -2088,6 +2088,19 @@ struct FormatStyle {
/// \version 3.7
bool BreakBeforeTernaryOperators;
+ /// Break between concatenated string literals in C, C++, and Objective-C.
+ /// \code
+ /// true:
+ /// return "Code"
+ /// "\0\52\26\55\55\0"
+ /// "x013"
+ /// "\02\xBA";
+ /// false:
+ /// return "Code" "\0\52\26\55\55\0" "x013" "\02\xBA";
+ /// \endcode
+ /// \version 18
+ bool BreakConcatenatedStrings;
+
/// Different ways to break initializers.
enum BreakConstructorInitializersStyle : int8_t {
/// Break constructor initializers before the colon and after the commas.
@@ -4753,6 +4766,7 @@ struct FormatStyle {
BreakBeforeConceptDeclarations == R.BreakBeforeConceptDeclarations &&
BreakBeforeInlineASMColon == R.BreakBeforeInlineASMColon &&
BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators &&
+ BreakConcatenatedStrings == R.BreakConcatenatedStrings &&
BreakConstructorInitializers == R.BreakConstructorInitializers &&
BreakInheritanceList == R.BreakInheritanceList &&
BreakStringLiterals == R.BreakStringLiterals &&
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index e1abcac5604a410..025bca2ea9f7365 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -978,6 +978,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.BreakBeforeInlineASMColon);
IO.mapOptional("BreakBeforeTernaryOperators",
Style.BreakBeforeTernaryOperators);
+ IO.mapOptional("BreakConcatenatedStrings", Style.BreakConcatenatedStrings);
IO.mapOptional("BreakConstructorInitializers",
Style.BreakConstructorInitializers);
IO.mapOptional("BreakInheritanceList", Style.BreakInheritanceList);
@@ -1485,6 +1486,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.BreakBeforeInlineASMColon = FormatStyle::BBIAS_OnlyMultiline;
LLVMStyle.AllowBreakBeforeNoexceptSpecifier = FormatStyle::BBNSS_Never;
LLVMStyle.BreakBeforeTernaryOperators = true;
+ LLVMStyle.BreakConcatenatedStrings = true;
LLVMStyle.BreakConstructorInitializers = FormatStyle::BCIS_BeforeColon;
LLVMStyle.BreakInheritanceList = FormatStyle::BILS_BeforeColon;
LLVMStyle.BreakStringLiterals = true;
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index cfca7c00312aab3..17d3b48e0af8332 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5078,8 +5078,7 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
// it is hard to identify them in UnwrappedLineParser.
if (!Keywords.isVerilogBegin(Right) && Keywords.isVerilogEndOfLabel(Left))
return true;
- } else if (Style.Language == FormatStyle::LK_Cpp ||
- Style.Language == FormatStyle::LK_ObjC ||
+ } else if ((Style.isCpp() && Style.BreakConcatenatedStrings) ||
Style.Language == FormatStyle::LK_Proto ||
Style.Language == FormatStyle::LK_TableGen ||
Style.Language == FormatStyle::LK_TextProto) {
diff --git a/clang/unittests/Format/ConfigParseTest.cpp b/clang/unittests/Format/ConfigParseTest.cpp
index 3a6667dbe0eb15d..910f5157a4f0209 100644
--- a/clang/unittests/Format/ConfigParseTest.cpp
+++ b/clang/unittests/Format/ConfigParseTest.cpp
@@ -161,6 +161,7 @@ TEST(ConfigParseTest, ParsesConfigurationBools) {
CHECK_PARSE_BOOL(BinPackParameters);
CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);
CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
+ CHECK_PARSE_BOOL(BreakConcatenatedStrings);
CHECK_PARSE_BOOL(BreakStringLiterals);
CHECK_PARSE_BOOL(CompactNamespaces);
CHECK_PARSE_BOOL(DerivePointerAlignment);
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 67423f9b06fbc37..f83234e39ea036e 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -26642,6 +26642,20 @@ TEST_F(FormatTest, StreamOutputOperator) {
verifyFormat("std::cout << \"foo\" << \"bar\" << baz;");
}
+TEST_F(FormatTest, BreakConcatenatedStrings) {
+ constexpr StringRef Code{
+ "return \"Code\" \"\\0\\52\\26\\55\\55\\0\" \"x013\" \"\\02\\xBA\";"};
+
+ verifyFormat("return \"Code\"\n"
+ " \"\\0\\52\\26\\55\\55\\0\"\n"
+ " \"x013\"\n"
+ " \"\\02\\xBA\";",
+ Code);
+
+ auto Style = getLLVMStyle();
+ Style.BreakConcatenatedStrings = false;
+ verifyFormat(Code, Style);
+}
} // namespace
} // namespace test
} // namespace format
More information about the cfe-commits
mailing list