From 562ecd4444b94fbcf9c3e860991228b1fa85e273 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Fri, 6 Sep 2013 08:08:14 +0000 Subject: [PATCH] clang-format: Fix regression introduced by r189337. Before: if (aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) ... After: if (aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) ... Also precompute startsBinaryExpression() to improve performance. llvm-svn: 190124 --- clang/lib/Format/ContinuationIndenter.cpp | 15 +++------------ clang/lib/Format/FormatToken.h | 13 ++++++++++--- clang/lib/Format/TokenAnnotator.cpp | 7 ++++++- clang/unittests/Format/FormatTest.cpp | 4 ++++ 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/clang/lib/Format/ContinuationIndenter.cpp b/clang/lib/Format/ContinuationIndenter.cpp index d48cb23..12cfd48 100644 --- a/clang/lib/Format/ContinuationIndenter.cpp +++ b/clang/lib/Format/ContinuationIndenter.cpp @@ -38,15 +38,6 @@ static unsigned getLengthToMatchingParen(const FormatToken &Tok) { return End->TotalLength - Tok.TotalLength + 1; } -// Returns \c true if \c Tok starts a binary expression. -static bool startsBinaryExpression(const FormatToken &Tok) { - for (unsigned i = 0, e = Tok.FakeLParens.size(); i != e; ++i) { - if (Tok.FakeLParens[i] > prec::Unknown) - return true; - } - return false; -} - // Returns \c true if \c Tok is the "." or "->" of a call and starts the next // segment of a builder type call. static bool startsSegmentOfBuilderTypeCall(const FormatToken &Tok) { @@ -156,7 +147,7 @@ bool ContinuationIndenter::mustBreak(const LineState &State) { Previous.Previous && Previous.Previous->Type != TT_BinaryOperator; // For >>. bool LHSIsBinaryExpr = - Previous.Previous && Previous.Previous->FakeRParens > 0; + Previous.Previous && Previous.Previous->EndsBinaryExpression; if (Previous.Type == TT_BinaryOperator && (!IsComparison || LHSIsBinaryExpr) && Current.Type != TT_BinaryOperator && // For >>. @@ -394,7 +385,7 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline, Previous.Type == TT_UnaryOperator || Previous.Type == TT_CtorInitializerColon) && (Previous.getPrecedence() != prec::Assignment || - startsBinaryExpression(Current))) + Current.StartsBinaryExpression)) // Always indent relative to the RHS of the expression unless this is a // simple assignment without binary expression on the RHS. Also indent // relative to unary operators and the colons of constructor initializers. @@ -455,7 +446,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State, } // If return returns a binary expression, align after it. - if (Current.is(tok::kw_return) && startsBinaryExpression(Current)) + if (Current.is(tok::kw_return) && Current.StartsBinaryExpression) State.Stack.back().LastSpace = State.Column + 7; // In ObjC method declaration we align on the ":" of parameters, but we need diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index e4342dd..e374f83 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -89,9 +89,10 @@ struct FormatToken { CanBreakBefore(false), ClosesTemplateDeclaration(false), ParameterCount(0), PackingKind(PPK_Inconclusive), TotalLength(0), UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0), - LongestObjCSelectorName(0), FakeRParens(0), LastInChainOfCalls(false), - PartOfMultiVariableDeclStmt(false), MatchingParen(NULL), Previous(NULL), - Next(NULL) {} + LongestObjCSelectorName(0), FakeRParens(0), + StartsBinaryExpression(false), EndsBinaryExpression(false), + LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false), + MatchingParen(NULL), Previous(NULL), Next(NULL) {} /// \brief The \c Token. Token Tok; @@ -221,6 +222,12 @@ struct FormatToken { /// \brief Insert this many fake ) after this token for correct indentation. unsigned FakeRParens; + /// \brief \c true if this token starts a binary expression, i.e. has at least + /// one fake l_paren with a precedence greater than prec::Unknown. + bool StartsBinaryExpression; + /// \brief \c true if this token ends a binary expression. + bool EndsBinaryExpression; + /// \brief Is this the last "." or "->" in a builder-type call? bool LastInChainOfCalls; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 2f3be55..c725f50 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -928,8 +928,13 @@ private: void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) { Start->FakeLParens.push_back(Precedence); - if (Current) + if (Precedence > prec::Unknown) + Start->StartsBinaryExpression = true; + if (Current) { ++Current->Previous->FakeRParens; + if (Precedence > prec::Unknown) + Current->Previous->EndsBinaryExpression = true; + } } /// \brief Parse unary operator expressions and surround them with fake diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 3eaa69a..6e9516d 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2341,6 +2341,10 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) { "if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" "}"); + verifyFormat( + "if (aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) == 5) {\n" + "}"); // Even explicit parentheses stress the precedence enough to make the // additional break unnecessary. verifyFormat( -- 2.7.4