Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -218,13 +218,6 @@ If ``true``, ``while (true) continue;`` can be put on a single line. -**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. - **AlwaysBreakBeforeMultilineStrings** (``bool``) If ``true``, always break before multiline string literals. @@ -245,6 +238,19 @@ If ``false``, a function declaration's or function definition's parameters will either all be on the same line or will have one line each. +**BreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``) + The function definition return type breaking style to use. + + Possible values: + + * ``DRTBS_Auto`` (in configuration: ``Auto``) + Break after return type automatically. ``PenaltyReturnTypeOnItsOwnLine`` + is taken into account. + * ``DRTBS_Always`` (in configuration: ``Always``) + Always break after the return type. + * ``DRTBS_TopLevel`` (in configuration: ``TopLevel``) + Always break after the return types of top level functions. + **BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) The way to wrap binary operators. Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -275,13 +275,6 @@ /// \brief The number of characters to use for indentation of ObjC blocks. unsigned ObjCBlockIndentWidth; - /// \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. - bool AlwaysBreakAfterDefinitionReturnType; - /// \brief If \c true, always break after the template<...> of a /// template declaration. bool AlwaysBreakTemplateDeclarations; @@ -344,6 +337,20 @@ /// \brief The brace breaking style to use. BraceBreakingStyle BreakBeforeBraces; + /// \brief Different ways to break after the function definition return type. + enum DefinitionReturnTypeBreakingStyle { + /// Break after return type automatically. \c PenaltyReturnTypeOnItsOwnLine + /// is taken into account. + DRTBS_Auto, + /// Always break after the return type. + DRTBS_Always, + /// Always break after the return types of top level functions. + DRTBS_TopLevel, + }; + + /// \brief The function definition return type breaking style to use. + DefinitionReturnTypeBreakingStyle BreakAfterDefinitionReturnType; + /// \brief If \c true, format braced lists as best suited for C++11 braced /// lists. /// @@ -438,14 +445,14 @@ AllowShortIfStatementsOnASingleLine == R.AllowShortIfStatementsOnASingleLine && AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine && - AlwaysBreakAfterDefinitionReturnType == - R.AlwaysBreakAfterDefinitionReturnType && AlwaysBreakTemplateDeclarations == R.AlwaysBreakTemplateDeclarations && AlwaysBreakBeforeMultilineStrings == R.AlwaysBreakBeforeMultilineStrings && BinPackParameters == R.BinPackParameters && BinPackArguments == R.BinPackArguments && + BreakAfterDefinitionReturnType == + R.BreakAfterDefinitionReturnType && BreakBeforeBinaryOperators == R.BreakBeforeBinaryOperators && BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakBeforeBraces == R.BreakBeforeBraces && Index: lib/Format/ContinuationIndenter.cpp =================================================================== --- lib/Format/ContinuationIndenter.cpp +++ lib/Format/ContinuationIndenter.cpp @@ -126,7 +126,8 @@ // 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.BreakAfterDefinitionReturnType == FormatStyle::DRTBS_Auto && + State.Column < 6) return false; return !State.Stack.back().NoLineBreak; Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -99,6 +99,14 @@ } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) { + IO.enumCase(Value, "Auto", FormatStyle::DRTBS_Auto); + IO.enumCase(Value, "Always", FormatStyle::DRTBS_Always); + IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, @@ -188,12 +196,12 @@ Style.AllowShortLoopsOnASingleLine); IO.mapOptional("AllowShortFunctionsOnASingleLine", Style.AllowShortFunctionsOnASingleLine); - IO.mapOptional("AlwaysBreakAfterDefinitionReturnType", - Style.AlwaysBreakAfterDefinitionReturnType); IO.mapOptional("AlwaysBreakTemplateDeclarations", Style.AlwaysBreakTemplateDeclarations); IO.mapOptional("AlwaysBreakBeforeMultilineStrings", Style.AlwaysBreakBeforeMultilineStrings); + IO.mapOptional("BreakAfterDefinitionReturnType", + Style.BreakAfterDefinitionReturnType); IO.mapOptional("BreakBeforeBinaryOperators", Style.BreakBeforeBinaryOperators); IO.mapOptional("BreakBeforeTernaryOperators", @@ -265,6 +273,14 @@ } IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens); IO.mapOptional("DisableFormat", Style.DisableFormat); + + // For backward compatibility. + bool AlwaysBreakAfterDefinitionReturnType = false; + IO.mapOptional("AlwaysBreakAfterDefinitionReturnType", + AlwaysBreakAfterDefinitionReturnType); + if (AlwaysBreakAfterDefinitionReturnType) { + Style.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_Always; + } } }; @@ -338,11 +354,11 @@ LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.AllowShortLoopsOnASingleLine = false; - LLVMStyle.AlwaysBreakAfterDefinitionReturnType = false; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; LLVMStyle.AlwaysBreakTemplateDeclarations = false; LLVMStyle.BinPackParameters = true; LLVMStyle.BinPackArguments = true; + LLVMStyle.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_Auto; LLVMStyle.BreakBeforeBinaryOperators = FormatStyle::BOS_None; LLVMStyle.BreakBeforeTernaryOperators = true; LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach; @@ -462,6 +478,7 @@ FormatStyle getMozillaStyle() { FormatStyle MozillaStyle = getLLVMStyle(); MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; + MozillaStyle.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_TopLevel; MozillaStyle.Cpp11BracedListStyle = false; MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; MozillaStyle.DerivePointerAlignment = true; @@ -496,7 +513,7 @@ FormatStyle getGNUStyle() { FormatStyle Style = getLLVMStyle(); - Style.AlwaysBreakAfterDefinitionReturnType = true; + Style.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_Always; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; Style.BreakBeforeBraces = FormatStyle::BS_GNU; Style.BreakBeforeTernaryOperators = true; Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -1539,8 +1539,10 @@ Current->MustBreakBefore = Current->MustBreakBefore || mustBreakBefore(Line, *Current); - if (Style.AlwaysBreakAfterDefinitionReturnType && InFunctionDecl && - Current->is(TT_FunctionDeclarationName) && + if ((Style.BreakAfterDefinitionReturnType == FormatStyle::DRTBS_Always || + (Style.BreakAfterDefinitionReturnType == FormatStyle::DRTBS_TopLevel && + Line.Level == 0)) && + InFunctionDecl && Current->is(TT_FunctionDeclarationName) && !Line.Last->isOneOf(tok::semi, tok::comment)) // Only for definitions. // FIXME: Line.Last points to other characters than tok::semi // and tok::lbrace. Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -4595,30 +4595,50 @@ " \"c\";"); } -TEST_F(FormatTest, AlwaysBreakAfterDefinitionReturnType) { - FormatStyle AfterType = getLLVMStyle(); - AfterType.AlwaysBreakAfterDefinitionReturnType = true; +TEST_F(FormatTest, DefinitionReturnTypeBreakingStyle) { + FormatStyle Style = getLLVMStyle(); + Style.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_TopLevel; + verifyFormat("class C {\n" + " int f() { return 1; }\n" + "};\n" + "int\n" + "f() {\n" + " return 1;\n" + "}", + Style); + Style.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_Always; + verifyFormat("class C {\n" + " int\n" + " f() {\n" + " return 1;\n" + " }\n" + "};\n" + "int\n" + "f() {\n" + " return 1;\n" + "}", + Style); verifyFormat("const char *\n" "f(void) {\n" // Break here. " return \"\";\n" "}\n" "const char *bar(void);\n", // No break here. - AfterType); + Style); verifyFormat("template \n" "T *\n" "f(T &c) {\n" // Break here. " return NULL;\n" "}\n" "template T *f(T &c);\n", // No break here. - AfterType); - AfterType.BreakBeforeBraces = FormatStyle::BS_Stroustrup; + Style); + Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup; verifyFormat("const char *\n" "f(void)\n" // Break here. "{\n" " return \"\";\n" "}\n" "const char *bar(void);\n", // No break here. - AfterType); + Style); verifyFormat("template \n" "T *\n" // Problem here: no line break "f(T &c)\n" // Break here. @@ -4626,7 +4646,7 @@ " return NULL;\n" "}\n" "template T *f(T &c);\n", // No break here. - AfterType); + Style); } TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { @@ -9018,7 +9038,6 @@ CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine); CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine); - CHECK_PARSE_BOOL(AlwaysBreakAfterDefinitionReturnType); CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations); CHECK_PARSE_BOOL(BinPackParameters); CHECK_PARSE_BOOL(BinPackArguments); @@ -9151,6 +9170,14 @@ FormatStyle::BS_Allman); CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU); + Style.BreakAfterDefinitionReturnType = FormatStyle::DRTBS_Always; + CHECK_PARSE("BreakAfterDefinitionReturnType: Auto", BreakAfterDefinitionReturnType, + FormatStyle::DRTBS_Auto); + CHECK_PARSE("BreakAfterDefinitionReturnType: Always", BreakAfterDefinitionReturnType, + FormatStyle::DRTBS_Always); + CHECK_PARSE("BreakAfterDefinitionReturnType: TopLevel", BreakAfterDefinitionReturnType, + FormatStyle::DRTBS_TopLevel); + Style.NamespaceIndentation = FormatStyle::NI_All; CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation, FormatStyle::NI_None);