r189108 - clang-format: Fix indentation relative to unary expressions.

Daniel Jasper djasper at google.com
Fri Aug 23 08:14:03 PDT 2013


Author: djasper
Date: Fri Aug 23 10:14:03 2013
New Revision: 189108

URL: http://llvm.org/viewvc/llvm-project?rev=189108&view=rev
Log:
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 "*")

Modified:
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=189108&r1=189107&r2=189108&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri Aug 23 10:14:03 2013
@@ -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);

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=189108&r1=189107&r2=189108&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Aug 23 10:14:03 2013
@@ -3524,6 +3524,10 @@ TEST_F(FormatTest, IndentsRelativeToUnar
                "}");
   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) {





More information about the cfe-commits mailing list