From 3618e6fae8b734ad94221d941417c12d4bd1e3a8 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Fri, 23 Aug 2013 15:14:03 +0000 Subject: [PATCH] clang-format: Fix indentation relative to unary expressions. This should be done, only if we are still in the unary expression's scope. Before: bool aaaa = !aaaaaaaa( // break aaaaaaaaaaa); *aaaaaa = aaaaaaa( // break aaaaaaaaaaaaaaaa); After: bool aaaa = !aaaaaaaa( // break aaaaaaaaaaa); // <- (unchanged) *aaaaaa = aaaaaaa( // break aaaaaaaaaaaaaaaa); // <- (no longer indented relative to "*") git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189108 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/TokenAnnotator.cpp | 71 ++++++++++++++++++++++++++------- unittests/Format/FormatTest.cpp | 4 ++ 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index ffbe240fa7..890b4f1c98 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -853,13 +853,21 @@ public: /// \brief Parse expressions with the given operatore precedence. void parse(int Precedence = 0) { + if (Current == NULL) + return; + // Conditional expressions need to be parsed separately for proper nesting. if (Precedence == prec::Conditional + 1) { parseConditionalExpr(); return; } - if (Precedence > prec::PointerToMember || Current == NULL) + + // Parse unary operators, which all have a higher precedence than binary + // operators. + if (Precedence > prec::PointerToMember) { + parseUnaryOperator(); return; + } FormatToken *Start = Current; bool OperatorFound = false; @@ -868,20 +876,11 @@ public: // Consume operators with higher precedence. parse(Precedence + 1); - int CurrentPrecedence = 0; - if (Current) { - if (Current->Type == TT_ConditionalExpr) - CurrentPrecedence = 1 + (int)prec::Conditional; - else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon) - CurrentPrecedence = 1; - else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) - CurrentPrecedence = 1 + (int)Current->getPrecedence(); - else if (Current->Type == TT_ObjCSelectorName) { - CurrentPrecedence = 1 + (int)prec::Assignment; - if (Precedence == CurrentPrecedence) - Start = Current; - } - } + int CurrentPrecedence = getCurrentPrecedence(); + + if (Current && Current->Type == TT_ObjCSelectorName && + Precedence == CurrentPrecedence) + Start = Current; // At the end of the line or when an operator with higher precedence is // found, insert fake parenthesis and return. @@ -910,12 +909,54 @@ public: } private: + /// \brief Gets the precedence (+1) of the given token for binary operators + /// and other tokens that we treat like binary operators. + int getCurrentPrecedence() { + if (Current) { + if (Current->Type == TT_ConditionalExpr) + return 1 + (int)prec::Conditional; + else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon) + return 1; + else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma)) + return 1 + (int)Current->getPrecedence(); + else if (Current->Type == TT_ObjCSelectorName) + return 1 + (int)prec::Assignment; + } + return 0; + } + void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) { Start->FakeLParens.push_back(Precedence); if (Current) ++Current->Previous->FakeRParens; } + /// \brief Parse unary operator expressions and surround them with fake + /// parentheses if appropriate. + void parseUnaryOperator() { + if (Current == NULL || Current->Type != TT_UnaryOperator) + return; + + FormatToken *Start = Current; + next(); + + while (Current) { + if (Current->opensScope()) { + while (Current && !Current->closesScope()) { + next(); + parse(); + } + next(); + } else if (getCurrentPrecedence() == 0 && !Current->closesScope()) { + next(); + } else { + break; + } + } + // The actual precedence doesn't matter. + addFakeParenthesis(Start, prec::Level(0)); + } + void parseConditionalExpr() { FormatToken *Start = Current; parse(prec::LogicalOr + 1); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index aec93bb4cf..5606aa109b 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -3524,6 +3524,10 @@ TEST_F(FormatTest, IndentsRelativeToUnaryOperators) { "}"); verifyFormat("aaaaaaaaaa(!aaaaaaaaaa( // break\n" " aaaaa));"); + + // Only indent relative to unary operators if the expression is nested. + verifyFormat("*aaa = aaaaaaa( // break\n" + " bbbbbb);"); } TEST_F(FormatTest, UndestandsOverloadedOperators) { -- 2.40.0