r188543 - Split UnwrappedLineFormatter into individual components.

Daniel Jasper djasper at google.com
Fri Aug 16 04:20:30 PDT 2013


Author: djasper
Date: Fri Aug 16 06:20:30 2013
New Revision: 188543

URL: http://llvm.org/viewvc/llvm-project?rev=188543&view=rev
Log:
Split UnwrappedLineFormatter into individual components.

Goals: Structure code better and make components easier to use for
future features (e.g. column layout for long braced initializers).

No functional changes intended.

Added:
    cfe/trunk/lib/Format/ContinuationIndenter.cpp
    cfe/trunk/lib/Format/ContinuationIndenter.h
Modified:
    cfe/trunk/lib/Format/CMakeLists.txt
    cfe/trunk/lib/Format/Format.cpp

Modified: cfe/trunk/lib/Format/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/CMakeLists.txt?rev=188543&r1=188542&r2=188543&view=diff
==============================================================================
--- cfe/trunk/lib/Format/CMakeLists.txt (original)
+++ cfe/trunk/lib/Format/CMakeLists.txt Fri Aug 16 06:20:30 2013
@@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support)
 
 add_clang_library(clangFormat
   BreakableToken.cpp
+  ContinuationIndenter.cpp
   Format.cpp
   TokenAnnotator.cpp
   UnwrappedLineParser.cpp

Added: cfe/trunk/lib/Format/ContinuationIndenter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=188543&view=auto
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (added)
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Fri Aug 16 06:20:30 2013
@@ -0,0 +1,670 @@
+//===--- ContinuationIndenter.cpp - Format C++ code -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements the continuation indenter.
+///
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "format-formatter"
+
+#include "BreakableToken.h"
+#include "ContinuationIndenter.h"
+#include "WhitespaceManager.h"
+#include "clang/Basic/OperatorPrecedence.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include <string>
+
+namespace clang {
+namespace format {
+
+// Returns the length of everything up to the first possible line break after
+// the ), ], } or > matching \c Tok.
+static unsigned getLengthToMatchingParen(const FormatToken &Tok) {
+  if (Tok.MatchingParen == NULL)
+    return 0;
+  FormatToken *End = Tok.MatchingParen;
+  while (End->Next && !End->Next->CanBreakBefore) {
+    End = End->Next;
+  }
+  return End->TotalLength - Tok.TotalLength + 1;
+}
+
+ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style,
+                                           SourceManager &SourceMgr,
+                                           const AnnotatedLine &Line,
+                                           unsigned FirstIndent,
+                                           WhitespaceManager &Whitespaces,
+                                           encoding::Encoding Encoding,
+                                           bool BinPackInconclusiveFunctions)
+    : Style(Style), SourceMgr(SourceMgr), Line(Line), FirstIndent(FirstIndent),
+      Whitespaces(Whitespaces), Encoding(Encoding),
+      BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}
+
+LineState ContinuationIndenter::getInitialState() {
+  // Initialize state dependent on indent.
+  LineState State;
+  State.Column = FirstIndent;
+  State.NextToken = Line.First;
+  State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
+                                   /*AvoidBinPacking=*/false,
+                                   /*NoLineBreak=*/false));
+  State.LineContainsContinuedForLoopSection = false;
+  State.ParenLevel = 0;
+  State.StartOfStringLiteral = 0;
+  State.StartOfLineLevel = State.ParenLevel;
+  State.LowestLevelOnLine = State.ParenLevel;
+  State.IgnoreStackForComparison = false;
+
+  // The first token has already been indented and thus consumed.
+  moveStateToNextToken(State, /*DryRun=*/false,
+                       /*Newline=*/false);
+  return State;
+}
+
+bool ContinuationIndenter::canBreak(const LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *Current.Previous;
+  assert(&Previous == Current.Previous);
+  if (!Current.CanBreakBefore &&
+      !(Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace))
+    return false;
+  // The opening "{" of a braced list has to be on the same line as the first
+  // element if it is nested in another braced init list or function call.
+  if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&
+      Previous.Previous &&
+      Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma))
+    return false;
+  // This prevents breaks like:
+  //   ...
+  //   SomeParameter, OtherParameter).DoSomething(
+  //   ...
+  // As they hide "DoSomething" and are generally bad for readability.
+  if (Previous.opensScope() && State.LowestLevelOnLine < State.StartOfLineLevel)
+    return false;
+  return !State.Stack.back().NoLineBreak;
+}
+
+bool ContinuationIndenter::mustBreak(const LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *Current.Previous;
+  if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon)
+    return true;
+  if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) &&
+      State.Stack.back().BreakBeforeClosingBrace)
+    return true;
+  if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
+    return true;
+  if (Style.BreakConstructorInitializersBeforeComma) {
+    if (Previous.Type == TT_CtorInitializerComma)
+      return false;
+    if (Current.Type == TT_CtorInitializerComma)
+      return true;
+  }
+  if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) ||
+       (Current.Type == TT_ConditionalExpr &&
+        !(Current.is(tok::colon) && Previous.is(tok::question)))) &&
+      State.Stack.back().BreakBeforeParameter && !Current.isTrailingComment() &&
+      !Current.isOneOf(tok::r_paren, tok::r_brace))
+    return true;
+  if (Style.AlwaysBreakBeforeMultilineStrings &&
+      State.Column > State.Stack.back().Indent &&
+      Current.is(tok::string_literal) && Previous.isNot(tok::lessless) &&
+      Previous.Type != TT_InlineASMColon &&
+      ((Current.getNextNonComment() &&
+        Current.getNextNonComment()->is(tok::string_literal)) ||
+       (Current.TokenText.find("\\\n") != StringRef::npos)))
+    return true;
+
+  if (!Style.BreakBeforeBinaryOperators) {
+    // If we need to break somewhere inside the LHS of a binary expression, we
+    // should also break after the operator. Otherwise, the formatting would
+    // hide the operator precedence, e.g. in:
+    //   if (aaaaaaaaaaaaaa ==
+    //           bbbbbbbbbbbbbb && c) {..
+    // For comparisons, we only apply this rule, if the LHS is a binary
+    // expression itself as otherwise, the line breaks seem superfluous.
+    // We need special cases for ">>" which we have split into two ">" while
+    // lexing in order to make template parsing easier.
+    //
+    // FIXME: We'll need something similar for styles that break before binary
+    // operators.
+    bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
+                         Previous.getPrecedence() == prec::Equality) &&
+                        Previous.Previous &&
+                        Previous.Previous->Type != TT_BinaryOperator; // For >>.
+    bool LHSIsBinaryExpr =
+        Previous.Previous && Previous.Previous->FakeRParens > 0;
+    if (Previous.Type == TT_BinaryOperator &&
+        (!IsComparison || LHSIsBinaryExpr) &&
+        Current.Type != TT_BinaryOperator && // For >>.
+        !Current.isTrailingComment() &&
+        !Previous.isOneOf(tok::lessless, tok::question) &&
+        Previous.getPrecedence() != prec::Assignment &&
+        State.Stack.back().BreakBeforeParameter)
+      return true;
+  }
+
+  // Same as above, but for the first "<<" operator.
+  if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
+      State.Stack.back().FirstLessLess == 0)
+    return true;
+
+  // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
+  // out whether it is the first parameter. Clean this up.
+  if (Current.Type == TT_ObjCSelectorName &&
+      Current.LongestObjCSelectorName == 0 &&
+      State.Stack.back().BreakBeforeParameter)
+    return true;
+  if ((Current.Type == TT_CtorInitializerColon ||
+       (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0)))
+    return true;
+
+  if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&
+      Line.MightBeFunctionDecl && State.Stack.back().BreakBeforeParameter &&
+      State.ParenLevel == 0)
+    return true;
+  return false;
+}
+
+unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
+                                               bool DryRun) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *State.NextToken->Previous;
+
+  // Extra penalty that needs to be added because of the way certain line
+  // breaks are chosen.
+  unsigned ExtraPenalty = 0;
+
+  if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) {
+    // FIXME: Is this correct?
+    int WhitespaceLength = SourceMgr.getSpellingColumnNumber(
+                               State.NextToken->WhitespaceRange.getEnd()) -
+                           SourceMgr.getSpellingColumnNumber(
+                               State.NextToken->WhitespaceRange.getBegin());
+    State.Column += WhitespaceLength + State.NextToken->CodePointCount;
+    State.NextToken = State.NextToken->Next;
+    return 0;
+  }
+
+  // If we are continuing an expression, we want to indent an extra 4 spaces.
+  unsigned ContinuationIndent =
+      std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4;
+  if (Newline) {
+    // 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)
+      ExtraPenalty += Style.PenaltyBreakFirstLessLess;
+
+    State.Stack.back().ContainsLineBreak = true;
+    if (Current.is(tok::r_brace)) {
+      if (Current.BlockKind == BK_BracedInit)
+        State.Column = State.Stack[State.Stack.size() - 2].LastSpace;
+      else
+        State.Column = FirstIndent;
+    } else if (Current.is(tok::string_literal) &&
+               State.StartOfStringLiteral != 0) {
+      State.Column = State.StartOfStringLiteral;
+      State.Stack.back().BreakBeforeParameter = true;
+    } else if (Current.is(tok::lessless) &&
+               State.Stack.back().FirstLessLess != 0) {
+      State.Column = State.Stack.back().FirstLessLess;
+    } else if (Current.isOneOf(tok::period, tok::arrow) &&
+               Current.Type != TT_DesignatedInitializerPeriod) {
+      if (State.Stack.back().CallContinuation == 0) {
+        State.Column = ContinuationIndent;
+        State.Stack.back().CallContinuation = State.Column;
+      } else {
+        State.Column = State.Stack.back().CallContinuation;
+      }
+    } else if (Current.Type == TT_ConditionalExpr) {
+      State.Column = State.Stack.back().QuestionColumn;
+    } else if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) {
+      State.Column = State.Stack.back().VariablePos;
+    } else if (Previous.ClosesTemplateDeclaration ||
+               ((Current.Type == TT_StartOfName ||
+                 Current.is(tok::kw_operator)) &&
+                State.ParenLevel == 0 &&
+                (!Style.IndentFunctionDeclarationAfterType ||
+                 Line.StartsDefinition))) {
+      State.Column = State.Stack.back().Indent;
+    } else if (Current.Type == TT_ObjCSelectorName) {
+      if (State.Stack.back().ColonPos > Current.CodePointCount) {
+        State.Column = State.Stack.back().ColonPos - Current.CodePointCount;
+      } else {
+        State.Column = State.Stack.back().Indent;
+        State.Stack.back().ColonPos = State.Column + Current.CodePointCount;
+      }
+    } else if (Current.is(tok::l_square) && Current.Type != TT_ObjCMethodExpr) {
+      if (State.Stack.back().StartOfArraySubscripts != 0)
+        State.Column = State.Stack.back().StartOfArraySubscripts;
+      else
+        State.Column = ContinuationIndent;
+    } else if (Current.Type == TT_StartOfName ||
+               Previous.isOneOf(tok::coloncolon, tok::equal) ||
+               Previous.Type == TT_ObjCMethodExpr) {
+      State.Column = ContinuationIndent;
+    } else if (Current.Type == TT_CtorInitializerColon) {
+      State.Column = FirstIndent + Style.ConstructorInitializerIndentWidth;
+    } else if (Current.Type == TT_CtorInitializerComma) {
+      State.Column = State.Stack.back().Indent;
+    } else {
+      State.Column = State.Stack.back().Indent;
+      // Ensure that we fall back to indenting 4 spaces instead of just
+      // flushing continuations left.
+      if (State.Column == FirstIndent)
+        State.Column += 4;
+    }
+
+    if (Current.is(tok::question))
+      State.Stack.back().BreakBeforeParameter = true;
+    if ((Previous.isOneOf(tok::comma, tok::semi) &&
+         !State.Stack.back().AvoidBinPacking) ||
+        Previous.Type == TT_BinaryOperator)
+      State.Stack.back().BreakBeforeParameter = false;
+    if (Previous.Type == TT_TemplateCloser && State.ParenLevel == 0)
+      State.Stack.back().BreakBeforeParameter = false;
+
+    if (!DryRun) {
+      unsigned NewLines = 1;
+      if (Current.is(tok::comment))
+        NewLines = std::max(NewLines, std::min(Current.NewlinesBefore,
+                                               Style.MaxEmptyLinesToKeep + 1));
+      Whitespaces.replaceWhitespace(Current, NewLines, State.Column,
+                                    State.Column, Line.InPPDirective);
+    }
+
+    if (!Current.isTrailingComment())
+      State.Stack.back().LastSpace = State.Column;
+    if (Current.isOneOf(tok::arrow, tok::period) &&
+        Current.Type != TT_DesignatedInitializerPeriod)
+      State.Stack.back().LastSpace += Current.CodePointCount;
+    State.StartOfLineLevel = State.ParenLevel;
+    State.LowestLevelOnLine = State.ParenLevel;
+
+    // Any break on this level means that the parent level has been broken
+    // and we need to avoid bin packing there.
+    for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
+      State.Stack[i].BreakBeforeParameter = true;
+    }
+    const FormatToken *TokenBefore = Current.getPreviousNonComment();
+    if (TokenBefore && !TokenBefore->isOneOf(tok::comma, tok::semi) &&
+        TokenBefore->Type != TT_TemplateCloser &&
+        TokenBefore->Type != TT_BinaryOperator && !TokenBefore->opensScope())
+      State.Stack.back().BreakBeforeParameter = true;
+
+    // If we break after {, we should also break before the corresponding }.
+    if (Previous.is(tok::l_brace))
+      State.Stack.back().BreakBeforeClosingBrace = true;
+
+    if (State.Stack.back().AvoidBinPacking) {
+      // If we are breaking after '(', '{', '<', this is not bin packing
+      // unless AllowAllParametersOfDeclarationOnNextLine is false.
+      if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) ||
+            Previous.Type == TT_BinaryOperator) ||
+          (!Style.AllowAllParametersOfDeclarationOnNextLine &&
+           Line.MustBeDeclaration))
+        State.Stack.back().BreakBeforeParameter = true;
+    }
+
+  } else {
+    if (Current.is(tok::equal) &&
+        (Line.First->is(tok::kw_for) || State.ParenLevel == 0) &&
+        State.Stack.back().VariablePos == 0) {
+      State.Stack.back().VariablePos = State.Column;
+      // Move over * and & if they are bound to the variable name.
+      const FormatToken *Tok = &Previous;
+      while (Tok && State.Stack.back().VariablePos >= Tok->CodePointCount) {
+        State.Stack.back().VariablePos -= Tok->CodePointCount;
+        if (Tok->SpacesRequiredBefore != 0)
+          break;
+        Tok = Tok->Previous;
+      }
+      if (Previous.PartOfMultiVariableDeclStmt)
+        State.Stack.back().LastSpace = State.Stack.back().VariablePos;
+    }
+
+    unsigned Spaces = State.NextToken->SpacesRequiredBefore;
+
+    if (!DryRun)
+      Whitespaces.replaceWhitespace(Current, 0, Spaces, State.Column + Spaces);
+
+    if (Current.Type == TT_ObjCSelectorName &&
+        State.Stack.back().ColonPos == 0) {
+      if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
+          State.Column + Spaces + Current.CodePointCount)
+        State.Stack.back().ColonPos =
+            State.Stack.back().Indent + Current.LongestObjCSelectorName;
+      else
+        State.Stack.back().ColonPos =
+            State.Column + Spaces + Current.CodePointCount;
+    }
+
+    if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr &&
+        Current.Type != TT_LineComment)
+      State.Stack.back().Indent = State.Column + Spaces;
+    if (Previous.is(tok::comma) && !Current.isTrailingComment() &&
+        State.Stack.back().AvoidBinPacking)
+      State.Stack.back().NoLineBreak = true;
+
+    State.Column += Spaces;
+    if (Current.is(tok::l_paren) && Previous.isOneOf(tok::kw_if, tok::kw_for))
+      // Treat the condition inside an if as if it was a second function
+      // parameter, i.e. let nested calls have an indent of 4.
+      State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
+    else if (Previous.is(tok::comma))
+      State.Stack.back().LastSpace = State.Column;
+    else if ((Previous.Type == TT_BinaryOperator ||
+              Previous.Type == TT_ConditionalExpr ||
+              Previous.Type == TT_CtorInitializerColon) &&
+             !(Previous.getPrecedence() == prec::Assignment &&
+               Current.FakeLParens.empty()))
+      // Always indent relative to the RHS of the expression unless this is a
+      // simple assignment without binary expression on the RHS.
+      State.Stack.back().LastSpace = State.Column;
+    else if (Previous.Type == TT_InheritanceColon)
+      State.Stack.back().Indent = State.Column;
+    else if (Previous.opensScope()) {
+      // If a function has multiple parameters (including a single parameter
+      // that is a binary expression) or a trailing call, indent all
+      // parameters from the opening parenthesis. This avoids confusing
+      // indents like:
+      //   OuterFunction(InnerFunctionCall(
+      //       ParameterToInnerFunction),
+      //                 SecondParameterToOuterFunction);
+      bool HasMultipleParameters = !Current.FakeLParens.empty();
+      bool HasTrailingCall = false;
+      if (Previous.MatchingParen) {
+        const FormatToken *Next = Previous.MatchingParen->getNextNonComment();
+        if (Next && Next->isOneOf(tok::period, tok::arrow))
+          HasTrailingCall = true;
+      }
+      if (HasMultipleParameters || HasTrailingCall)
+        State.Stack.back().LastSpace = State.Column;
+    }
+  }
+
+  return moveStateToNextToken(State, DryRun, Newline) + ExtraPenalty;
+}
+
+unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
+                                                    bool DryRun, bool Newline) {
+  const FormatToken &Current = *State.NextToken;
+  assert(State.Stack.size());
+
+  if (Current.Type == TT_InheritanceColon)
+    State.Stack.back().AvoidBinPacking = true;
+  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
+    State.Stack.back().FirstLessLess = State.Column;
+  if (Current.is(tok::l_square) &&
+      State.Stack.back().StartOfArraySubscripts == 0)
+    State.Stack.back().StartOfArraySubscripts = State.Column;
+  if (Current.is(tok::question))
+    State.Stack.back().QuestionColumn = State.Column;
+  if (!Current.opensScope() && !Current.closesScope())
+    State.LowestLevelOnLine =
+        std::min(State.LowestLevelOnLine, State.ParenLevel);
+  if (Current.isOneOf(tok::period, tok::arrow) &&
+      Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0)
+    State.Stack.back().StartOfFunctionCall =
+        Current.LastInChainOfCalls ? 0 : State.Column + Current.CodePointCount;
+  if (Current.Type == TT_CtorInitializerColon) {
+    // Indent 2 from the column, so:
+    // SomeClass::SomeClass()
+    //     : First(...), ...
+    //       Next(...)
+    //       ^ line up here.
+    State.Stack.back().Indent =
+        State.Column + (Style.BreakConstructorInitializersBeforeComma ? 0 : 2);
+    if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
+      State.Stack.back().AvoidBinPacking = true;
+    State.Stack.back().BreakBeforeParameter = false;
+  }
+
+  // If return returns a binary expression, align after it.
+  if (Current.is(tok::kw_return) && !Current.FakeLParens.empty())
+    State.Stack.back().LastSpace = State.Column + 7;
+
+  // In ObjC method declaration we align on the ":" of parameters, but we need
+  // to ensure that we indent parameters on subsequent lines by at least 4.
+  if (Current.Type == TT_ObjCMethodSpecifier)
+    State.Stack.back().Indent += 4;
+
+  // Insert scopes created by fake parenthesis.
+  const FormatToken *Previous = Current.getPreviousNonComment();
+  // Don't add extra indentation for the first fake parenthesis after
+  // 'return', assignements or opening <({[. The indentation for these cases
+  // is special cased.
+  bool SkipFirstExtraIndent =
+      Current.is(tok::kw_return) ||
+      (Previous && (Previous->opensScope() ||
+                    Previous->getPrecedence() == prec::Assignment));
+  for (SmallVectorImpl<prec::Level>::const_reverse_iterator
+           I = Current.FakeLParens.rbegin(),
+           E = Current.FakeLParens.rend();
+       I != E; ++I) {
+    ParenState NewParenState = State.Stack.back();
+    NewParenState.ContainsLineBreak = false;
+    NewParenState.Indent =
+        std::max(std::max(State.Column, NewParenState.Indent),
+                 State.Stack.back().LastSpace);
+
+    // Always indent conditional expressions. Never indent expression where
+    // the 'operator' is ',', ';' or an assignment (i.e. *I <=
+    // prec::Assignment) as those have different indentation rules. Indent
+    // other expression, unless the indentation needs to be skipped.
+    if (*I == prec::Conditional ||
+        (!SkipFirstExtraIndent && *I > prec::Assignment &&
+         !Style.BreakBeforeBinaryOperators))
+      NewParenState.Indent += 4;
+    if (Previous && !Previous->opensScope())
+      NewParenState.BreakBeforeParameter = false;
+    State.Stack.push_back(NewParenState);
+    SkipFirstExtraIndent = false;
+  }
+
+  // If we encounter an opening (, [, { or <, we add a level to our stacks to
+  // 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 =
+          LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);
+      const FormatToken *NextNoComment = Current.getNextNonComment();
+      AvoidBinPacking = NextNoComment &&
+                        NextNoComment->Type == TT_DesignatedInitializerPeriod;
+    } else {
+      NewIndent =
+          4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall);
+      AvoidBinPacking = !Style.BinPackParameters ||
+                        (Style.ExperimentalAutoDetectBinPacking &&
+                         (Current.PackingKind == PPK_OnePerLine ||
+                          (!BinPackInconclusiveFunctions &&
+                           Current.PackingKind == PPK_Inconclusive)));
+    }
+
+    State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking,
+                                     State.Stack.back().NoLineBreak));
+    ++State.ParenLevel;
+  }
+
+  // If this '[' opens an ObjC call, determine whether all parameters fit into
+  // one line and put one per line if they don't.
+  if (Current.is(tok::l_square) && Current.Type == TT_ObjCMethodExpr &&
+      Current.MatchingParen != NULL) {
+    if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())
+      State.Stack.back().BreakBeforeParameter = true;
+  }
+
+  // If we encounter a closing ), ], } or >, we can remove a level from our
+  // stacks.
+  if (Current.isOneOf(tok::r_paren, tok::r_square) ||
+      (Current.is(tok::r_brace) && State.NextToken != Line.First) ||
+      State.NextToken->Type == TT_TemplateCloser) {
+    State.Stack.pop_back();
+    --State.ParenLevel;
+  }
+  if (Current.is(tok::r_square)) {
+    // If this ends the array subscript expr, reset the corresponding value.
+    const FormatToken *NextNonComment = Current.getNextNonComment();
+    if (NextNonComment && NextNonComment->isNot(tok::l_square))
+      State.Stack.back().StartOfArraySubscripts = 0;
+  }
+
+  // Remove scopes created by fake parenthesis.
+  for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
+    unsigned VariablePos = State.Stack.back().VariablePos;
+    State.Stack.pop_back();
+    State.Stack.back().VariablePos = VariablePos;
+  }
+
+  if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) {
+    State.StartOfStringLiteral = State.Column;
+  } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash,
+                              tok::string_literal)) {
+    State.StartOfStringLiteral = 0;
+  }
+
+  State.Column += Current.CodePointCount;
+
+  State.NextToken = State.NextToken->Next;
+
+  if (!Newline && Style.AlwaysBreakBeforeMultilineStrings &&
+      Current.is(tok::string_literal) && Current.CanBreakBefore)
+    return 0;
+
+  return breakProtrudingToken(Current, State, DryRun);
+}
+
+unsigned ContinuationIndenter::breakProtrudingToken(const FormatToken &Current,
+                                                    LineState &State,
+                                                    bool DryRun) {
+  llvm::OwningPtr<BreakableToken> Token;
+  unsigned StartColumn = State.Column - Current.CodePointCount;
+  unsigned OriginalStartColumn =
+      SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) - 1;
+
+  if (Current.is(tok::string_literal) &&
+      Current.Type != TT_ImplicitStringLiteral) {
+    // Only break up default narrow strings.
+    if (!Current.TokenText.startswith("\""))
+      return 0;
+    // Don't break string literals with escaped newlines. As clang-format must
+    // not change the string's content, it is unlikely that we'll end up with
+    // a better format.
+    if (Current.TokenText.find("\\\n") != StringRef::npos)
+      return 0;
+    // Exempts unterminated string literals from line breaking. The user will
+    // likely want to terminate the string before any line breaking is done.
+    if (Current.IsUnterminatedLiteral)
+      return 0;
+
+    Token.reset(new BreakableStringLiteral(Current, StartColumn,
+                                           Line.InPPDirective, Encoding));
+  } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
+    Token.reset(new BreakableBlockComment(
+        Style, Current, StartColumn, OriginalStartColumn, !Current.Previous,
+        Line.InPPDirective, Encoding));
+  } else if (Current.Type == TT_LineComment &&
+             (Current.Previous == NULL ||
+              Current.Previous->Type != TT_ImplicitStringLiteral)) {
+    // Don't break line comments with escaped newlines. These look like
+    // separate line comments, but in fact contain a single line comment with
+    // multiple lines including leading whitespace and the '//' markers.
+    //
+    // FIXME: If we want to handle them correctly, we'll need to adjust
+    // leading whitespace in consecutive lines when changing indentation of
+    // the first line similar to what we do with block comments.
+    StringRef::size_type EscapedNewlinePos = Current.TokenText.find("\\\n");
+    if (EscapedNewlinePos != StringRef::npos) {
+      State.Column =
+          StartColumn +
+          encoding::getCodePointCount(
+              Current.TokenText.substr(0, EscapedNewlinePos), Encoding) +
+          1;
+      return 0;
+    }
+
+    Token.reset(new BreakableLineComment(Current, StartColumn,
+                                         Line.InPPDirective, Encoding));
+  } else {
+    return 0;
+  }
+  if (Current.UnbreakableTailLength >= getColumnLimit())
+    return 0;
+
+  unsigned RemainingSpace = getColumnLimit() - Current.UnbreakableTailLength;
+  bool BreakInserted = false;
+  unsigned Penalty = 0;
+  unsigned RemainingTokenColumns = 0;
+  for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
+       LineIndex != EndIndex; ++LineIndex) {
+    if (!DryRun)
+      Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
+    unsigned TailOffset = 0;
+    RemainingTokenColumns =
+        Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
+    while (RemainingTokenColumns > RemainingSpace) {
+      BreakableToken::Split Split =
+          Token->getSplit(LineIndex, TailOffset, getColumnLimit());
+      if (Split.first == StringRef::npos) {
+        // The last line's penalty is handled in addNextStateToQueue().
+        if (LineIndex < EndIndex - 1)
+          Penalty += Style.PenaltyExcessCharacter *
+                     (RemainingTokenColumns - RemainingSpace);
+        break;
+      }
+      assert(Split.first != 0);
+      unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
+          LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
+      assert(NewRemainingTokenColumns < RemainingTokenColumns);
+      if (!DryRun)
+        Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
+      Penalty += Current.is(tok::string_literal) ? Style.PenaltyBreakString
+                                                 : Style.PenaltyBreakComment;
+      unsigned ColumnsUsed =
+          Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
+      if (ColumnsUsed > getColumnLimit()) {
+        Penalty +=
+            Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit());
+      }
+      TailOffset += Split.first + Split.second;
+      RemainingTokenColumns = NewRemainingTokenColumns;
+      BreakInserted = true;
+    }
+  }
+
+  State.Column = RemainingTokenColumns;
+
+  if (BreakInserted) {
+    // If we break the token inside a parameter list, we need to break before
+    // the next parameter on all levels, so that the next parameter is clearly
+    // visible. Line comments already introduce a break.
+    if (Current.Type != TT_LineComment) {
+      for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
+        State.Stack[i].BreakBeforeParameter = true;
+    }
+
+    State.Stack.back().LastSpace = StartColumn;
+  }
+  return Penalty;
+}
+
+unsigned ContinuationIndenter::getColumnLimit() const {
+  // In preprocessor directives reserve two chars for trailing " \"
+  return Style.ColumnLimit - (Line.InPPDirective ? 2 : 0);
+}
+
+} // namespace format
+} // namespace clang

Added: cfe/trunk/lib/Format/ContinuationIndenter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.h?rev=188543&view=auto
==============================================================================
--- cfe/trunk/lib/Format/ContinuationIndenter.h (added)
+++ cfe/trunk/lib/Format/ContinuationIndenter.h Fri Aug 16 06:20:30 2013
@@ -0,0 +1,277 @@
+//===--- ContinuationIndenter.h - Format C++ code ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements an indenter that manages the indentation of
+/// continuations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
+#define LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H
+
+#include "Encoding.h"
+#include "clang/Format/Format.h"
+
+namespace clang {
+class SourceManager;
+
+namespace format {
+
+class AnnotatedLine;
+struct FormatToken;
+struct LineState;
+struct ParenState;
+class WhitespaceManager;
+
+class ContinuationIndenter {
+public:
+  /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in
+  /// column \p FirstIndent.
+  ContinuationIndenter(const FormatStyle &Style, SourceManager &SourceMgr,
+                       const AnnotatedLine &Line, unsigned FirstIndent,
+                       WhitespaceManager &Whitespaces,
+                       encoding::Encoding Encoding,
+                       bool BinPackInconclusiveFunctions);
+
+  /// \brief Get the initial state, i.e. the state after placing the line's
+  /// first token.
+  LineState getInitialState();
+
+  // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a
+  // better home.
+  /// \brief Returns \c true, if a line break after \p State is allowed.
+  bool canBreak(const LineState &State);
+
+  /// \brief Returns \c true, if a line break after \p State is mandatory.
+  bool mustBreak(const LineState &State);
+
+  /// \brief Appends the next token to \p State and updates information
+  /// necessary for indentation.
+  ///
+  /// Puts the token on the current line if \p Newline is \c false and adds a
+  /// line break and necessary indentation otherwise.
+  ///
+  /// If \p DryRun is \c false, also creates and stores the required
+  /// \c Replacement.
+  unsigned addTokenToState(LineState &State, bool Newline, bool DryRun);
+
+  /// \brief Get the column limit for this line. This is the style's column
+  /// limit, potentially reduced for preprocessor definitions.
+  unsigned getColumnLimit() const;
+
+private:
+  /// \brief Mark the next token as consumed in \p State and modify its stacks
+  /// accordingly.
+  unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
+
+  /// \brief If the current token sticks out over the end of the line, break
+  /// it if possible.
+  ///
+  /// \returns An extra penalty if a token was broken, otherwise 0.
+  ///
+  /// The returned penalty will cover the cost of the additional line breaks and
+  /// column limit violation in all lines except for the last one. The penalty
+  /// for the column limit violation in the last line (and in single line
+  /// tokens) is handled in \c addNextStateToQueue.
+  unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
+                                bool DryRun);
+
+  FormatStyle Style;
+  SourceManager &SourceMgr;
+  const AnnotatedLine &Line;
+  const unsigned FirstIndent;
+  WhitespaceManager &Whitespaces;
+  encoding::Encoding Encoding;
+  bool BinPackInconclusiveFunctions;
+};
+
+struct ParenState {
+  ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
+             bool NoLineBreak)
+      : Indent(Indent), LastSpace(LastSpace), FirstLessLess(0),
+        BreakBeforeClosingBrace(false), QuestionColumn(0),
+        AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
+        NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
+        StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
+        CallContinuation(0), VariablePos(0), ContainsLineBreak(false) {}
+
+  /// \brief The position to which a specific parenthesis level needs to be
+  /// indented.
+  unsigned Indent;
+
+  /// \brief The position of the last space on each level.
+  ///
+  /// Used e.g. to break like:
+  /// functionCall(Parameter, otherCall(
+  ///                             OtherParameter));
+  unsigned LastSpace;
+
+  /// \brief The position the first "<<" operator encountered on each level.
+  ///
+  /// Used to align "<<" operators. 0 if no such operator has been encountered
+  /// on a level.
+  unsigned FirstLessLess;
+
+  /// \brief Whether a newline needs to be inserted before the block's closing
+  /// brace.
+  ///
+  /// We only want to insert a newline before the closing brace if there also
+  /// was a newline after the beginning left brace.
+  bool BreakBeforeClosingBrace;
+
+  /// \brief The column of a \c ? in a conditional expression;
+  unsigned QuestionColumn;
+
+  /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
+  /// lines, in this context.
+  bool AvoidBinPacking;
+
+  /// \brief Break after the next comma (or all the commas in this context if
+  /// \c AvoidBinPacking is \c true).
+  bool BreakBeforeParameter;
+
+  /// \brief Line breaking in this context would break a formatting rule.
+  bool NoLineBreak;
+
+  /// \brief The position of the colon in an ObjC method declaration/call.
+  unsigned ColonPos;
+
+  /// \brief The start of the most recent function in a builder-type call.
+  unsigned StartOfFunctionCall;
+
+  /// \brief Contains the start of array subscript expressions, so that they
+  /// can be aligned.
+  unsigned StartOfArraySubscripts;
+
+  /// \brief If a nested name specifier was broken over multiple lines, this
+  /// contains the start column of the second line. Otherwise 0.
+  unsigned NestedNameSpecifierContinuation;
+
+  /// \brief If a call expression was broken over multiple lines, this
+  /// contains the start column of the second line. Otherwise 0.
+  unsigned CallContinuation;
+
+  /// \brief The column of the first variable name in a variable declaration.
+  ///
+  /// Used to align further variables if necessary.
+  unsigned VariablePos;
+
+  /// \brief \c true if this \c ParenState already contains a line-break.
+  ///
+  /// The first line break in a certain \c ParenState causes extra penalty so
+  /// that clang-format prefers similar breaks, i.e. breaks in the same
+  /// parenthesis.
+  bool ContainsLineBreak;
+
+  bool operator<(const ParenState &Other) const {
+    if (Indent != Other.Indent)
+      return Indent < Other.Indent;
+    if (LastSpace != Other.LastSpace)
+      return LastSpace < Other.LastSpace;
+    if (FirstLessLess != Other.FirstLessLess)
+      return FirstLessLess < Other.FirstLessLess;
+    if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
+      return BreakBeforeClosingBrace;
+    if (QuestionColumn != Other.QuestionColumn)
+      return QuestionColumn < Other.QuestionColumn;
+    if (AvoidBinPacking != Other.AvoidBinPacking)
+      return AvoidBinPacking;
+    if (BreakBeforeParameter != Other.BreakBeforeParameter)
+      return BreakBeforeParameter;
+    if (NoLineBreak != Other.NoLineBreak)
+      return NoLineBreak;
+    if (ColonPos != Other.ColonPos)
+      return ColonPos < Other.ColonPos;
+    if (StartOfFunctionCall != Other.StartOfFunctionCall)
+      return StartOfFunctionCall < Other.StartOfFunctionCall;
+    if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
+      return StartOfArraySubscripts < Other.StartOfArraySubscripts;
+    if (CallContinuation != Other.CallContinuation)
+      return CallContinuation < Other.CallContinuation;
+    if (VariablePos != Other.VariablePos)
+      return VariablePos < Other.VariablePos;
+    if (ContainsLineBreak != Other.ContainsLineBreak)
+      return ContainsLineBreak < Other.ContainsLineBreak;
+    return false;
+  }
+};
+
+/// \brief The current state when indenting a unwrapped line.
+///
+/// As the indenting tries different combinations this is copied by value.
+struct LineState {
+  /// \brief The number of used columns in the current line.
+  unsigned Column;
+
+  /// \brief The token that needs to be next formatted.
+  const FormatToken *NextToken;
+
+  /// \brief \c true if this line contains a continued for-loop section.
+  bool LineContainsContinuedForLoopSection;
+
+  /// \brief The level of nesting inside (), [], <> and {}.
+  unsigned ParenLevel;
+
+  /// \brief The \c ParenLevel at the start of this line.
+  unsigned StartOfLineLevel;
+
+  /// \brief The lowest \c ParenLevel on the current line.
+  unsigned LowestLevelOnLine;
+
+  /// \brief The start column of the string literal, if we're in a string
+  /// literal sequence, 0 otherwise.
+  unsigned StartOfStringLiteral;
+
+  /// \brief A stack keeping track of properties applying to parenthesis
+  /// levels.
+  std::vector<ParenState> Stack;
+
+  /// \brief Ignore the stack of \c ParenStates for state comparison.
+  ///
+  /// In long and deeply nested unwrapped lines, the current algorithm can
+  /// be insufficient for finding the best formatting with a reasonable amount
+  /// of time and memory. Setting this flag will effectively lead to the
+  /// algorithm not analyzing some combinations. However, these combinations
+  /// rarely contain the optimal solution: In short, accepting a higher
+  /// penalty early would need to lead to different values in the \c
+  /// ParenState stack (in an otherwise identical state) and these different
+  /// values would need to lead to a significant amount of avoided penalty
+  /// later.
+  ///
+  /// FIXME: Come up with a better algorithm instead.
+  bool IgnoreStackForComparison;
+
+  /// \brief Comparison operator to be able to used \c LineState in \c map.
+  bool operator<(const LineState &Other) const {
+    if (NextToken != Other.NextToken)
+      return NextToken < Other.NextToken;
+    if (Column != Other.Column)
+      return Column < Other.Column;
+    if (LineContainsContinuedForLoopSection !=
+        Other.LineContainsContinuedForLoopSection)
+      return LineContainsContinuedForLoopSection;
+    if (ParenLevel != Other.ParenLevel)
+      return ParenLevel < Other.ParenLevel;
+    if (StartOfLineLevel != Other.StartOfLineLevel)
+      return StartOfLineLevel < Other.StartOfLineLevel;
+    if (LowestLevelOnLine != Other.LowestLevelOnLine)
+      return LowestLevelOnLine < Other.LowestLevelOnLine;
+    if (StartOfStringLiteral != Other.StartOfStringLiteral)
+      return StartOfStringLiteral < Other.StartOfStringLiteral;
+    if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
+      return false;
+    return Stack < Other.Stack;
+  }
+};
+
+} // end namespace format
+} // end namespace clang
+
+#endif // LLVM_CLANG_FORMAT_CONTINUATION_INDENTER_H

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=188543&r1=188542&r2=188543&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Fri Aug 16 06:20:30 2013
@@ -15,12 +15,11 @@
 
 #define DEBUG_TYPE "format-formatter"
 
-#include "BreakableToken.h"
+#include "ContinuationIndenter.h"
 #include "TokenAnnotator.h"
 #include "UnwrappedLineParser.h"
 #include "WhitespaceManager.h"
 #include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/OperatorPrecedence.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
@@ -300,67 +299,37 @@ std::string configurationAsText(const Fo
   return Stream.str();
 }
 
-// Returns the length of everything up to the first possible line break after
-// the ), ], } or > matching \c Tok.
-static unsigned getLengthToMatchingParen(const FormatToken &Tok) {
-  if (Tok.MatchingParen == NULL)
-    return 0;
-  FormatToken *End = Tok.MatchingParen;
-  while (End->Next && !End->Next->CanBreakBefore) {
-    End = End->Next;
-  }
-  return End->TotalLength - Tok.TotalLength + 1;
-}
-
 namespace {
 
-class UnwrappedLineFormatter {
+class NoColumnLimitFormatter {
 public:
-  UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
-                         const AnnotatedLine &Line, unsigned FirstIndent,
-                         const FormatToken *RootToken,
-                         WhitespaceManager &Whitespaces,
-                         encoding::Encoding Encoding,
-                         bool BinPackInconclusiveFunctions)
-      : Style(Style), SourceMgr(SourceMgr), Line(Line),
-        FirstIndent(FirstIndent), RootToken(RootToken),
-        Whitespaces(Whitespaces), Count(0), Encoding(Encoding),
-        BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}
-
-  /// \brief Formats an \c UnwrappedLine.
-  void format(const AnnotatedLine *NextLine) {
-    // Initialize state dependent on indent.
-    LineState State;
-    State.Column = FirstIndent;
-    State.NextToken = RootToken;
-    State.Stack.push_back(ParenState(FirstIndent, FirstIndent,
-                                     /*AvoidBinPacking=*/false,
-                                     /*NoLineBreak=*/false));
-    State.LineContainsContinuedForLoopSection = false;
-    State.ParenLevel = 0;
-    State.StartOfStringLiteral = 0;
-    State.StartOfLineLevel = State.ParenLevel;
-    State.LowestLevelOnLine = State.ParenLevel;
-    State.IgnoreStackForComparison = false;
-
-    // The first token has already been indented and thus consumed.
-    moveStateToNextToken(State, /*DryRun=*/false, /*Newline=*/false);
+  NoColumnLimitFormatter(ContinuationIndenter *Indenter)
+      : Indenter(Indenter) {}
 
-    if (Style.ColumnLimit == 0) {
-      formatWithoutColumnLimit(State);
-      return;
+  /// \brief Formats the line starting at \p State, simply keeping all of the
+  /// input's line breaking decisions.
+  void format() {
+    LineState State = Indenter->getInitialState();
+    while (State.NextToken != NULL) {
+      bool Newline =
+          Indenter->mustBreak(State) ||
+          (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
+      Indenter->addTokenToState(State, Newline, /*DryRun=*/false);
     }
+  }
+private:
+  ContinuationIndenter *Indenter;
+};
 
-    // If everything fits on a single line, just put it there.
-    unsigned ColumnLimit = Style.ColumnLimit;
-    if (NextLine && NextLine->InPPDirective &&
-        !NextLine->First->HasUnescapedNewline)
-      ColumnLimit = getColumnLimit();
-    if (Line.Last->TotalLength <= ColumnLimit - FirstIndent) {
-      while (State.NextToken != NULL) {
-        addTokenToState(false, false, State);
-      }
-    }
+class UnwrappedLineFormatter {
+public:
+  UnwrappedLineFormatter(ContinuationIndenter *Indenter,
+                         const FormatStyle &Style, const AnnotatedLine &Line)
+      : Indenter(Indenter), Style(Style), Line(Line), Count(0) {}
+
+  /// \brief Formats an \c UnwrappedLine.
+  void format() {
+    LineState State = Indenter->getInitialState();
 
     // If the ObjC method declaration does not fit on a line, we should format
     // it with one arg per line.
@@ -372,717 +341,6 @@ public:
   }
 
 private:
-  void DebugTokenState(const FormatToken &FormatTok) {
-    const Token &Tok = FormatTok.Tok;
-    llvm::dbgs() << StringRef(SourceMgr.getCharacterData(Tok.getLocation()),
-                              Tok.getLength());
-    llvm::dbgs();
-  }
-
-  struct ParenState {
-    ParenState(unsigned Indent, unsigned LastSpace, bool AvoidBinPacking,
-               bool NoLineBreak)
-        : Indent(Indent), LastSpace(LastSpace), FirstLessLess(0),
-          BreakBeforeClosingBrace(false), QuestionColumn(0),
-          AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
-          NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
-          StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
-          CallContinuation(0), VariablePos(0), ContainsLineBreak(false) {}
-
-    /// \brief The position to which a specific parenthesis level needs to be
-    /// indented.
-    unsigned Indent;
-
-    /// \brief The position of the last space on each level.
-    ///
-    /// Used e.g. to break like:
-    /// functionCall(Parameter, otherCall(
-    ///                             OtherParameter));
-    unsigned LastSpace;
-
-    /// \brief The position the first "<<" operator encountered on each level.
-    ///
-    /// Used to align "<<" operators. 0 if no such operator has been encountered
-    /// on a level.
-    unsigned FirstLessLess;
-
-    /// \brief Whether a newline needs to be inserted before the block's closing
-    /// brace.
-    ///
-    /// We only want to insert a newline before the closing brace if there also
-    /// was a newline after the beginning left brace.
-    bool BreakBeforeClosingBrace;
-
-    /// \brief The column of a \c ? in a conditional expression;
-    unsigned QuestionColumn;
-
-    /// \brief Avoid bin packing, i.e. multiple parameters/elements on multiple
-    /// lines, in this context.
-    bool AvoidBinPacking;
-
-    /// \brief Break after the next comma (or all the commas in this context if
-    /// \c AvoidBinPacking is \c true).
-    bool BreakBeforeParameter;
-
-    /// \brief Line breaking in this context would break a formatting rule.
-    bool NoLineBreak;
-
-    /// \brief The position of the colon in an ObjC method declaration/call.
-    unsigned ColonPos;
-
-    /// \brief The start of the most recent function in a builder-type call.
-    unsigned StartOfFunctionCall;
-
-    /// \brief Contains the start of array subscript expressions, so that they
-    /// can be aligned.
-    unsigned StartOfArraySubscripts;
-
-    /// \brief If a nested name specifier was broken over multiple lines, this
-    /// contains the start column of the second line. Otherwise 0.
-    unsigned NestedNameSpecifierContinuation;
-
-    /// \brief If a call expression was broken over multiple lines, this
-    /// contains the start column of the second line. Otherwise 0.
-    unsigned CallContinuation;
-
-    /// \brief The column of the first variable name in a variable declaration.
-    ///
-    /// Used to align further variables if necessary.
-    unsigned VariablePos;
-
-    /// \brief \c true if this \c ParenState already contains a line-break.
-    ///
-    /// The first line break in a certain \c ParenState causes extra penalty so
-    /// that clang-format prefers similar breaks, i.e. breaks in the same
-    /// parenthesis.
-    bool ContainsLineBreak;
-
-    bool operator<(const ParenState &Other) const {
-      if (Indent != Other.Indent)
-        return Indent < Other.Indent;
-      if (LastSpace != Other.LastSpace)
-        return LastSpace < Other.LastSpace;
-      if (FirstLessLess != Other.FirstLessLess)
-        return FirstLessLess < Other.FirstLessLess;
-      if (BreakBeforeClosingBrace != Other.BreakBeforeClosingBrace)
-        return BreakBeforeClosingBrace;
-      if (QuestionColumn != Other.QuestionColumn)
-        return QuestionColumn < Other.QuestionColumn;
-      if (AvoidBinPacking != Other.AvoidBinPacking)
-        return AvoidBinPacking;
-      if (BreakBeforeParameter != Other.BreakBeforeParameter)
-        return BreakBeforeParameter;
-      if (NoLineBreak != Other.NoLineBreak)
-        return NoLineBreak;
-      if (ColonPos != Other.ColonPos)
-        return ColonPos < Other.ColonPos;
-      if (StartOfFunctionCall != Other.StartOfFunctionCall)
-        return StartOfFunctionCall < Other.StartOfFunctionCall;
-      if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
-        return StartOfArraySubscripts < Other.StartOfArraySubscripts;
-      if (CallContinuation != Other.CallContinuation)
-        return CallContinuation < Other.CallContinuation;
-      if (VariablePos != Other.VariablePos)
-        return VariablePos < Other.VariablePos;
-      if (ContainsLineBreak != Other.ContainsLineBreak)
-        return ContainsLineBreak < Other.ContainsLineBreak;
-      return false;
-    }
-  };
-
-  /// \brief The current state when indenting a unwrapped line.
-  ///
-  /// As the indenting tries different combinations this is copied by value.
-  struct LineState {
-    /// \brief The number of used columns in the current line.
-    unsigned Column;
-
-    /// \brief The token that needs to be next formatted.
-    const FormatToken *NextToken;
-
-    /// \brief \c true if this line contains a continued for-loop section.
-    bool LineContainsContinuedForLoopSection;
-
-    /// \brief The level of nesting inside (), [], <> and {}.
-    unsigned ParenLevel;
-
-    /// \brief The \c ParenLevel at the start of this line.
-    unsigned StartOfLineLevel;
-
-    /// \brief The lowest \c ParenLevel on the current line.
-    unsigned LowestLevelOnLine;
-
-    /// \brief The start column of the string literal, if we're in a string
-    /// literal sequence, 0 otherwise.
-    unsigned StartOfStringLiteral;
-
-    /// \brief A stack keeping track of properties applying to parenthesis
-    /// levels.
-    std::vector<ParenState> Stack;
-
-    /// \brief Ignore the stack of \c ParenStates for state comparison.
-    ///
-    /// In long and deeply nested unwrapped lines, the current algorithm can
-    /// be insufficient for finding the best formatting with a reasonable amount
-    /// of time and memory. Setting this flag will effectively lead to the
-    /// algorithm not analyzing some combinations. However, these combinations
-    /// rarely contain the optimal solution: In short, accepting a higher
-    /// penalty early would need to lead to different values in the \c
-    /// ParenState stack (in an otherwise identical state) and these different
-    /// values would need to lead to a significant amount of avoided penalty
-    /// later.
-    ///
-    /// FIXME: Come up with a better algorithm instead.
-    bool IgnoreStackForComparison;
-
-    /// \brief Comparison operator to be able to used \c LineState in \c map.
-    bool operator<(const LineState &Other) const {
-      if (NextToken != Other.NextToken)
-        return NextToken < Other.NextToken;
-      if (Column != Other.Column)
-        return Column < Other.Column;
-      if (LineContainsContinuedForLoopSection !=
-          Other.LineContainsContinuedForLoopSection)
-        return LineContainsContinuedForLoopSection;
-      if (ParenLevel != Other.ParenLevel)
-        return ParenLevel < Other.ParenLevel;
-      if (StartOfLineLevel != Other.StartOfLineLevel)
-        return StartOfLineLevel < Other.StartOfLineLevel;
-      if (LowestLevelOnLine != Other.LowestLevelOnLine)
-        return LowestLevelOnLine < Other.LowestLevelOnLine;
-      if (StartOfStringLiteral != Other.StartOfStringLiteral)
-        return StartOfStringLiteral < Other.StartOfStringLiteral;
-      if (IgnoreStackForComparison || Other.IgnoreStackForComparison)
-        return false;
-      return Stack < Other.Stack;
-    }
-  };
-
-  /// \brief Formats the line starting at \p State, simply keeping all of the
-  /// input's line breaking decisions.
-  void formatWithoutColumnLimit(LineState &State) {
-    while (State.NextToken != NULL) {
-      bool Newline = mustBreak(State) ||
-                     (canBreak(State) && State.NextToken->NewlinesBefore > 0);
-      addTokenToState(Newline, /*DryRun=*/false, State);
-    }
-  }
-
-  /// \brief Appends the next token to \p State and updates information
-  /// necessary for indentation.
-  ///
-  /// Puts the token on the current line if \p Newline is \c false and adds a
-  /// line break and necessary indentation otherwise.
-  ///
-  /// If \p DryRun is \c false, also creates and stores the required
-  /// \c Replacement.
-  unsigned addTokenToState(bool Newline, bool DryRun, LineState &State) {
-    const FormatToken &Current = *State.NextToken;
-    const FormatToken &Previous = *State.NextToken->Previous;
-
-    // Extra penalty that needs to be added because of the way certain line
-    // breaks are chosen.
-    unsigned ExtraPenalty = 0;
-
-    if (State.Stack.size() == 0 || Current.Type == TT_ImplicitStringLiteral) {
-      // FIXME: Is this correct?
-      int WhitespaceLength = SourceMgr.getSpellingColumnNumber(
-                                 State.NextToken->WhitespaceRange.getEnd()) -
-                             SourceMgr.getSpellingColumnNumber(
-                                 State.NextToken->WhitespaceRange.getBegin());
-      State.Column += WhitespaceLength + State.NextToken->CodePointCount;
-      State.NextToken = State.NextToken->Next;
-      return 0;
-    }
-
-    // If we are continuing an expression, we want to indent an extra 4 spaces.
-    unsigned ContinuationIndent =
-        std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) + 4;
-    if (Newline) {
-      // 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)
-        ExtraPenalty += Style.PenaltyBreakFirstLessLess;
-
-      State.Stack.back().ContainsLineBreak = true;
-      if (Current.is(tok::r_brace)) {
-        if (Current.BlockKind == BK_BracedInit)
-          State.Column = State.Stack[State.Stack.size() - 2].LastSpace;
-        else
-          State.Column = FirstIndent;
-      } else if (Current.is(tok::string_literal) &&
-                 State.StartOfStringLiteral != 0) {
-        State.Column = State.StartOfStringLiteral;
-        State.Stack.back().BreakBeforeParameter = true;
-      } else if (Current.is(tok::lessless) &&
-                 State.Stack.back().FirstLessLess != 0) {
-        State.Column = State.Stack.back().FirstLessLess;
-      } else if (Current.isOneOf(tok::period, tok::arrow) &&
-                 Current.Type != TT_DesignatedInitializerPeriod) {
-        if (State.Stack.back().CallContinuation == 0) {
-          State.Column = ContinuationIndent;
-          State.Stack.back().CallContinuation = State.Column;
-        } else {
-          State.Column = State.Stack.back().CallContinuation;
-        }
-      } else if (Current.Type == TT_ConditionalExpr) {
-        State.Column = State.Stack.back().QuestionColumn;
-      } else if (Previous.is(tok::comma) &&
-                 State.Stack.back().VariablePos != 0) {
-        State.Column = State.Stack.back().VariablePos;
-      } else if (Previous.ClosesTemplateDeclaration ||
-                 ((Current.Type == TT_StartOfName ||
-                   Current.is(tok::kw_operator)) &&
-                  State.ParenLevel == 0 &&
-                  (!Style.IndentFunctionDeclarationAfterType ||
-                   Line.StartsDefinition))) {
-        State.Column = State.Stack.back().Indent;
-      } else if (Current.Type == TT_ObjCSelectorName) {
-        if (State.Stack.back().ColonPos > Current.CodePointCount) {
-          State.Column = State.Stack.back().ColonPos - Current.CodePointCount;
-        } else {
-          State.Column = State.Stack.back().Indent;
-          State.Stack.back().ColonPos = State.Column + Current.CodePointCount;
-        }
-      } else if (Current.is(tok::l_square) &&
-                 Current.Type != TT_ObjCMethodExpr) {
-        if (State.Stack.back().StartOfArraySubscripts != 0)
-          State.Column = State.Stack.back().StartOfArraySubscripts;
-        else
-          State.Column = ContinuationIndent;
-      } else if (Current.Type == TT_StartOfName ||
-                 Previous.isOneOf(tok::coloncolon, tok::equal) ||
-                 Previous.Type == TT_ObjCMethodExpr) {
-        State.Column = ContinuationIndent;
-      } else if (Current.Type == TT_CtorInitializerColon) {
-        State.Column = FirstIndent + Style.ConstructorInitializerIndentWidth;
-      } else if (Current.Type == TT_CtorInitializerComma) {
-        State.Column = State.Stack.back().Indent;
-      } else {
-        State.Column = State.Stack.back().Indent;
-        // Ensure that we fall back to indenting 4 spaces instead of just
-        // flushing continuations left.
-        if (State.Column == FirstIndent)
-          State.Column += 4;
-      }
-
-      if (Current.is(tok::question))
-        State.Stack.back().BreakBeforeParameter = true;
-      if ((Previous.isOneOf(tok::comma, tok::semi) &&
-           !State.Stack.back().AvoidBinPacking) ||
-          Previous.Type == TT_BinaryOperator)
-        State.Stack.back().BreakBeforeParameter = false;
-      if (Previous.Type == TT_TemplateCloser && State.ParenLevel == 0)
-        State.Stack.back().BreakBeforeParameter = false;
-
-      if (!DryRun) {
-        unsigned NewLines = 1;
-        if (Current.is(tok::comment))
-          NewLines = std::max(
-              NewLines,
-              std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1));
-        Whitespaces.replaceWhitespace(Current, NewLines, State.Column,
-                                      State.Column, Line.InPPDirective);
-      }
-
-      if (!Current.isTrailingComment())
-        State.Stack.back().LastSpace = State.Column;
-      if (Current.isOneOf(tok::arrow, tok::period) &&
-          Current.Type != TT_DesignatedInitializerPeriod)
-        State.Stack.back().LastSpace += Current.CodePointCount;
-      State.StartOfLineLevel = State.ParenLevel;
-      State.LowestLevelOnLine = State.ParenLevel;
-
-      // Any break on this level means that the parent level has been broken
-      // and we need to avoid bin packing there.
-      for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
-        State.Stack[i].BreakBeforeParameter = true;
-      }
-      const FormatToken *TokenBefore = Current.getPreviousNonComment();
-      if (TokenBefore && !TokenBefore->isOneOf(tok::comma, tok::semi) &&
-          TokenBefore->Type != TT_TemplateCloser &&
-          TokenBefore->Type != TT_BinaryOperator && !TokenBefore->opensScope())
-        State.Stack.back().BreakBeforeParameter = true;
-
-      // If we break after {, we should also break before the corresponding }.
-      if (Previous.is(tok::l_brace))
-        State.Stack.back().BreakBeforeClosingBrace = true;
-
-      if (State.Stack.back().AvoidBinPacking) {
-        // If we are breaking after '(', '{', '<', this is not bin packing
-        // unless AllowAllParametersOfDeclarationOnNextLine is false.
-        if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) ||
-              Previous.Type == TT_BinaryOperator) ||
-            (!Style.AllowAllParametersOfDeclarationOnNextLine &&
-             Line.MustBeDeclaration))
-          State.Stack.back().BreakBeforeParameter = true;
-      }
-
-    } else {
-      if (Current.is(tok::equal) &&
-          (RootToken->is(tok::kw_for) || State.ParenLevel == 0) &&
-          State.Stack.back().VariablePos == 0) {
-        State.Stack.back().VariablePos = State.Column;
-        // Move over * and & if they are bound to the variable name.
-        const FormatToken *Tok = &Previous;
-        while (Tok && State.Stack.back().VariablePos >= Tok->CodePointCount) {
-          State.Stack.back().VariablePos -= Tok->CodePointCount;
-          if (Tok->SpacesRequiredBefore != 0)
-            break;
-          Tok = Tok->Previous;
-        }
-        if (Previous.PartOfMultiVariableDeclStmt)
-          State.Stack.back().LastSpace = State.Stack.back().VariablePos;
-      }
-
-      unsigned Spaces = State.NextToken->SpacesRequiredBefore;
-
-      if (!DryRun)
-        Whitespaces.replaceWhitespace(Current, 0, Spaces,
-                                      State.Column + Spaces);
-
-      if (Current.Type == TT_ObjCSelectorName &&
-          State.Stack.back().ColonPos == 0) {
-        if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
-            State.Column + Spaces + Current.CodePointCount)
-          State.Stack.back().ColonPos =
-              State.Stack.back().Indent + Current.LongestObjCSelectorName;
-        else
-          State.Stack.back().ColonPos =
-              State.Column + Spaces + Current.CodePointCount;
-      }
-
-      if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr &&
-          Current.Type != TT_LineComment)
-        State.Stack.back().Indent = State.Column + Spaces;
-      if (Previous.is(tok::comma) && !Current.isTrailingComment() &&
-          State.Stack.back().AvoidBinPacking)
-        State.Stack.back().NoLineBreak = true;
-
-      State.Column += Spaces;
-      if (Current.is(tok::l_paren) && Previous.isOneOf(tok::kw_if, tok::kw_for))
-        // Treat the condition inside an if as if it was a second function
-        // parameter, i.e. let nested calls have an indent of 4.
-        State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
-      else if (Previous.is(tok::comma))
-        State.Stack.back().LastSpace = State.Column;
-      else if ((Previous.Type == TT_BinaryOperator ||
-                Previous.Type == TT_ConditionalExpr ||
-                Previous.Type == TT_CtorInitializerColon) &&
-               !(Previous.getPrecedence() == prec::Assignment &&
-                 Current.FakeLParens.empty()))
-        // Always indent relative to the RHS of the expression unless this is a
-        // simple assignment without binary expression on the RHS.
-        State.Stack.back().LastSpace = State.Column;
-      else if (Previous.Type == TT_InheritanceColon)
-        State.Stack.back().Indent = State.Column;
-      else if (Previous.opensScope()) {
-        // If a function has multiple parameters (including a single parameter
-        // that is a binary expression) or a trailing call, indent all
-        // parameters from the opening parenthesis. This avoids confusing
-        // indents like:
-        //   OuterFunction(InnerFunctionCall(
-        //       ParameterToInnerFunction),
-        //                 SecondParameterToOuterFunction);
-        bool HasMultipleParameters = !Current.FakeLParens.empty();
-        bool HasTrailingCall = false;
-        if (Previous.MatchingParen) {
-          const FormatToken *Next = Previous.MatchingParen->getNextNonComment();
-          if (Next && Next->isOneOf(tok::period, tok::arrow))
-            HasTrailingCall = true;
-        }
-        if (HasMultipleParameters || HasTrailingCall)
-          State.Stack.back().LastSpace = State.Column;
-      }
-    }
-
-    return moveStateToNextToken(State, DryRun, Newline) + ExtraPenalty;
-  }
-
-  /// \brief Mark the next token as consumed in \p State and modify its stacks
-  /// accordingly.
-  unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline) {
-    const FormatToken &Current = *State.NextToken;
-    assert(State.Stack.size());
-
-    if (Current.Type == TT_InheritanceColon)
-      State.Stack.back().AvoidBinPacking = true;
-    if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
-      State.Stack.back().FirstLessLess = State.Column;
-    if (Current.is(tok::l_square) &&
-        State.Stack.back().StartOfArraySubscripts == 0)
-      State.Stack.back().StartOfArraySubscripts = State.Column;
-    if (Current.is(tok::question))
-      State.Stack.back().QuestionColumn = State.Column;
-    if (!Current.opensScope() && !Current.closesScope())
-      State.LowestLevelOnLine =
-          std::min(State.LowestLevelOnLine, State.ParenLevel);
-    if (Current.isOneOf(tok::period, tok::arrow) &&
-        Line.Type == LT_BuilderTypeCall && State.ParenLevel == 0)
-      State.Stack.back().StartOfFunctionCall =
-          Current.LastInChainOfCalls ? 0
-                                     : State.Column + Current.CodePointCount;
-    if (Current.Type == TT_CtorInitializerColon) {
-      // Indent 2 from the column, so:
-      // SomeClass::SomeClass()
-      //     : First(...), ...
-      //       Next(...)
-      //       ^ line up here.
-      State.Stack.back().Indent =
-          State.Column +
-          (Style.BreakConstructorInitializersBeforeComma ? 0 : 2);
-      if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
-        State.Stack.back().AvoidBinPacking = true;
-      State.Stack.back().BreakBeforeParameter = false;
-    }
-
-    // If return returns a binary expression, align after it.
-    if (Current.is(tok::kw_return) && !Current.FakeLParens.empty())
-      State.Stack.back().LastSpace = State.Column + 7;
-
-    // In ObjC method declaration we align on the ":" of parameters, but we need
-    // to ensure that we indent parameters on subsequent lines by at least 4.
-    if (Current.Type == TT_ObjCMethodSpecifier)
-      State.Stack.back().Indent += 4;
-
-    // Insert scopes created by fake parenthesis.
-    const FormatToken *Previous = Current.getPreviousNonComment();
-    // Don't add extra indentation for the first fake parenthesis after
-    // 'return', assignements or opening <({[. The indentation for these cases
-    // is special cased.
-    bool SkipFirstExtraIndent =
-        Current.is(tok::kw_return) ||
-        (Previous && (Previous->opensScope() ||
-                      Previous->getPrecedence() == prec::Assignment));
-    for (SmallVectorImpl<prec::Level>::const_reverse_iterator
-             I = Current.FakeLParens.rbegin(),
-             E = Current.FakeLParens.rend();
-         I != E; ++I) {
-      ParenState NewParenState = State.Stack.back();
-      NewParenState.ContainsLineBreak = false;
-      NewParenState.Indent =
-          std::max(std::max(State.Column, NewParenState.Indent),
-                   State.Stack.back().LastSpace);
-
-      // Always indent conditional expressions. Never indent expression where
-      // the 'operator' is ',', ';' or an assignment (i.e. *I <=
-      // prec::Assignment) as those have different indentation rules. Indent
-      // other expression, unless the indentation needs to be skipped.
-      if (*I == prec::Conditional ||
-          (!SkipFirstExtraIndent && *I > prec::Assignment &&
-           !Style.BreakBeforeBinaryOperators))
-        NewParenState.Indent += 4;
-      if (Previous && !Previous->opensScope())
-        NewParenState.BreakBeforeParameter = false;
-      State.Stack.push_back(NewParenState);
-      SkipFirstExtraIndent = false;
-    }
-
-    // If we encounter an opening (, [, { or <, we add a level to our stacks to
-    // 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 =
-            LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);
-        const FormatToken *NextNoComment = Current.getNextNonComment();
-        AvoidBinPacking = NextNoComment &&
-                          NextNoComment->Type == TT_DesignatedInitializerPeriod;
-      } else {
-        NewIndent =
-            4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall);
-        AvoidBinPacking = !Style.BinPackParameters ||
-                          (Style.ExperimentalAutoDetectBinPacking &&
-                           (Current.PackingKind == PPK_OnePerLine ||
-                            (!BinPackInconclusiveFunctions &&
-                             Current.PackingKind == PPK_Inconclusive)));
-      }
-
-      State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking,
-                                       State.Stack.back().NoLineBreak));
-      ++State.ParenLevel;
-    }
-
-    // If this '[' opens an ObjC call, determine whether all parameters fit into
-    // one line and put one per line if they don't.
-    if (Current.is(tok::l_square) && Current.Type == TT_ObjCMethodExpr &&
-        Current.MatchingParen != NULL) {
-      if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())
-        State.Stack.back().BreakBeforeParameter = true;
-    }
-
-    // If we encounter a closing ), ], } or >, we can remove a level from our
-    // stacks.
-    if (Current.isOneOf(tok::r_paren, tok::r_square) ||
-        (Current.is(tok::r_brace) && State.NextToken != RootToken) ||
-        State.NextToken->Type == TT_TemplateCloser) {
-      State.Stack.pop_back();
-      --State.ParenLevel;
-    }
-    if (Current.is(tok::r_square)) {
-      // If this ends the array subscript expr, reset the corresponding value.
-      const FormatToken *NextNonComment = Current.getNextNonComment();
-      if (NextNonComment && NextNonComment->isNot(tok::l_square))
-        State.Stack.back().StartOfArraySubscripts = 0;
-    }
-
-    // Remove scopes created by fake parenthesis.
-    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
-      unsigned VariablePos = State.Stack.back().VariablePos;
-      State.Stack.pop_back();
-      State.Stack.back().VariablePos = VariablePos;
-    }
-
-    if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) {
-      State.StartOfStringLiteral = State.Column;
-    } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash,
-                                tok::string_literal)) {
-      State.StartOfStringLiteral = 0;
-    }
-
-    State.Column += Current.CodePointCount;
-
-    State.NextToken = State.NextToken->Next;
-
-    if (!Newline && Style.AlwaysBreakBeforeMultilineStrings &&
-        Current.is(tok::string_literal) && Current.CanBreakBefore)
-      return 0;
-
-    return breakProtrudingToken(Current, State, DryRun);
-  }
-
-  /// \brief If the current token sticks out over the end of the line, break
-  /// it if possible.
-  ///
-  /// \returns An extra penalty if a token was broken, otherwise 0.
-  ///
-  /// The returned penalty will cover the cost of the additional line breaks and
-  /// column limit violation in all lines except for the last one. The penalty
-  /// for the column limit violation in the last line (and in single line
-  /// tokens) is handled in \c addNextStateToQueue.
-  unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
-                                bool DryRun) {
-    llvm::OwningPtr<BreakableToken> Token;
-    unsigned StartColumn = State.Column - Current.CodePointCount;
-    unsigned OriginalStartColumn =
-        SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) -
-        1;
-
-    if (Current.is(tok::string_literal) &&
-        Current.Type != TT_ImplicitStringLiteral) {
-      // Only break up default narrow strings.
-      if (!Current.TokenText.startswith("\""))
-        return 0;
-      // Don't break string literals with escaped newlines. As clang-format must
-      // not change the string's content, it is unlikely that we'll end up with
-      // a better format.
-      if (Current.TokenText.find("\\\n") != StringRef::npos)
-        return 0;
-      // Exempts unterminated string literals from line breaking. The user will
-      // likely want to terminate the string before any line breaking is done.
-      if (Current.IsUnterminatedLiteral)
-        return 0;
-
-      Token.reset(new BreakableStringLiteral(Current, StartColumn,
-                                             Line.InPPDirective, Encoding));
-    } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
-      Token.reset(new BreakableBlockComment(
-          Style, Current, StartColumn, OriginalStartColumn, !Current.Previous,
-          Line.InPPDirective, Encoding));
-    } else if (Current.Type == TT_LineComment &&
-               (Current.Previous == NULL ||
-                Current.Previous->Type != TT_ImplicitStringLiteral)) {
-      // Don't break line comments with escaped newlines. These look like
-      // separate line comments, but in fact contain a single line comment with
-      // multiple lines including leading whitespace and the '//' markers.
-      //
-      // FIXME: If we want to handle them correctly, we'll need to adjust
-      // leading whitespace in consecutive lines when changing indentation of
-      // the first line similar to what we do with block comments.
-      StringRef::size_type EscapedNewlinePos = Current.TokenText.find("\\\n");
-      if (EscapedNewlinePos != StringRef::npos) {
-        State.Column =
-            StartColumn +
-            encoding::getCodePointCount(
-                Current.TokenText.substr(0, EscapedNewlinePos), Encoding) +
-            1;
-        return 0;
-      }
-
-      Token.reset(new BreakableLineComment(Current, StartColumn,
-                                           Line.InPPDirective, Encoding));
-    } else {
-      return 0;
-    }
-    if (Current.UnbreakableTailLength >= getColumnLimit())
-      return 0;
-
-    unsigned RemainingSpace = getColumnLimit() - Current.UnbreakableTailLength;
-    bool BreakInserted = false;
-    unsigned Penalty = 0;
-    unsigned RemainingTokenColumns = 0;
-    for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
-         LineIndex != EndIndex; ++LineIndex) {
-      if (!DryRun)
-        Token->replaceWhitespaceBefore(LineIndex, Whitespaces);
-      unsigned TailOffset = 0;
-      RemainingTokenColumns = Token->getLineLengthAfterSplit(
-          LineIndex, TailOffset, StringRef::npos);
-      while (RemainingTokenColumns > RemainingSpace) {
-        BreakableToken::Split Split =
-            Token->getSplit(LineIndex, TailOffset, getColumnLimit());
-        if (Split.first == StringRef::npos) {
-          // The last line's penalty is handled in addNextStateToQueue().
-          if (LineIndex < EndIndex - 1)
-            Penalty += Style.PenaltyExcessCharacter *
-                       (RemainingTokenColumns - RemainingSpace);
-          break;
-        }
-        assert(Split.first != 0);
-        unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
-            LineIndex, TailOffset + Split.first + Split.second,
-            StringRef::npos);
-        assert(NewRemainingTokenColumns < RemainingTokenColumns);
-        if (!DryRun)
-          Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
-        Penalty += Current.is(tok::string_literal) ? Style.PenaltyBreakString
-                                                   : Style.PenaltyBreakComment;
-        unsigned ColumnsUsed =
-            Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
-        if (ColumnsUsed > getColumnLimit()) {
-          Penalty +=
-              Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit());
-        }
-        TailOffset += Split.first + Split.second;
-        RemainingTokenColumns = NewRemainingTokenColumns;
-        BreakInserted = true;
-      }
-    }
-
-    State.Column = RemainingTokenColumns;
-
-    if (BreakInserted) {
-      // If we break the token inside a parameter list, we need to break before
-      // the next parameter on all levels, so that the next parameter is clearly
-      // visible. Line comments already introduce a break.
-      if (Current.Type != TT_LineComment) {
-        for (unsigned i = 0, e = State.Stack.size(); i != e; ++i)
-          State.Stack[i].BreakBeforeParameter = true;
-      }
-
-      State.Stack.back().LastSpace = StartColumn;
-    }
-    return Penalty;
-  }
-
-  unsigned getColumnLimit() {
-    // In preprocessor directives reserve two chars for trailing " \"
-    return Style.ColumnLimit - (Line.InPPDirective ? 2 : 0);
-  }
-
   /// \brief An edge in the solution space from \c Previous->State to \c State,
   /// inserting a newline dependent on the \c NewLine.
   struct StateNode {
@@ -1173,7 +431,7 @@ private:
                        << (*I)->Previous->State.NextToken->SplitPenalty << "\n";
         }
       });
-      addTokenToState((*I)->NewLine, false, State);
+      Indenter->addTokenToState(State, (*I)->NewLine, false);
     }
   }
 
@@ -1183,9 +441,9 @@ private:
   /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.
   void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,
                            bool NewLine) {
-    if (NewLine && !canBreak(PreviousNode->State))
+    if (NewLine && !Indenter->canBreak(PreviousNode->State))
       return;
-    if (!NewLine && mustBreak(PreviousNode->State))
+    if (!NewLine && Indenter->mustBreak(PreviousNode->State))
       return;
     if (NewLine) {
       if (!PreviousNode->State.Stack.back().ContainsLineBreak)
@@ -1195,9 +453,10 @@ private:
 
     StateNode *Node = new (Allocator.Allocate())
         StateNode(PreviousNode->State, NewLine, PreviousNode);
-    Penalty += addTokenToState(NewLine, true, Node->State);
-    if (Node->State.Column > getColumnLimit()) {
-      unsigned ExcessCharacters = Node->State.Column - getColumnLimit();
+    Penalty += Indenter->addTokenToState(Node->State, NewLine, true);
+    if (Node->State.Column > Indenter->getColumnLimit()) {
+      unsigned ExcessCharacters =
+          Node->State.Column - Indenter->getColumnLimit();
       Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
     }
 
@@ -1205,137 +464,15 @@ private:
     ++Count;
   }
 
-  /// \brief Returns \c true, if a line break after \p State is allowed.
-  bool canBreak(const LineState &State) {
-    const FormatToken &Current = *State.NextToken;
-    const FormatToken &Previous = *Current.Previous;
-    assert(&Previous == Current.Previous);
-    if (!Current.CanBreakBefore &&
-        !(Current.is(tok::r_brace) &&
-          State.Stack.back().BreakBeforeClosingBrace))
-      return false;
-    // The opening "{" of a braced list has to be on the same line as the first
-    // element if it is nested in another braced init list or function call.
-    if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&
-        Previous.Previous &&
-        Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma))
-      return false;
-    // This prevents breaks like:
-    //   ...
-    //   SomeParameter, OtherParameter).DoSomething(
-    //   ...
-    // As they hide "DoSomething" and are generally bad for readability.
-    if (Previous.opensScope() &&
-        State.LowestLevelOnLine < State.StartOfLineLevel)
-      return false;
-    return !State.Stack.back().NoLineBreak;
-  }
-
-  /// \brief Returns \c true, if a line break after \p State is mandatory.
-  bool mustBreak(const LineState &State) {
-    const FormatToken &Current = *State.NextToken;
-    const FormatToken &Previous = *Current.Previous;
-    if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon)
-      return true;
-    if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) &&
-        State.Stack.back().BreakBeforeClosingBrace)
-      return true;
-    if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
-      return true;
-    if (Style.BreakConstructorInitializersBeforeComma) {
-      if (Previous.Type == TT_CtorInitializerComma)
-        return false;
-      if (Current.Type == TT_CtorInitializerComma)
-        return true;
-    }
-    if ((Previous.isOneOf(tok::comma, tok::semi) || Current.is(tok::question) ||
-         (Current.Type == TT_ConditionalExpr &&
-          !(Current.is(tok::colon) && Previous.is(tok::question)))) &&
-        State.Stack.back().BreakBeforeParameter &&
-        !Current.isTrailingComment() &&
-        !Current.isOneOf(tok::r_paren, tok::r_brace))
-      return true;
-    if (Style.AlwaysBreakBeforeMultilineStrings &&
-        State.Column > State.Stack.back().Indent &&
-        Current.is(tok::string_literal) && Previous.isNot(tok::lessless) &&
-        Previous.Type != TT_InlineASMColon &&
-        ((Current.getNextNonComment() &&
-          Current.getNextNonComment()->is(tok::string_literal)) ||
-         (Current.TokenText.find("\\\n") != StringRef::npos)))
-      return true;
-
-    if (!Style.BreakBeforeBinaryOperators) {
-      // If we need to break somewhere inside the LHS of a binary expression, we
-      // should also break after the operator. Otherwise, the formatting would
-      // hide the operator precedence, e.g. in:
-      //   if (aaaaaaaaaaaaaa ==
-      //           bbbbbbbbbbbbbb && c) {..
-      // For comparisons, we only apply this rule, if the LHS is a binary
-      // expression itself as otherwise, the line breaks seem superfluous.
-      // We need special cases for ">>" which we have split into two ">" while
-      // lexing in order to make template parsing easier.
-      //
-      // FIXME: We'll need something similar for styles that break before binary
-      // operators.
-      bool IsComparison = (Previous.getPrecedence() == prec::Relational ||
-                           Previous.getPrecedence() == prec::Equality) &&
-                          Previous.Previous && Previous.Previous->Type !=
-                                                   TT_BinaryOperator; // For >>.
-      bool LHSIsBinaryExpr =
-          Previous.Previous && Previous.Previous->FakeRParens > 0;
-      if (Previous.Type == TT_BinaryOperator &&
-          (!IsComparison || LHSIsBinaryExpr) &&
-          Current.Type != TT_BinaryOperator && // For >>.
-          !Current.isTrailingComment() &&
-          !Previous.isOneOf(tok::lessless, tok::question) &&
-          Previous.getPrecedence() != prec::Assignment &&
-          State.Stack.back().BreakBeforeParameter)
-        return true;
-    }
-
-    // Same as above, but for the first "<<" operator.
-    if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
-        State.Stack.back().FirstLessLess == 0)
-      return true;
-
-    // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
-    // out whether it is the first parameter. Clean this up.
-    if (Current.Type == TT_ObjCSelectorName &&
-        Current.LongestObjCSelectorName == 0 &&
-        State.Stack.back().BreakBeforeParameter)
-      return true;
-    if ((Current.Type == TT_CtorInitializerColon ||
-         (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0)))
-      return true;
-
-    if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&
-        Line.MightBeFunctionDecl && State.Stack.back().BreakBeforeParameter &&
-        State.ParenLevel == 0)
-      return true;
-    return false;
-  }
-
-  // Returns the total number of columns required for the remaining tokens.
-  unsigned getRemainingLength(const LineState &State) {
-    if (State.NextToken && State.NextToken->Previous)
-      return Line.Last->TotalLength - State.NextToken->Previous->TotalLength;
-    return 0;
-  }
-
+  ContinuationIndenter *Indenter;
   FormatStyle Style;
-  SourceManager &SourceMgr;
   const AnnotatedLine &Line;
-  const unsigned FirstIndent;
-  const FormatToken *RootToken;
-  WhitespaceManager &Whitespaces;
 
   llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
   QueueType Queue;
   // Increasing count of \c StateNode items we have created. This is used
   // to create a deterministic order independent of the container.
   unsigned Count;
-  encoding::Encoding Encoding;
-  bool BinPackInconclusiveFunctions;
 };
 
 class FormatTokenLexer {
@@ -1549,10 +686,28 @@ public:
               SourceMgr.getSpellingColumnNumber(FirstTok->Tok.getLocation()) -
               1;
         }
-        UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine, Indent,
-                                         TheLine.First, Whitespaces, Encoding,
-                                         BinPackInconclusiveFunctions);
-        Formatter.format(I + 1 != E ? &*(I + 1) : NULL);
+        ContinuationIndenter Indenter(Style, SourceMgr, TheLine, Indent,
+                                      Whitespaces, Encoding,
+                                      BinPackInconclusiveFunctions);
+
+        // If everything fits on a single line, just put it there.
+        unsigned ColumnLimit = Style.ColumnLimit;
+        if ((I + 1) != E && (I + 1)->InPPDirective &&
+            !(I + 1)->First->HasUnescapedNewline)
+          ColumnLimit = Indenter.getColumnLimit();
+
+        if (I->Last->TotalLength + Indent <= ColumnLimit) {
+          LineState State = Indenter.getInitialState();
+          while (State.NextToken != NULL)
+            Indenter.addTokenToState(State, false, false);
+        } else if (Style.ColumnLimit == 0) {
+          NoColumnLimitFormatter Formatter(&Indenter);
+          Formatter.format();
+        } else {
+          UnwrappedLineFormatter Formatter(&Indenter, Style, TheLine);
+          Formatter.format();
+        }
+
         IndentForLevel[TheLine.Level] = LevelIndent;
         PreviousLineWasTouched = true;
       } else {





More information about the cfe-commits mailing list