DaanDeMeyer created this revision. DaanDeMeyer added a reviewer: clang-format. DaanDeMeyer added a project: clang-format. Herald added a project: clang. Herald added a subscriber: cfe-commits.
systemd <https://github.com/systemd/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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D78869 Files: 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 Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -972,6 +972,16 @@ " 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" Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2889,6 +2889,10 @@ 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, Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -327,6 +327,8 @@ 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); Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -1954,6 +1954,7 @@ /// } /// \endcode SBPO_ControlStatements, + SBPO_ControlStatementsExceptForEachMacros, /// Put a space before opening parentheses only if the parentheses are not /// empty i.e. '()' /// \code Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -2308,6 +2308,19 @@ } } + * ``SBPO_ControlStatementsExceptForEachMacros`` (in configuration: + ``ControlStatementsExceptForEachMacros``) + Same as ``SBPO_ControlStatements`` except this option doesn't apply to + ForEach macros. + + .. 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. '()'
Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -972,6 +972,16 @@ " 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" Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2889,6 +2889,10 @@ 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, Index: clang/lib/Format/Format.cpp =================================================================== --- clang/lib/Format/Format.cpp +++ clang/lib/Format/Format.cpp @@ -327,6 +327,8 @@ 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); Index: clang/include/clang/Format/Format.h =================================================================== --- clang/include/clang/Format/Format.h +++ clang/include/clang/Format/Format.h @@ -1954,6 +1954,7 @@ /// } /// \endcode SBPO_ControlStatements, + SBPO_ControlStatementsExceptForEachMacros, /// Put a space before opening parentheses only if the parentheses are not /// empty i.e. '()' /// \code Index: clang/docs/ClangFormatStyleOptions.rst =================================================================== --- clang/docs/ClangFormatStyleOptions.rst +++ clang/docs/ClangFormatStyleOptions.rst @@ -2308,6 +2308,19 @@ } } + * ``SBPO_ControlStatementsExceptForEachMacros`` (in configuration: + ``ControlStatementsExceptForEachMacros``) + Same as ``SBPO_ControlStatements`` except this option doesn't apply to + ForEach macros. + + .. 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. '()'
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits