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/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/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/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/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -972,6 +972,17 @@ " 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"