diff --git a/clang/docs/ClangFormatStyleOptions.rst b/clang/docs/ClangFormatStyleOptions.rst --- a/clang/docs/ClangFormatStyleOptions.rst +++ b/clang/docs/ClangFormatStyleOptions.rst @@ -1999,6 +1999,15 @@ Base2 {}; + * ``BILS_AfterComma`` (in configuration: ``AfterComma``) + Break inheritance list only after the commas. + + .. code-block:: c++ + + class Foo : Base1, + Base2 + {}; + **BreakStringLiterals** (``bool``) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -248,6 +248,9 @@ accepts ``AllIfsAndElse`` value that allows to put "else if" and "else" short statements on a single line. (Fixes https://llvm.org/PR50019.) +- Option ``BreakInheritanceList`` gets a new style, ``AfterComma``. It breaks + only after the commas that separate the base-specifiers. + - ``git-clang-format`` no longer formats changes to symbolic links. (Fixes https://llvm.org/PR46992.) diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -1829,7 +1829,14 @@ /// Base2 /// {}; /// \endcode - BILS_AfterColon + BILS_AfterColon, + /// Break inheritance list only after the commas. + /// \code + /// class Foo : Base1, + /// Base2 + /// {}; + /// \endcode + BILS_AfterComma, }; /// The inheritance list style to use. diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -240,6 +240,7 @@ IO.enumCase(Value, "BeforeColon", FormatStyle::BILS_BeforeColon); IO.enumCase(Value, "BeforeComma", FormatStyle::BILS_BeforeComma); IO.enumCase(Value, "AfterColon", FormatStyle::BILS_AfterColon); + IO.enumCase(Value, "AfterComma", FormatStyle::BILS_AfterComma); } }; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3639,6 +3639,9 @@ if (Style.BreakInheritanceList == FormatStyle::BILS_BeforeComma && Right.is(TT_InheritanceComma)) return true; + if (Style.BreakInheritanceList == FormatStyle::BILS_AfterComma && + Left.is(TT_InheritanceComma)) + return true; if (Right.is(tok::string_literal) && Right.TokenText.startswith("R\"")) // Multiline raw string literals are special wrt. line breaks. The author // has made a deliberate choice and might have aligned the contents of the diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2290,6 +2290,28 @@ " public aaaaaaaaaaaaaaaaaaa< // break\n" " aaaaaaaaaaaaaaaa> {};", StyleWithInheritanceBreakAfterColon); + + FormatStyle StyleWithInheritanceBreakAfterComma = getLLVMStyle(); + StyleWithInheritanceBreakAfterComma.BreakInheritanceList = + FormatStyle::BILS_AfterComma; + verifyFormat("class MyClass : public X {};", + StyleWithInheritanceBreakAfterComma); + verifyFormat("class MyClass : public X,\n" + " public Y {};", + StyleWithInheritanceBreakAfterComma); + verifyFormat( + "class AAAAAAAAAAAAAAAAAAAAAA : public BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB,\n" + " public CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC " + "{};", + StyleWithInheritanceBreakAfterComma); + verifyFormat("struct aaaaaaaaaaaaa : public aaaaaaaaaaaaaaaaaaa< // break\n" + " aaaaaaaaaaaaaaaa> {};", + StyleWithInheritanceBreakAfterComma); + verifyFormat("class AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n" + " : public OnceBreak,\n" + " public AlwaysBreak,\n" + " EvenBasesFitInOneLine {};", + StyleWithInheritanceBreakAfterComma); } TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) { @@ -5585,6 +5607,12 @@ " public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", Style); + Style.BreakInheritanceList = FormatStyle::BILS_AfterComma; + verifyFormat( + "class SomeClass\n" + " : public aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " public bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb {};", + Style); } #ifndef EXPENSIVE_CHECKS @@ -13505,6 +13533,12 @@ "}\n" "}", InheritanceStyle); + InheritanceStyle.BreakInheritanceList = FormatStyle::BILS_AfterComma; + verifyFormat("class Foooooooooooooooooooooo\n" + " : public aaaaaaaaaaaaaaaaaa,\n" + " public bbbbbbbbbbbbbbbbbb {\n" + "}", + InheritanceStyle); InheritanceStyle.BreakInheritanceList = FormatStyle::BILS_AfterColon; verifyFormat("class Foooooooooooooooooooooo:\n" " public aaaaaaaaaaaaaaaaaa,\n" @@ -16843,6 +16877,8 @@ BreakConstructorInitializers, FormatStyle::BCIS_BeforeComma); Style.BreakInheritanceList = FormatStyle::BILS_BeforeColon; + CHECK_PARSE("BreakInheritanceList: AfterComma", BreakInheritanceList, + FormatStyle::BILS_AfterComma); CHECK_PARSE("BreakInheritanceList: BeforeComma", BreakInheritanceList, FormatStyle::BILS_BeforeComma); CHECK_PARSE("BreakInheritanceList: AfterColon", BreakInheritanceList,