]> granicus.if.org Git - clang/commitdiff
Fix bug where optimization would lead to strange line breaks.
authorManuel Klimek <klimek@google.com>
Wed, 20 Nov 2013 11:20:32 +0000 (11:20 +0000)
committerManuel Klimek <klimek@google.com>
Wed, 20 Nov 2013 11:20:32 +0000 (11:20 +0000)
Before:
  void f() {
    CHECK_EQ(aaaa, (
                       *bbbbbbbbb)->cccccc)
        << "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
  }

After:
  void f() {
    CHECK_EQ(aaaa, (*bbbbbbbbb)->cccccc)
        << "qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
  }

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

lib/Format/ContinuationIndenter.cpp
lib/Format/ContinuationIndenter.h
unittests/Format/FormatTest.cpp

index 971acc2b7a3c121a2803931e9a952c27d5a41906..bbc1ac5382465a9703c8a116ab191d5a0f8abd3c 100644 (file)
@@ -224,13 +224,14 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
   if (Newline)
     Penalty = addTokenOnNewLine(State, DryRun);
   else
-    addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
+    Penalty = addTokenOnCurrentLine(State, DryRun, ExtraSpaces);
 
   return moveStateToNextToken(State, DryRun, Newline) + Penalty;
 }
 
-void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
-                                                 unsigned ExtraSpaces) {
+unsigned ContinuationIndenter::addTokenOnCurrentLine(LineState &State,
+                                                     bool DryRun,
+                                                     unsigned ExtraSpaces) {
   FormatToken &Current = *State.NextToken;
   const FormatToken &Previous = *State.NextToken->Previous;
   if (Current.is(tok::equal) &&
@@ -249,6 +250,15 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
       State.Stack.back().LastSpace = State.Stack.back().VariablePos;
   }
 
+  unsigned Penalty = 0;
+  // A break before a "<<" will get Style.PenaltyBreakFirstLessLess, so a
+  // continuation with "<<" has a smaller penalty in general.
+  // If the LHS is long, we don't want to penalize the break though, so we
+  // also add Style.PenaltyBreakFirstLessLess.
+  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0 &&
+      State.Column > Style.ColumnLimit / 2)
+    Penalty += Style.PenaltyBreakFirstLessLess;
+
   unsigned Spaces = Current.SpacesRequiredBefore + ExtraSpaces;
 
   if (!DryRun)
@@ -307,6 +317,7 @@ void ContinuationIndenter::addTokenOnCurrentLine(LineState &State, bool DryRun,
         State.Stack[State.Stack.size() - 2].CallContinuation == 0)
       State.Stack.back().LastSpace = State.Column;
   }
+  return Penalty;
 }
 
 unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
@@ -332,9 +343,8 @@ unsigned ContinuationIndenter::addTokenOnNewLine(LineState &State,
   Penalty += State.NextToken->SplitPenalty;
 
   // Breaking before the first "<<" is generally not desirable if the LHS is
-  // short.
-  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0 &&
-      State.Column <= Style.ColumnLimit / 2)
+  // short (not breaking with a long LHS is penalized in addTokenOnCurrentLine).
+  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
     Penalty += Style.PenaltyBreakFirstLessLess;
 
   if (Current.is(tok::l_brace) && Current.BlockKind == BK_Block) {
index b31756583389e484adf4c52352b53a0b478c2cd4..b675b0a0c55283c94455943970195071be0041e8 100644 (file)
@@ -91,8 +91,8 @@ private:
   ///
   /// If \p DryRun is \c false, also creates and stores the required
   /// \c Replacement.
-  void addTokenOnCurrentLine(LineState &State, bool DryRun,
-                             unsigned ExtraSpaces);
+  unsigned addTokenOnCurrentLine(LineState &State, bool DryRun,
+                                 unsigned ExtraSpaces);
 
   /// \brief Appends the next token to \p State and updates information
   /// necessary for indentation.
index b6574c7503aaa6ad56d80467c519a7540e654b57..d9ca12996fa0d2536876bca76e1f65d21bd90f07 100644 (file)
@@ -3744,6 +3744,11 @@ TEST_F(FormatTest, AlignsPipes) {
   EXPECT_EQ("llvm::errs() << \"\n"
             "             << a;",
             format("llvm::errs() << \"\n<<a;"));
+
+  verifyFormat("void f() {\n"
+               "  CHECK_EQ(aaaa, (*bbbbbbbbb)->cccccc)\n"
+               "      << \"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\";\n"
+               "}");
 }
 
 TEST_F(FormatTest, UnderstandsEquals) {