Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -218,12 +218,24 @@ If ``true``, ``while (true) continue;`` can be put on a single line. +**AlwaysBreakAfterDeclarationReturnType** (``bool``) + If ``true``, always break after function declaration (prototype) return + types. + + More truthfully called 'break before the identifier following the type + in a function declarations'. PenaltyReturnTypeOnItsOwnLine becomes + irrelevant for function declarations. + + See also AlwaysBreakAfterDefinitionReturnType. + **AlwaysBreakAfterDefinitionReturnType** (``bool``) If ``true``, always break after function definition return types. More truthfully called 'break before the identifier following the type in a function definition'. PenaltyReturnTypeOnItsOwnLine becomes - irrelevant. + irrelevant for function definitions. + + See also AlwaysBreakAfterDeclarationReturnType. **AlwaysBreakBeforeMultilineStrings** (``bool``) If ``true``, always break before multiline string literals. Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -275,11 +275,23 @@ /// \brief The number of characters to use for indentation of ObjC blocks. unsigned ObjCBlockIndentWidth; + /// If \c true, always break after function declaration (prototype) return + /// types. + /// + /// More truthfully called 'break before the identifier following the type + /// in a function declarations'. PenaltyReturnTypeOnItsOwnLine becomes + /// irrelevant for function declarations. + /// + /// See also AlwaysBreakAfterDefinitionReturnType. + bool AlwaysBreakAfterDeclarationReturnType; + /// \brief If \c true, always break after function definition return types. /// /// More truthfully called 'break before the identifier following the type /// in a function definition'. PenaltyReturnTypeOnItsOwnLine becomes - /// irrelevant. + /// irrelevant for function definitions. + /// + /// See also AlwaysBreakAfterDeclarationReturnType. bool AlwaysBreakAfterDefinitionReturnType; /// \brief If \c true, always break after the template<...> of a @@ -433,6 +445,8 @@ AllowShortIfStatementsOnASingleLine == R.AllowShortIfStatementsOnASingleLine && AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine && + AlwaysBreakAfterDeclarationReturnType == + R.AlwaysBreakAfterDeclarationReturnType && AlwaysBreakAfterDefinitionReturnType == R.AlwaysBreakAfterDefinitionReturnType && AlwaysBreakTemplateDeclarations == Index: lib/Format/ContinuationIndenter.cpp =================================================================== --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -126,7 +126,9 @@ // Don't break after very short return types (e.g. "void") as that is often // unexpected. if (Current.is(TT_FunctionDeclarationName) && - !Style.AlwaysBreakAfterDefinitionReturnType && State.Column < 6) + !(Style.AlwaysBreakAfterDefinitionReturnType || + Style.AlwaysBreakAfterDeclarationReturnType) && + State.Column < 6) return false; return !State.Stack.back().NoLineBreak; Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -187,6 +187,8 @@ Style.AllowShortLoopsOnASingleLine); IO.mapOptional("AllowShortFunctionsOnASingleLine", Style.AllowShortFunctionsOnASingleLine); + IO.mapOptional("AlwaysBreakAfterDeclarationReturnType", + Style.AlwaysBreakAfterDeclarationReturnType); IO.mapOptional("AlwaysBreakAfterDefinitionReturnType", Style.AlwaysBreakAfterDefinitionReturnType); IO.mapOptional("AlwaysBreakTemplateDeclarations", @@ -337,6 +339,7 @@ LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.AllowShortLoopsOnASingleLine = false; + LLVMStyle.AlwaysBreakAfterDeclarationReturnType = false; LLVMStyle.AlwaysBreakAfterDefinitionReturnType = false; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; LLVMStyle.AlwaysBreakTemplateDeclarations = false; Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1537,12 +1537,15 @@ Current->MustBreakBefore = Current->MustBreakBefore || mustBreakBefore(Line, *Current); - if (Style.AlwaysBreakAfterDefinitionReturnType && InFunctionDecl && - Current->is(TT_FunctionDeclarationName) && - !Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions. + if (!Current->MustBreakBefore && InFunctionDecl && + Current->is(TT_FunctionDeclarationName)) { // FIXME: Line.Last points to other characters than tok::semi // and tok::lbrace. - Current->MustBreakBefore = true; + bool IsDefinition = !Line.Last->isOneOf(tok::semi, tok::comment); + if ((IsDefinition && Style.AlwaysBreakAfterDefinitionReturnType) || + (!IsDefinition && Style.AlwaysBreakAfterDeclarationReturnType)) + Current->MustBreakBefore = true; + } Current->CanBreakBefore = Current->MustBreakBefore || canBreakBefore(Line, *Current); Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -4868,6 +4868,84 @@ AfterType); } +TEST_F(FormatTest, AlwaysBreakAfterDeclarationReturnType) { + FormatStyle AfterType = getLLVMStyle(); + AfterType.AlwaysBreakAfterDeclarationReturnType = true; + verifyFormat("const char *\n" + "bar(void);\n" // Break here. + "const char *f(void) {\n" // No break here. + " f();\n" + " return \"\";\n" + "}\n", + AfterType); + verifyFormat("template \n" + "T *\n" + "f(T &c);\n" // Break here. + "template T *f(T &c) {\n" // No break here. + " f(c);\n" + " return NULL;\n" + "}\n", + AfterType); + AfterType.BreakBeforeBraces = FormatStyle::BS_Stroustrup; + verifyFormat("const char *\n" + "bar(void);\n" // Break here. + "const char *f(void)\n" // No break here. + "{\n" + " f();\n" + " return \"\";\n" + "}\n", + AfterType); + verifyFormat("template \n" + "T *\n" + "f(T &c);\n" // Break here. + "template T *f(T &c)\n" // No break here. + "{\n" + " f(c);\n" + " return NULL;\n" + "}\n", + AfterType); +} + +TEST_F(FormatTest, AlwaysBreakAfterDeclarationAndDefinitionReturnTypeMixed) { + FormatStyle AfterType = getLLVMStyle(); + AfterType.AlwaysBreakAfterDeclarationReturnType = false; + AfterType.AlwaysBreakAfterDefinitionReturnType = false; + verifyFormat("void f(void) {\n" // No break here. + " f();\n" + " f();\n" + "}\n" + "void bar(void);\n", // No break here. + AfterType); + AfterType.AlwaysBreakAfterDeclarationReturnType = true; + AfterType.AlwaysBreakAfterDefinitionReturnType = false; + verifyFormat("void f(void) {\n" // No break here. + " f();\n" + " f();\n" + "}\n" + "void\n" + "bar(void);\n", // Break here. + AfterType); + AfterType.AlwaysBreakAfterDeclarationReturnType = false; + AfterType.AlwaysBreakAfterDefinitionReturnType = true; + verifyFormat("void\n" + "f(void) {\n" // Break here. + " f();\n" + " f();\n" + "}\n" + "void bar(void);\n", // No break here. + AfterType); + AfterType.AlwaysBreakAfterDeclarationReturnType = true; + AfterType.AlwaysBreakAfterDefinitionReturnType = true; + verifyFormat("void\n" + "f(void) {\n" // Break here. + " f();\n" + " f();\n" + "}\n" + "void\n" + "bar(void);\n", // Break here. + AfterType); +} + TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { FormatStyle NoBreak = getLLVMStyle(); NoBreak.AlwaysBreakBeforeMultilineStrings = false; @@ -9382,6 +9460,7 @@ CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine); CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine); + CHECK_PARSE_BOOL(AlwaysBreakAfterDeclarationReturnType); CHECK_PARSE_BOOL(AlwaysBreakAfterDefinitionReturnType); CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations); CHECK_PARSE_BOOL(BinPackParameters);