clang-format: Avoid line breaks before the first <<.
This puts a slight penalty on the linebreak before the first "<<", so
that clang-format generally tries to keep things on the first line.
User feedback has shown that this is generally desirable.
Before:
llvm::outs()
<< "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =" << aaaaaaaaaaaaaaaaaaaaaaaaaaa;
After:
llvm::outs() << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ="
<< aaaaaaaaaaaaaaaaaaaaaaaaaaa;
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186115 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index f8786c8..0bfcc74 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -45,6 +45,9 @@
/// \brief The penalty for each character outside of the column limit.
unsigned PenaltyExcessCharacter;
+ /// \brief The penalty for breaking before the first "<<".
+ unsigned PenaltyBreakFirstLessLess;
+
/// \brief Set whether & and * bind to the type as opposed to the variable.
bool PointerBindsToType;
@@ -173,8 +176,9 @@
IndentWidth == R.IndentWidth &&
MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
- PenaltyBreakString == R.PenaltyBreakString &&
PenaltyBreakComment == R.PenaltyBreakComment &&
+ PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
+ PenaltyBreakString == R.PenaltyBreakString &&
PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
PointerBindsToType == R.PointerBindsToType &&
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 0dd47fe..680bb13 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -102,6 +102,8 @@
Style.ObjCSpaceBeforeProtocolList);
IO.mapOptional("PenaltyBreakComment", Style.PenaltyBreakComment);
IO.mapOptional("PenaltyBreakString", Style.PenaltyBreakString);
+ IO.mapOptional("PenaltyBreakFirstLessLess",
+ Style.PenaltyBreakFirstLessLess);
IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
Style.PenaltyReturnTypeOnItsOwnLine);
@@ -123,6 +125,13 @@
namespace clang {
namespace format {
+void setDefaultPenalties(FormatStyle &Style) {
+ Style.PenaltyBreakComment = 45;
+ Style.PenaltyBreakFirstLessLess = 100;
+ Style.PenaltyBreakString = 1000;
+ Style.PenaltyExcessCharacter = 1000000;
+}
+
FormatStyle getLLVMStyle() {
FormatStyle LLVMStyle;
LLVMStyle.AccessModifierOffset = -2;
@@ -140,10 +149,6 @@
LLVMStyle.IndentCaseLabels = false;
LLVMStyle.MaxEmptyLinesToKeep = 1;
LLVMStyle.ObjCSpaceBeforeProtocolList = true;
- LLVMStyle.PenaltyBreakComment = 45;
- LLVMStyle.PenaltyBreakString = 1000;
- LLVMStyle.PenaltyExcessCharacter = 1000000;
- LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
LLVMStyle.PointerBindsToType = false;
LLVMStyle.SpacesBeforeTrailingComments = 1;
LLVMStyle.SpacesInBracedLists = true;
@@ -152,6 +157,10 @@
LLVMStyle.UseTab = false;
LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
LLVMStyle.IndentFunctionDeclarationAfterType = false;
+
+ setDefaultPenalties(LLVMStyle);
+ LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
+
return LLVMStyle;
}
@@ -172,10 +181,6 @@
GoogleStyle.IndentCaseLabels = true;
GoogleStyle.MaxEmptyLinesToKeep = 1;
GoogleStyle.ObjCSpaceBeforeProtocolList = false;
- GoogleStyle.PenaltyBreakComment = 45;
- GoogleStyle.PenaltyBreakString = 1000;
- GoogleStyle.PenaltyExcessCharacter = 1000000;
- GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
GoogleStyle.PointerBindsToType = true;
GoogleStyle.SpacesBeforeTrailingComments = 2;
GoogleStyle.SpacesInBracedLists = false;
@@ -184,6 +189,10 @@
GoogleStyle.UseTab = false;
GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
GoogleStyle.IndentFunctionDeclarationAfterType = true;
+
+ setDefaultPenalties(GoogleStyle);
+ GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
+
return GoogleStyle;
}
@@ -503,6 +512,10 @@
const FormatToken &Current = *State.NextToken;
const FormatToken &Previous = *State.NextToken->Previous;
+ // Extra penalty that needs to be added because of the way certain line
+ // breaks are chosen.
+ unsigned ExtraPenalty = 0;
+
if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) {
// FIXME: Is this correct?
int WhitespaceLength = SourceMgr.getSpellingColumnNumber(
@@ -621,6 +634,11 @@
Line.MustBeDeclaration))
State.Stack.back().BreakBeforeParameter = true;
}
+
+ // Breaking before the first "<<" is generally not desirable.
+ if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
+ ExtraPenalty += Style.PenaltyBreakFirstLessLess;
+
} else {
if (Current.is(tok::equal) &&
(RootToken->is(tok::kw_for) || State.ParenLevel == 0) &&
@@ -699,7 +717,7 @@
}
}
- return moveStateToNextToken(State, DryRun);
+ return moveStateToNextToken(State, DryRun) + ExtraPenalty;
}
/// \brief Mark the next token as consumed in \p State and modify its stacks
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 37ac1a2..c99d2ae 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -3002,6 +3002,22 @@
verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaaaaaaaaaa: \"\n"
" << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+ // Breaking before the first "<<" is generally not desirable.
+ verifyFormat(
+ "llvm::errs()\n"
+ " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << \"aaaaaaaaaaaaaaaaaaa: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
+ getLLVMStyleWithColumns(70));
+ verifyFormat("llvm::errs() << \"aaaaaaaaaaaaaaaaaaa: \"\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << \"aaaaaaaaaaaaaaaaaaa: \"\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << \"aaaaaaaaaaaaaaaaaaa: \"\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
+ getLLVMStyleWithColumns(70));
+
verifyFormat(
"llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();");