[clang] f21c704 - clang-format: Add ControlStatementsExceptForEachMacros option to SpaceBeforeParens
Daan De Meyer via cfe-commits
cfe-commits at lists.llvm.org
Wed May 6 11:59:32 PDT 2020
Author: Daan De Meyer
Date: 2020-05-06T20:59:24+02:00
New Revision: f21c704553a8af7012eaf1ab777e2aa1a55cc86d
URL: https://github.com/llvm/llvm-project/commit/f21c704553a8af7012eaf1ab777e2aa1a55cc86d
DIFF: https://github.com/llvm/llvm-project/commit/f21c704553a8af7012eaf1ab777e2aa1a55cc86d.diff
LOG: clang-format: Add ControlStatementsExceptForEachMacros option to SpaceBeforeParens
Summary: systemd recently added a clang-format file. One issue I
encountered in using clang-format on systemd is that systemd does
not add a space before the parens of their foreach macros but
clang-format always adds a space. This does not seem to be
configurable in clang-format. This revision adds the
ControlStatementsExceptForEachMacros option to SpaceBeforeParens
which puts a space before all control statement parens except
ForEach macros. This drastically reduces the amount of changes
when running clang-format on systemd's source code.
Reviewers: MyDeveloperDay, krasimir, mitchell-stellar
Reviewed By: MyDeveloperDay
Subscribers: cfe-commits
Tags: #clang-format, #clang
Differential Revision: https://reviews.llvm.org/D78869
Added:
Modified:
clang/docs/ClangFormatStyleOptions.rst
clang/include/clang/Format/Format.h
clang/lib/Format/Format.cpp
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst
index ce26b06bf171..3ea503a592ac 100644
--- a/clang/docs/ClangFormatStyleOptions.rst
+++ b/clang/docs/ClangFormatStyleOptions.rst
@@ -2336,6 +2336,19 @@ the configuration (without a prefix: ``Auto``).
}
}
+ * ``SBPO_ControlStatementsExceptForEachMacros`` (in configuration: ``ControlStatementsExceptForEachMacros``)
+ Same as ``SBPO_ControlStatements`` except this option doesn't apply to
+ ForEach macros. This is useful in projects where ForEach macros are
+ treated as function calls instead of control statements.
+
+ .. code-block:: c++
+
+ void f() {
+ Q_FOREACH(...) {
+ f();
+ }
+ }
+
* ``SBPO_NonEmptyParentheses`` (in configuration: ``NonEmptyParentheses``)
Put a space before opening parentheses only if the parentheses are not
empty i.e. '()'
diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h
index 011cf599d526..f8f2903dde57 100644
--- a/clang/include/clang/Format/Format.h
+++ b/clang/include/clang/Format/Format.h
@@ -1983,6 +1983,17 @@ struct FormatStyle {
/// }
/// \endcode
SBPO_ControlStatements,
+ /// Same as ``SBPO_ControlStatements`` except this option doesn't apply to
+ /// ForEach macros. This is useful in projects where ForEach macros are
+ /// treated as function calls instead of control statements.
+ /// \code
+ /// void f() {
+ /// Q_FOREACH(...) {
+ /// f();
+ /// }
+ /// }
+ /// \endcode
+ SBPO_ControlStatementsExceptForEachMacros,
/// Put a space before opening parentheses only if the parentheses are not
/// empty i.e. '()'
/// \code
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 961cb92ebd40..1fd7d613f9fb 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -329,6 +329,8 @@ struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
IO.enumCase(Value, "ControlStatements",
FormatStyle::SBPO_ControlStatements);
+ IO.enumCase(Value, "ControlStatementsExceptForEachMacros",
+ FormatStyle::SBPO_ControlStatementsExceptForEachMacros);
IO.enumCase(Value, "NonEmptyParentheses",
FormatStyle::SBPO_NonEmptyParentheses);
IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 734dbdc1b6f3..408f68e35418 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -2900,6 +2900,10 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
if ((Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) ||
(Left.is(tok::r_square) && Left.is(TT_AttributeSquare)))
return true;
+ if (Style.SpaceBeforeParens ==
+ FormatStyle::SBPO_ControlStatementsExceptForEachMacros &&
+ Left.is(TT_ForEachMacro))
+ return false;
return Line.Type == LT_ObjCDecl || Left.is(tok::semi) ||
(Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
(Left.isOneOf(tok::pp_elif, tok::kw_for, tok::kw_while,
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 9fdf2e728472..aba209b4252d 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -972,6 +972,17 @@ TEST_F(FormatTest, ForEachLoops) {
" UNKNOWN_FORACH(Item * item, itemlist) {}\n"
"}");
+ FormatStyle Style = getLLVMStyle();
+ Style.SpaceBeforeParens =
+ FormatStyle::SBPO_ControlStatementsExceptForEachMacros;
+ verifyFormat("void f() {\n"
+ " foreach(Item *item, itemlist) {}\n"
+ " Q_FOREACH(Item *item, itemlist) {}\n"
+ " BOOST_FOREACH(Item *item, itemlist) {}\n"
+ " UNKNOWN_FORACH(Item * item, itemlist) {}\n"
+ "}",
+ Style);
+
// As function-like macros.
verifyFormat("#define foreach(x, y)\n"
"#define Q_FOREACH(x, y)\n"
More information about the cfe-commits
mailing list