diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -720,8 +720,9 @@ (Previous.is(tok::l_brace) && Previous.isNot(BK_Block) && Style.Cpp11BracedListStyle)) && State.Column > getNewLineColumn(State) && - (!Previous.Previous || !Previous.Previous->isOneOf( - tok::kw_for, tok::kw_while, tok::kw_switch)) && + (!Previous.Previous || + !Previous.Previous->isOneOf(TT_CastRParen, tok::kw_for, tok::kw_while, + tok::kw_switch)) && // Don't do this for simple (no expressions) one-argument function calls // as that feels like needlessly wasting whitespace, e.g.: // 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 @@ -5006,7 +5006,21 @@ return false; } const FormatToken *Previous = Right.MatchingParen->Previous; - return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf())); + if (Previous && (Previous->is(tok::kw_for) || Previous->isIf())) + return false; + if (Right.Next) { + // Avoid breaking when there is a left parens immediately following + // a right parens, such as in cast operators and indirect function calls. + if (Right.Next->is(tok::l_paren)) + return false; + // Avoid breaking between two consecutive right parens at outermost + // nesting or when dereferencing a function pointer. + if (Right.Next->is(tok::r_paren) && + (Right.NestingLevel == 0 || Previous->is(tok::star))) { + return false; + } + } + return true; } // Allow breaking after a trailing annotation, e.g. after a method 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 @@ -7225,7 +7225,7 @@ "void functionDecl(int A, int B,\n" " int C);"), format(Input, Style)); - // However, BAS_AlwaysBreak should take precedence over + // However, BAS_AlwaysBreak and BAS_BlockIndent should take precedence over // AllowAllArgumentsOnNextLine. Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; EXPECT_EQ(StringRef("functionCall(\n" @@ -7233,6 +7233,14 @@ "void functionDecl(\n" " int A, int B, int C);"), format(Input, Style)); + Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + EXPECT_EQ(StringRef("functionCall(\n" + " paramA, paramB, paramC\n" + ");\n" + "void functionDecl(\n" + " int A, int B, int C\n" + ");"), + format(Input, Style)); // When AllowAllArgumentsOnNextLine is set, we prefer breaking before the // first argument. @@ -8435,6 +8443,54 @@ " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)) &&\n" " aaaaaaaaaaaaaaaa);", Style); + + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BinPackArguments = false; + Style.BinPackParameters = false; + verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaa aaaaaaaa,\n" + " aaaaaaaaa aaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + ") {}", + Style); + verifyFormat("SomeLongVariableName->someVeryLongFunctionName(\n" + " aaaaaaaaaaa aaaaaaaaa,\n" + " aaaaaaaaaaa aaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + ");", + Style); + verifyFormat("SomeLongVariableName->someFunction(foooooooo(\n" + " aaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + "));", + Style); + verifyFormat( + "aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)\n" + "));", + Style); + verifyFormat( + "aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaa.aaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)\n" + "));", + Style); + verifyFormat( + "aaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)\n" + " ),\n" + " aaaaaaaaaaaaaaaa\n" + ");", + Style); + verifyFormat( + "aaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)\n" + " ) &&\n" + " aaaaaaaaaaaaaaaa\n" + ");", + Style); } TEST_F(FormatTest, ParenthesesAndOperandAlignment) { @@ -14354,6 +14410,13 @@ " \"long\",\n" " a);", format("someFunction(\"long long long long\", a);", Style)); + Style.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + EXPECT_EQ("someFunction(\n" + " \"long long long \"\n" + " \"long\",\n" + " a\n" + ");", + format("someFunction(\"long long long long\", a);", Style)); } TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) { @@ -16075,6 +16138,23 @@ " FoooooooooLooooong);\n" "}", Spaces); + + Spaces.AlignAfterOpenBracket = FormatStyle::BAS_BlockIndent; + verifyFormat("void foo( ) {\n" + " size_t foo = (*(function))(\n" + " Foooo, Barrrrr, Foooo, Barrrr, FoooooooooLooooong, " + "BarrrrrrrrrrrrLong,\n" + " FoooooooooLooooong\n" + " );\n" + "}", + Spaces); + verifyFormat("size_t idx = (size_t)(ptr - ((char *)file));", Spaces); + verifyFormat("size_t idx = (size_t)a;", Spaces); + verifyFormat("size_t idx = (size_t)(a - 1);", Spaces); + verifyFormat("size_t idx = (a->*foo)(a - 1);", Spaces); + verifyFormat("size_t idx = (a->foo)(a - 1);", Spaces); + verifyFormat("size_t idx = (*foo)(a - 1);", Spaces); + verifyFormat("size_t idx = (*(foo))(a - 1);", Spaces); } TEST_F(FormatTest, ConfigurableSpacesInSquareBrackets) {