From c3df5ffb52cb656c3a4d0b4d70f8f28ed2390e78 Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Mon, 13 May 2013 09:19:24 +0000 Subject: [PATCH] Further improve optimization for nested calls. 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 | 32 ++++++++++++++++++++++---------- unittests/Format/FormatTest.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp index d5676814c1..f3ca9c371f 100644 --- a/lib/Format/Format.cpp +++ b/lib/Format/Format.cpp @@ -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; } diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index f0319d5e48..931d29dd3e 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -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(); -- 2.40.0