This fixes llvm.org/PR15033.
Also: Always break before a parameter, if the previous parameter was
split over multiple lines. This was necessary to make the right
decisions in for-loops, almost always makes the code more readable and
also fixes llvm.org/PR14873.
Before:
for (llvm::ArrayRef<NamedDecl *>::iterator I = FD->getDeclsInPrototypeScope()
.begin(), E = FD->getDeclsInPrototypeScope().end();
I != E; ++I) {
}
foo(bar(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccccccccccc), d, bar(e, f));
After:
for (llvm::ArrayRef<NamedDecl *>::iterator
I = FD->getDeclsInPrototypeScope().begin(),
E = FD->getDeclsInPrototypeScope().end();
I != E; ++I) {
}
foo(bar(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
ccccccccccccccccccccccccccccc),
d, bar(e, f));
llvm-svn: 175741
tooling::Replacements Replaces;
};
+static bool isVarDeclName(const AnnotatedToken &Tok) {
+ return Tok.Parent != NULL && Tok.is(tok::identifier) &&
+ (Tok.Parent->Type == TT_PointerOrReference ||
+ Tok.Parent->is(tok::identifier));
+}
+
class UnwrappedLineFormatter {
public:
UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
State.Stack.back().ColonPos =
State.Column + Current.FormatTok.TokenLength;
}
- } else if (Previous.Type == TT_ObjCMethodExpr) {
+ } else if (Previous.Type == TT_ObjCMethodExpr || isVarDeclName(Current)) {
State.Column = State.Stack.back().Indent + 4;
} else {
State.Column = State.Stack.back().Indent;
(!Style.AllowAllParametersOfDeclarationOnNextLine &&
Line.MustBeDeclaration))
State.Stack.back().BreakBeforeParameter = true;
+ }
+ if (Newline) {
// Any break on this level means that the parent level has been broken
// and we need to avoid bin packing there.
for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
State.Stack.back().FirstLessLess = State.Column;
if (Current.is(tok::question))
State.Stack.back().QuestionColumn = State.Column;
- if (Current.Type == TT_CtorInitializerColon &&
- Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
- State.Stack.back().AvoidBinPacking = true;
- if (Current.is(tok::l_brace) && Current.MatchingParen != NULL &&
- !Current.MatchingParen->MustBreakBefore) {
- if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())
- State.Stack.back().BreakBeforeParameter = true;
+ if (Current.Type == TT_CtorInitializerColon) {
+ if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
+ State.Stack.back().AvoidBinPacking = true;
+ State.Stack.back().BreakBeforeParameter = false;
}
// Insert scopes created by fake parenthesis.
if (State.NextToken->Parent->is(tok::comma) &&
State.Stack.back().BreakBeforeParameter &&
!isTrailingComment(*State.NextToken) &&
- State.NextToken->isNot(tok::r_paren))
+ State.NextToken->isNot(tok::r_paren) &&
+ State.NextToken->isNot(tok::r_brace))
return true;
// FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
// out whether it is the first parameter. Clean this up.
}
// In for-loops, prefer breaking at ',' and ';'.
- if (Line.First.is(tok::kw_for) &&
- (Left.isNot(tok::comma) && Left.isNot(tok::semi)))
- return 20;
+ if (Line.First.is(tok::kw_for) && Left.is(tok::equal))
+ return 4;
if (Left.is(tok::semi))
return 0;
if (Left.Type == TT_RangeBasedForLoopColon ||
Left.Type == TT_InheritanceColon)
return true;
+ if (Right.Type == TT_RangeBasedForLoopColon)
+ return false;
if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser ||
Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr ||
Left.is(tok::question) || Left.is(tok::kw_operator))
// change the "binding" behavior of a comment.
return false;
+ // FIXME: We can probably remove this special case once we have implemented
+ // breaking after types in general.
+ if (Line.First.is(tok::kw_for) && !Right.Children.empty() &&
+ Right.Children[0].is(tok::equal))
+ return true;
+
// Allow breaking after a trailing 'const', e.g. after a method declaration,
// unless it is follow by ';', '{' or '='.
if (Left.is(tok::kw_const) && Left.Parent != NULL &&
verifyFormat(
"for (MachineFun::iterator IIII = PrevIt, EEEE = F.end(); IIII != EEEE;\n"
" ++IIIII) {\n}");
- verifyFormat("for (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaa =\n"
- " aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa;\n"
+ verifyFormat("for (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " aaaaaaaaaaa = aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa;\n"
" aaaaaaaaaaa != aaaaaaaaaaaaaaaaaaa; ++aaaaaaaaaaa) {\n}");
+ verifyFormat("for (llvm::ArrayRef<NamedDecl *>::iterator\n"
+ " I = FD->getDeclsInPrototypeScope().begin(),\n"
+ " E = FD->getDeclsInPrototypeScope().end();\n"
+ " I != E; ++I) {\n}");
// FIXME: Not sure whether we want extra identation in line 3 here:
verifyFormat(
"#define A B\n"
" withMoreParamters,\n"
" whichStronglyInfluenceTheLayout),\n"
- " andMoreParameters), trailing);",
+ " andMoreParameters),\n"
+ " trailing);",
getLLVMStyleWithColumns(69));
}
"unsigned Indent =\n"
" format(TheLine.First, IndentForLevel[TheLine.Level] >= 0\n"
" ? IndentForLevel[TheLine.Level]\n"
- " : TheLine * 2, TheLine.InPPDirective,\n"
- " PreviousEndOfLineColumn);",
+ " : TheLine * 2,\n"
+ " TheLine.InPPDirective, PreviousEndOfLineColumn);",
getLLVMStyleWithColumns(70));
}
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa),\n"
" bbbbbbbbbbbbbbbbbbbbbbbbb =\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(bbbbbbbbbbbbbbbb);");
-
- // FIXME: This is bad as we hide "d".
verifyFormat(
- "bool aaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb &&\n"
- " cccccccccccccccccccccccccccc, d = e && f;");
+ "bool aaaaaaaaaaaaaaaaaaaaa =\n"
+ " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb && cccccccccccccccccccccccccccc,\n"
+ " d = e && f;");
}
}
TEST_F(FormatTest, LayoutTokensFollowingBlockInParentheses) {
+ // FIXME: This is bad, find a better and more generic solution.
verifyFormat(
"Aaa({\n"
" int i;\n"
- "}, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
- " ccccccccccccccccc));");
+ "},\n"
+ " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
+ " ccccccccccccccccc));");
}
TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {