Index: cfe/trunk/docs/ClangFormatStyleOptions.rst =================================================================== --- cfe/trunk/docs/ClangFormatStyleOptions.rst +++ cfe/trunk/docs/ClangFormatStyleOptions.rst @@ -218,12 +218,19 @@ If ``true``, ``while (true) continue;`` can be put on a single line. -**AlwaysBreakAfterDefinitionReturnType** (``bool``) - If ``true``, always break after function definition return types. +**AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``) + The function definition return type breaking style to use. + + Possible values: + + * ``DRTBS_None`` (in configuration: ``None``) + Break after return type automatically. + ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. + * ``DRTBS_All`` (in configuration: ``All``) + Always break after the return type. + * ``DRTBS_TopLevel`` (in configuration: ``TopLevel``) + Always break after the return types of top level functions. - 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. Index: cfe/trunk/include/clang/Format/Format.h =================================================================== --- cfe/trunk/include/clang/Format/Format.h +++ cfe/trunk/include/clang/Format/Format.h @@ -112,12 +112,19 @@ /// single line. bool AllowShortLoopsOnASingleLine; - /// \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 Different ways to break after the function definition return type. + enum DefinitionReturnTypeBreakingStyle { + /// Break after return type automatically. + /// \c PenaltyReturnTypeOnItsOwnLine is taken into account. + DRTBS_None, + /// Always break after the return type. + DRTBS_All, + /// Always break after the return types of top level functions. + DRTBS_TopLevel, + }; + + /// \brief The function definition return type breaking style to use. + DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType; /// \brief If \c true, always break before multiline string literals. /// Index: cfe/trunk/lib/Format/ContinuationIndenter.cpp =================================================================== --- cfe/trunk/lib/Format/ContinuationIndenter.cpp +++ cfe/trunk/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.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_None && + State.Column < 6) return false; return !State.Stack.back().NoLineBreak; Index: cfe/trunk/lib/Format/Format.cpp =================================================================== --- cfe/trunk/lib/Format/Format.cpp +++ cfe/trunk/lib/Format/Format.cpp @@ -99,6 +99,18 @@ } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) { + IO.enumCase(Value, "None", FormatStyle::DRTBS_None); + IO.enumCase(Value, "All", FormatStyle::DRTBS_All); + IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel); + + // For backward compatibility. + IO.enumCase(Value, "false", FormatStyle::DRTBS_None); + IO.enumCase(Value, "true", FormatStyle::DRTBS_All); + } +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, @@ -338,7 +350,7 @@ LLVMStyle.AllowShortCaseLabelsOnASingleLine = false; LLVMStyle.AllowShortIfStatementsOnASingleLine = false; LLVMStyle.AllowShortLoopsOnASingleLine = false; - LLVMStyle.AlwaysBreakAfterDefinitionReturnType = false; + LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None; LLVMStyle.AlwaysBreakBeforeMultilineStrings = false; LLVMStyle.AlwaysBreakTemplateDeclarations = false; LLVMStyle.BinPackParameters = true; @@ -463,6 +475,8 @@ FormatStyle MozillaStyle = getLLVMStyle(); MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false; MozillaStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; + MozillaStyle.AlwaysBreakAfterDefinitionReturnType = + FormatStyle::DRTBS_TopLevel; MozillaStyle.AlwaysBreakTemplateDeclarations = true; MozillaStyle.BreakConstructorInitializersBeforeComma = true; MozillaStyle.ConstructorInitializerIndentWidth = 2; @@ -498,7 +512,7 @@ FormatStyle getGNUStyle() { FormatStyle Style = getLLVMStyle(); - Style.AlwaysBreakAfterDefinitionReturnType = true; + Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; Style.BreakBeforeBraces = FormatStyle::BS_GNU; Style.BreakBeforeTernaryOperators = true; Index: cfe/trunk/lib/Format/TokenAnnotator.cpp =================================================================== --- cfe/trunk/lib/Format/TokenAnnotator.cpp +++ cfe/trunk/lib/Format/TokenAnnotator.cpp @@ -1539,8 +1539,11 @@ Current->MustBreakBefore = Current->MustBreakBefore || mustBreakBefore(Line, *Current); - if (Style.AlwaysBreakAfterDefinitionReturnType && InFunctionDecl && - Current->is(TT_FunctionDeclarationName) && + if ((Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_All || + (Style.AlwaysBreakAfterDefinitionReturnType == + 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: cfe/trunk/unittests/Format/FormatTest.cpp =================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp +++ cfe/trunk/unittests/Format/FormatTest.cpp @@ -4618,30 +4618,50 @@ " \"c\";"); } -TEST_F(FormatTest, AlwaysBreakAfterDefinitionReturnType) { - FormatStyle AfterType = getLLVMStyle(); - AfterType.AlwaysBreakAfterDefinitionReturnType = true; +TEST_F(FormatTest, DefinitionReturnTypeBreakingStyle) { + FormatStyle Style = getLLVMStyle(); + Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_TopLevel; + verifyFormat("class C {\n" + " int f() { return 1; }\n" + "};\n" + "int\n" + "f() {\n" + " return 1;\n" + "}", + Style); + Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; + 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. @@ -4649,7 +4669,7 @@ " return NULL;\n" "}\n" "template T *f(T &c);\n", // No break here. - AfterType); + Style); } TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { @@ -9041,7 +9061,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); @@ -9174,6 +9193,15 @@ FormatStyle::BS_Allman); CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU); + Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; + CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None", + AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None); + CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: All", + AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_All); + CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: TopLevel", + AlwaysBreakAfterDefinitionReturnType, + FormatStyle::DRTBS_TopLevel); + Style.NamespaceIndentation = FormatStyle::NI_All; CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation, FormatStyle::NI_None);