Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -172,6 +172,9 @@ Always break before braces and add an extra level of indentation to braces of control statements, not to those of class, function or other definitions. + * ``BS_KernighanRitchie`` (in configuration: ``KernighanRitchie``) + Like ``Attach``, but only break before braces on function + definitions. **BreakBeforeTernaryOperators** (``bool``) @@ -220,7 +223,8 @@ **DerivePointerAlignment** (``bool``) If ``true``, analyze the formatted file for the most common - alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as fallback. + alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as + fallback. **DisableFormat** (``bool``) Disables formatting at all. Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -99,7 +99,8 @@ PointerAlignmentStyle PointerAlignment; /// \brief If \c true, analyze the formatted file for the most common - /// alignment of & and *. \c PointerAlignment is then used only as fallback. + /// alignment of \c & and \c *. \c PointerAlignment is then used only as + /// fallback. bool DerivePointerAlignment; /// \brief The extra indent or outdent of access modifiers, e.g. \c public:. @@ -283,7 +284,10 @@ /// Always break before braces and add an extra level of indentation to /// braces of control statements, not to those of class, function /// or other definitions. - BS_GNU + BS_GNU, + /// Like \c Attach, but only break before braces on function + /// definitions. + BS_KernighanRitchie }; /// \brief The brace breaking style to use. Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -83,6 +83,7 @@ IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup); IO.enumCase(Value, "Allman", FormatStyle::BS_Allman); IO.enumCase(Value, "GNU", FormatStyle::BS_GNU); + IO.enumCase(Value, "KernighanRitchie", FormatStyle::BS_KernighanRitchie); } }; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -2118,6 +2118,13 @@ " // something\n" "}", Style); + Style.BreakBeforeBraces = FormatStyle::BS_KernighanRitchie; + verifyFormat("try {\n" + " // something\n" + "} catch (...) {\n" + " // something\n" + "}", + Style); Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; verifyFormat("try {\n" " // something\n" @@ -8058,6 +8065,101 @@ getLLVMStyle()); } +TEST_F(FormatTest, KernighanRitchieBraceBreaking) { + FormatStyle KRStyle = getLLVMStyle(); + KRStyle.BreakBeforeBraces = FormatStyle::BS_KernighanRitchie; + verifyFormat("namespace a {\n" + "class A {\n" + " void f()\n" + " {\n" + " if (true) {\n" + " a();\n" + " b();\n" + " }\n" + " }\n" + " void g() { return; }\n" + "}\n" + "}", + KRStyle); + + verifyFormat("void foo()\n" + "{\n" + " if (a) {\n" + " a();\n" + " } else {\n" + " b();\n" + " }\n" + "}\n", + KRStyle); + + verifyFormat("std::function adder(int x)\n" + "{\n" + " return [=](int someReallyLongParameterName) {\n" + " return someReallyLongParameterName + x;\n" + " }\n" + "}\n", + KRStyle); + + verifyFormat("#ifdef _DEBUG\n" + "int foo(int i = 0)\n" + "#else\n" + "int foo(int i = 5)\n" + "#endif\n" + "{\n" + " return i;\n" + "}", + KRStyle); + + verifyFormat("void f()\n" + "{\n" + " for (int i = 0; i < 10; ++i) {\n" + " a();\n" + " }\n" + " while (false) {\n" + " b();\n" + " }\n" + " do {\n" + " c();\n" + " } while (false);\n" + "}\n", + KRStyle); + + verifyFormat("namespace ns {\n" + "class A {\n" + "public:\n" + " void method(int x, int y) noexcept\n" + " {\n" + " try {\n" + " return;\n" + " } catch (...) {\n" + " return;\n" + " }\n" + " }\n" + "};\n" + "}\n", + KRStyle); + + verifyFormat("void foo() {}\n" + "void bar()\n" + "#ifdef _DEBUG\n" + "{\n" + " foo();\n" + "}\n" + "#else\n" + "{\n" + "}\n" + "#endif", + KRStyle); + + verifyFormat("void foobar() { int i = 5; }\n" + "#ifdef _DEBUG\n" + "void bar() {}\n" + "#else\n" + "void bar() { foobar(); }\n" + "#endif", + KRStyle); +} + TEST_F(FormatTest, UnderstandsPragmas) { verifyFormat("#pragma omp reduction(| : var)"); verifyFormat("#pragma omp reduction(+ : var)"); @@ -8273,6 +8375,8 @@ CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces, FormatStyle::BS_Allman); CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU); + CHECK_PARSE("BreakBeforeBraces: KernighanRitchie", BreakBeforeBraces, + FormatStyle::BS_KernighanRitchie); Style.NamespaceIndentation = FormatStyle::NI_All; CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation,