strager updated this revision to Diff 35038.
strager added a comment.
Fix missing IsDefinition check in ContinuationIndenter::canBreak.
http://reviews.llvm.org/D10370
Files:
docs/ClangFormatStyleOptions.rst
include/clang/Format/Format.h
lib/Format/ContinuationIndenter.cpp
lib/Format/Format.cpp
lib/Format/TokenAnnotator.cpp
lib/Format/TokenAnnotator.h
unittests/Format/FormatTest.cpp
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -4658,6 +4658,44 @@
" \"c\";");
}
+TEST_F(FormatTest, DeclarationReturnTypeBreakingStyle) {
+ FormatStyle Style = getLLVMStyle();
+ Style.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_TopLevel;
+ verifyFormat("class C {\n"
+ " int f();\n"
+ "};\n"
+ "int\n"
+ "f();",
+ Style);
+ Style.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+ verifyFormat("class C {\n"
+ " int\n"
+ " f();\n"
+ "};\n"
+ "int\n"
+ "f();",
+ Style);
+ verifyFormat("const char *f(void) { return \"\"; }\n"
+ "const char *\n"
+ "bar(void);\n",
+ Style);
+ verifyFormat("template <class T> T *f(T &c) { return NULL; }\n"
+ "template <class T>\n"
+ "T *\n"
+ "f(T &c);\n",
+ Style);
+ Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+ verifyFormat("const char *f(void) { return \"\"; }\n"
+ "const char *\n"
+ "bar(void);\n",
+ Style);
+ verifyFormat("template <class T> T *f(T &c) { return NULL; }\n"
+ "template <class T>\n"
+ "T *\n"
+ "f(T &c);\n",
+ Style);
+}
+
TEST_F(FormatTest, DefinitionReturnTypeBreakingStyle) {
FormatStyle Style = getLLVMStyle();
Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_TopLevel;
@@ -4738,6 +4776,46 @@
Style);
}
+TEST_F(FormatTest, AlwaysBreakAfterDeclarationAndDefinitionReturnTypeMixed) {
+ FormatStyle AfterType = getLLVMStyle();
+ AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_None;
+ AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
+ verifyFormat("void f(void) {\n" // No break here.
+ " f();\n"
+ " f();\n"
+ "}\n"
+ "void bar(void);\n", // No break here.
+ AfterType);
+ AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+ AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
+ verifyFormat("void f(void) {\n" // No break here.
+ " f();\n"
+ " f();\n"
+ "}\n"
+ "void\n"
+ "bar(void);\n", // Break here.
+ AfterType);
+ AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_None;
+ AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
+ verifyFormat("void\n"
+ "f(void) {\n" // Break here.
+ " f();\n"
+ " f();\n"
+ "}\n"
+ "void bar(void);\n", // No break here.
+ AfterType);
+ AfterType.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+ AfterType.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
+ 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;
@@ -9409,6 +9487,15 @@
CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);
CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces, FormatStyle::BS_WebKit);
+ Style.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_All;
+ CHECK_PARSE("AlwaysBreakAfterDeclarationReturnType: None",
+ AlwaysBreakAfterDeclarationReturnType, FormatStyle::DRTBS_None);
+ CHECK_PARSE("AlwaysBreakAfterDeclarationReturnType: All",
+ AlwaysBreakAfterDeclarationReturnType, FormatStyle::DRTBS_All);
+ CHECK_PARSE("AlwaysBreakAfterDeclarationReturnType: TopLevel",
+ AlwaysBreakAfterDeclarationReturnType,
+ FormatStyle::DRTBS_TopLevel);
+
Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All;
CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None",
AlwaysBreakAfterDefinitionReturnType, FormatStyle::DRTBS_None);
Index: lib/Format/TokenAnnotator.h
===================================================================
--- lib/Format/TokenAnnotator.h
+++ lib/Format/TokenAnnotator.h
@@ -86,6 +86,15 @@
return startsWith(First, Tokens...);
}
+ /// \c true if this line looks like a function definition instead of a
+ /// function declaration. Asserts MightBeFunctionDecl.
+ bool mightBeFunctionDefinition() const {
+ assert(MightBeFunctionDecl);
+ // FIXME: Line.Last points to other characters than tok::semi
+ // and tok::lbrace.
+ return !Last->isOneOf(tok::semi, tok::comment);
+ }
+
FormatToken *First;
FormatToken *Last;
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1593,15 +1593,16 @@
Current->MustBreakBefore =
Current->MustBreakBefore || mustBreakBefore(Line, *Current);
- 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.
- Current->MustBreakBefore = true;
+ if (!Current->MustBreakBefore && InFunctionDecl &&
+ Current->is(TT_FunctionDeclarationName)) {
+ FormatStyle::ReturnTypeBreakingStyle BreakStyle =
+ Line.mightBeFunctionDefinition()
+ ? Style.AlwaysBreakAfterDefinitionReturnType
+ : Style.AlwaysBreakAfterDeclarationReturnType;
+ if ((BreakStyle == FormatStyle::DRTBS_All ||
+ (BreakStyle == FormatStyle::DRTBS_TopLevel && Line.Level == 0)))
+ Current->MustBreakBefore = true;
+ }
Current->CanBreakBefore =
Current->MustBreakBefore || canBreakBefore(Line, *Current);
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -102,8 +102,8 @@
}
};
-template <> struct ScalarEnumerationTraits<FormatStyle::DefinitionReturnTypeBreakingStyle> {
- static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) {
+template <> struct ScalarEnumerationTraits<FormatStyle::ReturnTypeBreakingStyle> {
+ static void enumeration(IO &IO, FormatStyle::ReturnTypeBreakingStyle &Value) {
IO.enumCase(Value, "None", FormatStyle::DRTBS_None);
IO.enumCase(Value, "All", FormatStyle::DRTBS_All);
IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel);
@@ -213,6 +213,8 @@
Style.AllowShortIfStatementsOnASingleLine);
IO.mapOptional("AllowShortLoopsOnASingleLine",
Style.AllowShortLoopsOnASingleLine);
+ IO.mapOptional("AlwaysBreakAfterDeclarationReturnType",
+ Style.AlwaysBreakAfterDeclarationReturnType);
IO.mapOptional("AlwaysBreakAfterDefinitionReturnType",
Style.AlwaysBreakAfterDefinitionReturnType);
IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
@@ -355,6 +357,7 @@
LLVMStyle.AllowShortCaseLabelsOnASingleLine = false;
LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
LLVMStyle.AllowShortLoopsOnASingleLine = false;
+ LLVMStyle.AlwaysBreakAfterDeclarationReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_None;
LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
LLVMStyle.AlwaysBreakTemplateDeclarations = false;
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -125,10 +125,14 @@
// Don't break after very short return types (e.g. "void") as that is often
// unexpected.
- if (Current.is(TT_FunctionDeclarationName) &&
- Style.AlwaysBreakAfterDefinitionReturnType == FormatStyle::DRTBS_None &&
- State.Column < 6)
- return false;
+ if (Current.is(TT_FunctionDeclarationName) && State.Column < 6) {
+ FormatStyle::ReturnTypeBreakingStyle BreakStyle =
+ State.Line->mightBeFunctionDefinition()
+ ? Style.AlwaysBreakAfterDefinitionReturnType
+ : Style.AlwaysBreakAfterDeclarationReturnType;
+ if (BreakStyle == FormatStyle::DRTBS_None)
+ return false;
+ }
return !State.Stack.back().NoLineBreak;
}
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -112,8 +112,9 @@
/// single line.
bool AllowShortLoopsOnASingleLine;
- /// \brief Different ways to break after the function definition return type.
- enum DefinitionReturnTypeBreakingStyle {
+ /// \brief Different ways to break after the function declaration or
+ /// definition return type.
+ enum ReturnTypeBreakingStyle {
/// Break after return type automatically.
/// \c PenaltyReturnTypeOnItsOwnLine is taken into account.
DRTBS_None,
@@ -123,8 +124,11 @@
DRTBS_TopLevel,
};
+ /// \brief The function declaration return type breaking style to use.
+ ReturnTypeBreakingStyle AlwaysBreakAfterDeclarationReturnType;
+
/// \brief The function definition return type breaking style to use.
- DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType;
+ ReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType;
/// \brief If \c true, always break before multiline string literals.
///
@@ -459,6 +463,8 @@
AllowShortIfStatementsOnASingleLine ==
R.AllowShortIfStatementsOnASingleLine &&
AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
+ AlwaysBreakAfterDeclarationReturnType ==
+ R.AlwaysBreakAfterDeclarationReturnType &&
AlwaysBreakAfterDefinitionReturnType ==
R.AlwaysBreakAfterDefinitionReturnType &&
AlwaysBreakBeforeMultilineStrings ==
Index: docs/ClangFormatStyleOptions.rst
===================================================================
--- docs/ClangFormatStyleOptions.rst
+++ docs/ClangFormatStyleOptions.rst
@@ -218,7 +218,21 @@
If ``true``, ``while (true) continue;`` can be put on a
single line.
-**AlwaysBreakAfterDefinitionReturnType** (``DefinitionReturnTypeBreakingStyle``)
+**AlwaysBreakAfterDeclarationReturnType** (``ReturnTypeBreakingStyle``)
+ The function declaration 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.
+
+
+**AlwaysBreakAfterDefinitionReturnType** (``ReturnTypeBreakingStyle``)
The function definition return type breaking style to use.
Possible values:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits