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);