Index: docs/ClangFormatStyleOptions.rst
===================================================================
--- docs/ClangFormatStyleOptions.rst
+++ docs/ClangFormatStyleOptions.rst
@@ -474,6 +474,10 @@
* ``SBPO_ControlStatements`` (in configuration: ``ControlStatements``)
Put a space before opening parentheses only after control statement
keywords (``for/if/while...``).
+ * ``SBPO_ControlStatementsExceptObjC`` (in configuration: ``ControlStatementsExceptObjC``)
+ Put a space before opening parentheses only after control statement
+ keywords and excluding Objective-C control statement
+ keywords (``@synchronized``).
* ``SBPO_Always`` (in configuration: ``Always``)
Always put a space before opening parentheses, except when it's
prohibited by the syntax rules (in function-like macro definitions) or
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -401,6 +401,10 @@
/// Put a space before opening parentheses only after control statement
/// keywords (for/if/while...).
SBPO_ControlStatements,
+ /// Put a space before opening parentheses only after control statement
+ /// keywords and excluding Objective-C control statement
+ /// keywords (@synchronized).
+ SBPO_ControlStatementsExceptObjC,
/// Always put a space before opening parentheses, except when it's
/// prohibited by the syntax rules (in function-like macro definitions) or
/// when determined by other style rules (after unary operators, opening
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -128,6 +128,8 @@
IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
IO.enumCase(Value, "ControlStatements",
FormatStyle::SBPO_ControlStatements);
+ IO.enumCase(Value, "ControlStatementsExceptObjC",
+ FormatStyle::SBPO_ControlStatementsExceptObjC);
IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
// For backward compatibility.
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1841,6 +1841,9 @@
return true;
return Line.Type == LT_ObjCDecl || Left.is(tok::semi) ||
(Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
+ !(Style.SpaceBeforeParens ==
+ FormatStyle::SBPO_ControlStatementsExceptObjC &&
+ Left.is(tok::objc_synchronized)) &&
(Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while,
tok::kw_switch, tok::kw_case, tok::objc_synchronized,
TT_ForEachMacro) ||
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -2434,6 +2434,11 @@
" f();\n"
"}\n",
Style);
+ Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatementsExceptObjC;
+ verifyFormat("@synchronized(foo)\n"
+ "{\n"
+ "}\n",
+ Style);
}
TEST_F(FormatTest, StaticInitializers) {
@@ -8263,6 +8268,9 @@
verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", NoSpace);
verifyFormat("int f() throw(Deprecated);", NoSpace);
verifyFormat("typedef void (*cb)(int);", NoSpace);
+ verifyFormat("@synchronized(mutex) {\n"
+ "}",
+ NoSpace);
FormatStyle Space = getLLVMStyle();
Space.SpaceBeforeParens = FormatStyle::SBPO_Always;
@@ -8308,6 +8316,59 @@
verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", Space);
verifyFormat("int f () throw (Deprecated);", Space);
verifyFormat("typedef void (*cb) (int);", Space);
+ verifyFormat("@synchronized (mutex) {\n"
+ "}",
+ Space);
+
+ FormatStyle ControlSpace = getLLVMStyle();
+ ControlSpace.SpaceBeforeParens =
+ FormatStyle::SBPO_ControlStatementsExceptObjC;
+
+ verifyFormat("int f();", ControlSpace);
+ verifyFormat("void f(int a, T b) {\n"
+ " while (true)\n"
+ " continue;\n"
+ "}",
+ ControlSpace);
+ verifyFormat("if (true)\n"
+ " f();\n"
+ "else if (true)\n"
+ " f();",
+ ControlSpace);
+ verifyFormat("do {\n"
+ " do_something();\n"
+ "} while (something());",
+ ControlSpace);
+ verifyFormat("switch (x) {\n"
+ "default:\n"
+ " break;\n"
+ "}",
+ ControlSpace);
+ verifyFormat("A::A() : a(1) {}", ControlSpace);
+ verifyFormat("void f() __attribute__((asdf));", ControlSpace);
+ verifyFormat("*(&a + 1);\n"
+ "&((&a)[1]);\n"
+ "a[(b + c) * d];\n"
+ "(((a + 1) * 2) + 3) * 4;",
+ ControlSpace);
+ verifyFormat("#define A(x) x", ControlSpace);
+ verifyFormat("#define A (x) x", ControlSpace);
+ verifyFormat("#if defined(x)\n"
+ "#endif",
+ ControlSpace);
+ verifyFormat("auto i = std::make_unique(5);", ControlSpace);
+ verifyFormat("size_t x = sizeof(x);", ControlSpace);
+ verifyFormat("auto f(int x) -> decltype(x);", ControlSpace);
+ verifyFormat("int f(T x) noexcept(x.create());", ControlSpace);
+ verifyFormat("alignas(128) char a[128];", ControlSpace);
+ verifyFormat("size_t x = alignof(MyType);", ControlSpace);
+ verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");",
+ ControlSpace);
+ verifyFormat("int f() throw(Deprecated);", ControlSpace);
+ verifyFormat("typedef void (*cb)(int);", ControlSpace);
+ verifyFormat("@synchronized(mutex) {\n"
+ "}",
+ ControlSpace);
}
TEST_F(FormatTest, ConfigurableSpacesInParentheses) {
@@ -9258,6 +9319,8 @@
FormatStyle::SBPO_Always);
CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
FormatStyle::SBPO_ControlStatements);
+ CHECK_PARSE("SpaceBeforeParens: ControlStatementsExceptObjC",
+ SpaceBeforeParens, FormatStyle::SBPO_ControlStatementsExceptObjC);
// For backward compatibility:
CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
FormatStyle::SBPO_Never);