]> granicus.if.org Git - clang/commitdiff
Further improve optimization for nested calls.
authorDaniel Jasper <djasper@google.com>
Mon, 13 May 2013 09:19:24 +0000 (09:19 +0000)
committerDaniel Jasper <djasper@google.com>
Mon, 13 May 2013 09:19:24 +0000 (09:19 +0000)
Fake parentheses (i.e. emulated parentheses used to correctly handle
binary expressions) used to prevent the optimization implemented in
r180264.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181692 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/Format.cpp
unittests/Format/FormatTest.cpp

index d5676814c1b4211f5160c410c827732450843f59..f3ca9c371f1ecb1d67da1bae0a11ae74d0c38549 100644 (file)
@@ -270,7 +270,7 @@ private:
           AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
           NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
           NestedNameSpecifierContinuation(0), CallContinuation(0),
-          VariablePos(0) {}
+          VariablePos(0), ForFakeParenthesis(false) {}
 
     /// \brief The position to which a specific parenthesis level needs to be
     /// indented.
@@ -329,6 +329,13 @@ private:
     /// Used to align further variables if necessary.
     unsigned VariablePos;
 
+    /// \brief \c true if this \c ParenState was created for a fake parenthesis.
+    ///
+    /// Does not need to be considered for memoization / the comparison function
+    /// as otherwise identical states will have the same fake/non-fake
+    /// \c ParenStates.
+    bool ForFakeParenthesis;
+
     bool operator<(const ParenState &Other) const {
       if (Indent != Other.Indent)
         return Indent < Other.Indent;
@@ -641,6 +648,7 @@ private:
              E = Current.FakeLParens.rend();
          I != E; ++I) {
       ParenState NewParenState = State.Stack.back();
+      NewParenState.ForFakeParenthesis = true;
       NewParenState.Indent =
           std::max(std::max(State.Column, NewParenState.Indent),
                    State.Stack.back().LastSpace);
@@ -662,27 +670,31 @@ private:
     // prepare for the following tokens.
     if (Current.opensScope()) {
       unsigned NewIndent;
+      unsigned LastSpace = State.Stack.back().LastSpace;
       bool AvoidBinPacking;
       if (Current.is(tok::l_brace)) {
-        NewIndent = Style.IndentWidth + State.Stack.back().LastSpace;
+        NewIndent = Style.IndentWidth + LastSpace;
         AvoidBinPacking = false;
       } else {
-        NewIndent = 4 + std::max(State.Stack.back().LastSpace,
-                                 State.Stack.back().StartOfFunctionCall);
+        NewIndent =
+            4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall);
         AvoidBinPacking = !Style.BinPackParameters;
       }
-      State.Stack.push_back(
-          ParenState(NewIndent, State.Stack.back().LastSpace, AvoidBinPacking,
-                     State.Stack.back().NoLineBreak));
 
       if (Current.NoMoreTokensOnLevel && Current.FakeLParens.empty()) {
         // This parenthesis was the last token possibly making use of Indent and
-        // LastSpace of the next higher ParenLevel. Thus, erase them to acieve
+        // LastSpace of the next higher ParenLevel. Thus, erase them to achieve
         // better memoization results.
-        State.Stack[State.Stack.size() - 2].Indent = 0;
-        State.Stack[State.Stack.size() - 2].LastSpace = 0;
+        for (unsigned i = State.Stack.size() - 1; i > 0; --i) {
+          State.Stack[i].Indent = 0;
+          State.Stack[i].LastSpace = 0;
+          if (!State.Stack[i].ForFakeParenthesis)
+            break;
+        }
       }
 
+      State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking,
+                                       State.Stack.back().NoLineBreak));
       ++State.ParenLevel;
     }
 
index f0319d5e4896112eb1759b9a8054018013d835ad..931d29dd3e7c8d1ba2872b4ccde7a3862d750cd8 100644 (file)
@@ -1761,6 +1761,33 @@ TEST_F(FormatTest, MemoizationTests) {
       "            aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(aaaaa(\n"
       "                aaaaa())))))))))))))))))))))))))))))))))))))));",
       getLLVMStyleWithColumns(65));
+  verifyFormat(
+      "aaaaa(\n"
+      "    aaaaa,\n"
+      "    aaaaa(\n"
+      "        aaaaa,\n"
+      "        aaaaa(\n"
+      "            aaaaa,\n"
+      "            aaaaa(\n"
+      "                aaaaa,\n"
+      "                aaaaa(\n"
+      "                    aaaaa,\n"
+      "                    aaaaa(\n"
+      "                        aaaaa,\n"
+      "                        aaaaa(\n"
+      "                            aaaaa,\n"
+      "                            aaaaa(\n"
+      "                                aaaaa,\n"
+      "                                aaaaa(\n"
+      "                                    aaaaa,\n"
+      "                                    aaaaa(\n"
+      "                                        aaaaa,\n"
+      "                                        aaaaa(\n"
+      "                                            aaaaa,\n"
+      "                                            aaaaa(\n"
+      "                                                aaaaa,\n"
+      "                                                aaaaa))))))))))));",
+      getLLVMStyleWithColumns(65));
 
   // This test takes VERY long when memoization is broken.
   FormatStyle OnePerLine = getLLVMStyle();