diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 44a91a96ecb94c1f9bc50f2b013db598308d065c..2bd533222769b2161d7ce72142c49cd932f480ba 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -258,6 +258,12 @@ private: 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, @@ -512,7 +518,7 @@ private: 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; @@ -610,7 +616,9 @@ private: (!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) { @@ -634,13 +642,10 @@ private: 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. @@ -908,7 +913,8 @@ private: 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. diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 2bce7c0f34904f0a6c0e1b983a339b3696b7ce9c..dcbdb786fae643751f1fa091187012f15f276068 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -886,9 +886,8 @@ unsigned TokenAnnotator::splitPenalty(const AnnotatedLine &Line, } // 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; @@ -1066,6 +1065,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, 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)) @@ -1078,6 +1079,12 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, // 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 && diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index ca522084d5ef5cc2f5259bec76d35dd55324a147..90813042dafd64c9f7eb1a8c48178c4a01029423 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -278,9 +278,13 @@ TEST_F(FormatTest, FormatsForLoop) { 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::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( @@ -1012,7 +1016,8 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { "#define A B\n" " withMoreParamters,\n" " whichStronglyInfluenceTheLayout),\n" - " andMoreParameters), trailing);", + " andMoreParameters),\n" + " trailing);", getLLVMStyleWithColumns(69)); } @@ -1398,8 +1403,8 @@ TEST_F(FormatTest, BreaksConditionalExpressions) { "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)); } @@ -1414,11 +1419,10 @@ TEST_F(FormatTest, DeclarationsOfMultipleVariables) { " 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;"); } @@ -2066,11 +2070,13 @@ TEST_F(FormatTest, LayoutBraceInitializersInReturnStatement) { } 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) {