<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">This patch causes this failure on a VS buildbot machine.<div><br></div><div><pre style="font-family: 'Courier New', courier, monotype, monospace; "><span class="stdout">style-on-command-line.cpp</span></pre><div>- Fariborz</div><div><br></div><div><div>On Nov 5, 2013, at 11:10 AM, Daniel Jasper <<a href="mailto:djasper@google.com">djasper@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Author: djasper<br>Date: Tue Nov  5 13:10:03 2013<br>New Revision: 194090<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194090&view=rev">http://llvm.org/viewvc/llvm-project?rev=194090&view=rev</a><br>Log:<br>clang-format: Allow line merging and partial formatting of nested blocks<br><br>Before, clang-format would always format entire nested blocks, which<br>can be unwanted e.g. for long DEBUG({...}) statements. Also<br>clang-format would not allow to merge lines in nested blocks (e.g. to<br>put "if (a) return;" on one line in Google style).<br><br>This is the first step of several refactorings mostly focussing on the<br>additional functionality (by reusing the "format many lines" code to<br>format the children of a nested block). The next steps are:<br>* Pull out the line merging into its own class.<br>* Seperate the formatting of many lines from the formatting of a single<br>  line (and the analysis of the solution space).<br><br>Modified:<br>    cfe/trunk/lib/Format/Format.cpp<br>    cfe/trunk/lib/Format/TokenAnnotator.cpp<br>    cfe/trunk/unittests/Format/FormatTest.cpp<br><br>Modified: cfe/trunk/lib/Format/Format.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=194090&r1=194089&r2=194090&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=194090&r1=194089&r2=194090&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/Format/Format.cpp (original)<br>+++ cfe/trunk/lib/Format/Format.cpp Tue Nov  5 13:10:03 2013<br>@@ -372,28 +372,148 @@ private:<br><br> class UnwrappedLineFormatter {<br> public:<br>-  UnwrappedLineFormatter(ContinuationIndenter *Indenter,<br>+  UnwrappedLineFormatter(SourceManager &SourceMgr,<br>+                         SmallVectorImpl<CharSourceRange> &Ranges,<br>+                         ContinuationIndenter *Indenter,<br>                          WhitespaceManager *Whitespaces,<br>-                         const FormatStyle &Style, const AnnotatedLine &Line)<br>-      : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), Line(Line),<br>-        Count(0) {}<br>+                         const FormatStyle &Style)<br>+      : SourceMgr(SourceMgr), Ranges(Ranges), Indenter(Indenter),<br>+        Whitespaces(Whitespaces), Style(Style) {}<br>+<br>+  unsigned format(SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,<br>+                  int AdditionalIndent = 0) {<br>+    assert(!Lines.empty());<br>+    unsigned Penalty = 0;<br>+    std::vector<int> IndentForLevel;<br>+    for (unsigned i = 0, e = Lines[0]->Level; i != e; ++i)<br>+      IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent);<br>+    bool PreviousLineWasTouched = false;<br>+    const AnnotatedLine *PreviousLine = NULL;<br>+    bool FormatPPDirective = false;<br>+    for (SmallVectorImpl<AnnotatedLine *>::iterator I = Lines.begin(),<br>+                                                    E = Lines.end();<br>+         I != E; ++I) {<br>+      const AnnotatedLine &TheLine = **I;<br>+      const FormatToken *FirstTok = TheLine.First;<br>+      int Offset = getIndentOffset(*FirstTok);<br>+<br>+      // Check whether this line is part of a formatted preprocessor directive.<br>+      if (FirstTok->HasUnescapedNewline)<br>+        FormatPPDirective = false;<br>+      if (!FormatPPDirective && TheLine.InPPDirective &&<br>+          (touchesLine(TheLine) || touchesPPDirective(I + 1, E)))<br>+        FormatPPDirective = true;<br>+<br>+      // Determine indent and try to merge multiple unwrapped lines.<br>+      while (IndentForLevel.size() <= TheLine.Level)<br>+        IndentForLevel.push_back(-1);<br>+      IndentForLevel.resize(TheLine.Level + 1);<br>+      unsigned Indent = getIndent(IndentForLevel, TheLine.Level);<br>+      if (static_cast<int>(Indent) + Offset >= 0)<br>+        Indent += Offset;<br>+      if (!DryRun)<br>+        tryFitMultipleLinesInOne(Indent, I, E);<br>+<br>+      bool WasMoved = PreviousLineWasTouched && FirstTok->NewlinesBefore == 0;<br>+      if (TheLine.First->is(tok::eof)) {<br>+        if (PreviousLineWasTouched && !DryRun) {<br>+          unsigned Newlines = std::min(FirstTok->NewlinesBefore, 1u);<br>+          Whitespaces->replaceWhitespace(*TheLine.First, Newlines,<br>+                                         /*IndentLevel=*/0, /*Spaces=*/0,<br>+                                         /*TargetColumn=*/0);<br>+        }<br>+      } else if (TheLine.Type != LT_Invalid &&<br>+                 (WasMoved || FormatPPDirective || touchesLine(TheLine))) {<br>+        unsigned LevelIndent =<br>+            getIndent(IndentForLevel, TheLine.Level);<br>+        if (FirstTok->WhitespaceRange.isValid()) {<br>+          if (!DryRun)<br>+            formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level,<br>+                             Indent, TheLine.InPPDirective);<br>+        } else {<br>+          Indent = LevelIndent = FirstTok->OriginalColumn;<br>+        }<br>+<br>+        // If everything fits on a single line, just put it there.<br>+        unsigned ColumnLimit = Style.ColumnLimit;<br>+        if (I + 1 != E) {<br>+          AnnotatedLine *NextLine = *(I + 1);<br>+          if (NextLine->InPPDirective && !NextLine->First->HasUnescapedNewline)<br>+            ColumnLimit = getColumnLimit(TheLine.InPPDirective);<br>+        }<br>+<br>+        if (TheLine.Last->TotalLength + Indent <= ColumnLimit) {<br>+          LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun);<br>+          while (State.NextToken != NULL)<br>+            Indenter->addTokenToState(State, /*Newline=*/false, DryRun);<br>+        } else if (Style.ColumnLimit == 0) {<br>+          NoColumnLimitFormatter Formatter(Indenter);<br>+          if (!DryRun)<br>+            Formatter.format(Indent, &TheLine);<br>+        } else {<br>+          Penalty += format(TheLine, Indent, DryRun);<br>+        }<br>+<br>+        IndentForLevel[TheLine.Level] = LevelIndent;<br>+        PreviousLineWasTouched = true;<br>+      } else {<br>+        // Format the first token if necessary, and notify the WhitespaceManager<br>+        // about the unchanged whitespace.<br>+        for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {<br>+          if (Tok == TheLine.First &&<br>+              (Tok->NewlinesBefore > 0 || Tok->IsFirst)) {<br>+            unsigned LevelIndent = Tok->OriginalColumn;<br>+            if (!DryRun) {<br>+              // Remove trailing whitespace of the previous line if it was<br>+              // touched.<br>+              if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) {<br>+                formatFirstToken(*Tok, PreviousLine, TheLine.Level, LevelIndent,<br>+                                 TheLine.InPPDirective);<br>+              } else {<br>+                Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);<br>+              }<br>+            }<br>+<br>+            if (static_cast<int>(LevelIndent) - Offset >= 0)<br>+              LevelIndent -= Offset;<br>+            if (Tok->isNot(tok::comment))<br>+              IndentForLevel[TheLine.Level] = LevelIndent;<br>+          } else if (!DryRun) {<br>+            Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);<br>+          }<br>+        }<br>+        // If we did not reformat this unwrapped line, the column at the end of<br>+        // the last token is unchanged - thus, we can calculate the end of the<br>+        // last token.<br>+        PreviousLineWasTouched = false;<br>+      }<br>+      if (!DryRun) {<br>+        for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {<br>+          Tok->Finalized = true;<br>+        }<br>+      }<br>+      PreviousLine = *I;<br>+    }<br>+    return Penalty;<br>+  }<br><br>-  /// \brief Formats an \c UnwrappedLine and returns the penalty.<br>+private:<br>+  /// \brief Formats an \c AnnotatedLine and returns the penalty.<br>   ///<br>   /// If \p DryRun is \c false, directly applies the changes.<br>-  unsigned format(unsigned FirstIndent, bool DryRun = false) {<br>+  unsigned format(const AnnotatedLine &Line, unsigned FirstIndent,<br>+                  bool DryRun) {<br>     LineState State = Indenter->getInitialState(FirstIndent, &Line, DryRun);<br><br>     // If the ObjC method declaration does not fit on a line, we should format<br>     // it with one arg per line.<br>-    if (Line.Type == LT_ObjCMethodDecl)<br>+    if (State.Line->Type == LT_ObjCMethodDecl)<br>       State.Stack.back().BreakBeforeParameter = true;<br><br>     // Find best solution in solution space.<br>     return analyzeSolutionSpace(State, DryRun);<br>   }<br><br>-private:<br>   /// \brief An edge in the solution space from \c Previous->State to \c State,<br>   /// inserting a newline dependent on the \c NewLine.<br>   struct StateNode {<br>@@ -419,6 +539,262 @@ private:<br>   typedef std::priority_queue<QueueItem, std::vector<QueueItem>,<br>                               std::greater<QueueItem> > QueueType;<br><br>+  /// \brief Get the offset of the line relatively to the level.<br>+  ///<br>+  /// For example, 'public:' labels in classes are offset by 1 or 2<br>+  /// characters to the left from their level.<br>+  int getIndentOffset(const FormatToken &RootToken) {<br>+    if (RootToken.isAccessSpecifier(false) || RootToken.isObjCAccessSpecifier())<br>+      return Style.AccessModifierOffset;<br>+    return 0;<br>+  }<br>+<br>+  /// \brief Add a new line and the required indent before the first Token<br>+  /// of the \c UnwrappedLine if there was no structural parsing error.<br>+  void formatFirstToken(FormatToken &RootToken,<br>+                        const AnnotatedLine *PreviousLine, unsigned IndentLevel,<br>+                        unsigned Indent, bool InPPDirective) {<br>+    unsigned Newlines =<br>+        std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);<br>+    // Remove empty lines before "}" where applicable.<br>+    if (<a href="http://RootToken.is">RootToken.is</a>(tok::r_brace) &&<br>+        (!RootToken.Next ||<br>+         (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)))<br>+      Newlines = std::min(Newlines, 1u);<br>+    if (Newlines == 0 && !RootToken.IsFirst)<br>+      Newlines = 1;<br>+<br>+    // Insert extra new line before access specifiers.<br>+    if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) &&<br>+        RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1)<br>+      ++Newlines;<br>+<br>+    // Remove empty lines after access specifiers.<br>+    if (PreviousLine && PreviousLine->First->isAccessSpecifier())<br>+      Newlines = std::min(1u, Newlines);<br>+<br>+    Whitespaces->replaceWhitespace(<br>+        RootToken, Newlines, IndentLevel, Indent, Indent,<br>+        InPPDirective && !RootToken.HasUnescapedNewline);<br>+  }<br>+<br>+  /// \brief Get the indent of \p Level from \p IndentForLevel.<br>+  ///<br>+  /// \p IndentForLevel must contain the indent for the level \c l<br>+  /// at \p IndentForLevel[l], or a value < 0 if the indent for<br>+  /// that level is unknown.<br>+  unsigned getIndent(const std::vector<int> IndentForLevel, unsigned Level) {<br>+    if (IndentForLevel[Level] != -1)<br>+      return IndentForLevel[Level];<br>+    if (Level == 0)<br>+      return 0;<br>+    return getIndent(IndentForLevel, Level - 1) + Style.IndentWidth;<br>+  }<br>+<br>+  /// \brief Tries to merge lines into one.<br>+  ///<br>+  /// This will change \c Line and \c AnnotatedLine to contain the merged line,<br>+  /// if possible; note that \c I will be incremented when lines are merged.<br>+  void tryFitMultipleLinesInOne(unsigned Indent,<br>+                                SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>+                                SmallVectorImpl<AnnotatedLine *>::iterator E) {<br>+    // We can never merge stuff if there are trailing line comments.<br>+    AnnotatedLine *TheLine = *I;<br>+    if (TheLine->Last->Type == TT_LineComment)<br>+      return;<br>+<br>+    if (Indent > Style.ColumnLimit)<br>+      return;<br>+<br>+    unsigned Limit = Style.ColumnLimit - Indent;<br>+    // If we already exceed the column limit, we set 'Limit' to 0. The different<br>+    // tryMerge..() functions can then decide whether to still do merging.<br>+    Limit = TheLine->Last->TotalLength > Limit<br>+                ? 0<br>+                : Limit - TheLine->Last->TotalLength;<br>+<br>+    if (I + 1 == E || (*(I + 1))->Type == LT_Invalid)<br>+      return;<br>+<br>+    if (TheLine->Last->is(tok::l_brace)) {<br>+      tryMergeSimpleBlock(I, E, Limit);<br>+    } else if (Style.AllowShortIfStatementsOnASingleLine &&<br>+               TheLine->First->is(tok::kw_if)) {<br>+      tryMergeSimpleControlStatement(I, E, Limit);<br>+    } else if (Style.AllowShortLoopsOnASingleLine &&<br>+               TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {<br>+      tryMergeSimpleControlStatement(I, E, Limit);<br>+    } else if (TheLine->InPPDirective && (TheLine->First->HasUnescapedNewline ||<br>+                                          TheLine->First->IsFirst)) {<br>+      tryMergeSimplePPDirective(I, E, Limit);<br>+    }<br>+  }<br>+<br>+  void tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>+                                 SmallVectorImpl<AnnotatedLine *>::iterator E,<br>+                                 unsigned Limit) {<br>+    if (Limit == 0)<br>+      return;<br>+    AnnotatedLine &Line = **I;<br>+    if (!(*(I + 1))->InPPDirective || (*(I + 1))->First->HasUnescapedNewline)<br>+      return;<br>+    if (I + 2 != E && (*(I + 2))->InPPDirective &&<br>+        !(*(I + 2))->First->HasUnescapedNewline)<br>+      return;<br>+    if (1 + (*(I + 1))->Last->TotalLength > Limit)<br>+      return;<br>+    join(Line, **(++I));<br>+  }<br>+<br>+  void<br>+  tryMergeSimpleControlStatement(SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>+                                 SmallVectorImpl<AnnotatedLine *>::iterator E,<br>+                                 unsigned Limit) {<br>+    if (Limit == 0)<br>+      return;<br>+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman &&<br>+        (*(I + 1))->First->is(tok::l_brace))<br>+      return;<br>+    if ((*(I + 1))->InPPDirective != (*I)->InPPDirective ||<br>+        ((*(I + 1))->InPPDirective && (*(I + 1))->First->HasUnescapedNewline))<br>+      return;<br>+    AnnotatedLine &Line = **I;<br>+    if (Line.Last->isNot(tok::r_paren))<br>+      return;<br>+    if (1 + (*(I + 1))->Last->TotalLength > Limit)<br>+      return;<br>+    if ((*(I + 1))->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,<br>+                                   tok::kw_while) ||<br>+        (*(I + 1))->First->Type == TT_LineComment)<br>+      return;<br>+    // Only inline simple if's (no nested if or else).<br>+    if (I + 2 != E && Line.First->is(tok::kw_if) &&<br>+        (*(I + 2))->First->is(tok::kw_else))<br>+      return;<br>+    join(Line, **(++I));<br>+  }<br>+<br>+  void tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>+                           SmallVectorImpl<AnnotatedLine *>::iterator E,<br>+                           unsigned Limit) {<br>+    // No merging if the brace already is on the next line.<br>+    if (Style.BreakBeforeBraces != FormatStyle::BS_Attach)<br>+      return;<br>+<br>+    // First, check that the current line allows merging. This is the case if<br>+    // we're not in a control flow statement and the last token is an opening<br>+    // brace.<br>+    AnnotatedLine &Line = **I;<br>+    if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,<br>+                            tok::kw_else, tok::kw_try, tok::kw_catch,<br>+                            tok::kw_for,<br>+                            // This gets rid of all ObjC @ keywords and methods.<br>+                            tok::at, tok::minus, tok::plus))<br>+      return;<br>+<br>+    FormatToken *Tok = (*(I + 1))->First;<br>+    if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&<br>+        (Tok->getNextNonComment() == NULL ||<br>+         Tok->getNextNonComment()->is(tok::semi))) {<br>+      // We merge empty blocks even if the line exceeds the column limit.<br>+      Tok->SpacesRequiredBefore = 0;<br>+      Tok->CanBreakBefore = true;<br>+      join(Line, **(I + 1));<br>+      I += 1;<br>+    } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) {<br>+      // Check that we still have three lines and they fit into the limit.<br>+      if (I + 2 == E || (*(I + 2))->Type == LT_Invalid ||<br>+          !nextTwoLinesFitInto(I, Limit))<br>+        return;<br>+<br>+      // Second, check that the next line does not contain any braces - if it<br>+      // does, readability declines when putting it into a single line.<br>+      if ((*(I + 1))->Last->Type == TT_LineComment || Tok->MustBreakBefore)<br>+        return;<br>+      do {<br>+        if (Tok->isOneOf(tok::l_brace, tok::r_brace))<br>+          return;<br>+        Tok = Tok->Next;<br>+      } while (Tok != NULL);<br>+<br>+      // Last, check that the third line contains a single closing brace.<br>+      Tok = (*(I + 2))->First;<br>+      if (Tok->getNextNonComment() != NULL || Tok->isNot(tok::r_brace) ||<br>+          Tok->MustBreakBefore)<br>+        return;<br>+<br>+      join(Line, **(I + 1));<br>+      join(Line, **(I + 2));<br>+      I += 2;<br>+    }<br>+  }<br>+<br>+  bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::iterator I,<br>+                           unsigned Limit) {<br>+    return 1 + (*(I + 1))->Last->TotalLength + 1 +<br>+               (*(I + 2))->Last->TotalLength <=<br>+           Limit;<br>+  }<br>+<br>+  void join(AnnotatedLine &A, const AnnotatedLine &B) {<br>+    assert(!A.Last->Next);<br>+    assert(!B.First->Previous);<br>+    A.Last->Next = B.First;<br>+    B.First->Previous = A.Last;<br>+    unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;<br>+    for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {<br>+      Tok->TotalLength += LengthA;<br>+      A.Last = Tok;<br>+    }<br>+  }<br>+<br>+  unsigned getColumnLimit(bool InPPDirective) const {<br>+    // In preprocessor directives reserve two chars for trailing " \"<br>+    return Style.ColumnLimit - (InPPDirective ? 2 : 0);<br>+  }<br>+<br>+  bool touchesRanges(const CharSourceRange &Range) {<br>+    for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),<br>+                                                          E = Ranges.end();<br>+         I != E; ++I) {<br>+      if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) &&<br>+          !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin()))<br>+        return true;<br>+    }<br>+    return false;<br>+  }<br>+<br>+  bool touchesLine(const AnnotatedLine &TheLine) {<br>+    const FormatToken *First = TheLine.First;<br>+    const FormatToken *Last = TheLine.Last;<br>+    CharSourceRange LineRange = CharSourceRange::getCharRange(<br>+        First->WhitespaceRange.getBegin().getLocWithOffset(<br>+            First->LastNewlineOffset),<br>+        Last->getStartOfNonWhitespace().getLocWithOffset(<br>+            Last->TokenText.size() - 1));<br>+    return touchesRanges(LineRange);<br>+  }<br>+<br>+  bool touchesPPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>+                          SmallVectorImpl<AnnotatedLine *>::const_iterator E) {<br>+    for (; I != E; ++I) {<br>+      if ((*I)->First->HasUnescapedNewline)<br>+        return false;<br>+      if (touchesLine(**I))<br>+        return true;<br>+    }<br>+    return false;<br>+  }<br>+<br>+  bool touchesEmptyLineBefore(const AnnotatedLine &TheLine) {<br>+    const FormatToken *First = TheLine.First;<br>+    CharSourceRange LineRange = CharSourceRange::getCharRange(<br>+        First->WhitespaceRange.getBegin(),<br>+        First->WhitespaceRange.getBegin().getLocWithOffset(<br>+            First->LastNewlineOffset));<br>+    return touchesRanges(LineRange);<br>+  }<br>+<br>   /// \brief Analyze the entire solution space starting from \p InitialState.<br>   ///<br>   /// This implements a variant of Dijkstra's algorithm on the graph that spans<br>@@ -430,6 +806,11 @@ private:<br>   unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun = false) {<br>     std::set<LineState> Seen;<br><br>+    // Increasing count of \c StateNode items we have created. This is used to<br>+    // create a deterministic order independent of the container.<br>+    unsigned Count = 0;<br>+    QueueType Queue;<br>+<br>     // Insert start element into queue.<br>     StateNode *Node =<br>         new (Allocator.Allocate()) StateNode(InitialState, false, NULL);<br>@@ -459,9 +840,9 @@ private:<br><br>       FormatDecision LastFormat = Node->State.NextToken->Decision;<br>       if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)<br>-        addNextStateToQueue(Penalty, Node, /*NewLine=*/false);<br>+        addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);<br>       if (LastFormat == FD_Unformatted || LastFormat == FD_Break)<br>-        addNextStateToQueue(Penalty, Node, /*NewLine=*/true);<br>+        addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);<br>     }<br><br>     if (Queue.empty()) {<br>@@ -509,7 +890,7 @@ private:<br>   /// Assume the current state is \p PreviousNode and has been reached with a<br>   /// penalty of \p Penalty. Insert a line break if \p NewLine is \c true.<br>   void addNextStateToQueue(unsigned Penalty, StateNode *PreviousNode,<br>-                           bool NewLine) {<br>+                           bool NewLine, unsigned *Count, QueueType *Queue) {<br>     if (NewLine && !Indenter->canBreak(PreviousNode->State))<br>       return;<br>     if (!NewLine && Indenter->mustBreak(PreviousNode->State))<br>@@ -522,8 +903,8 @@ private:<br><br>     Penalty += Indenter->addTokenToState(Node->State, NewLine, true);<br><br>-    Queue.push(QueueItem(OrderedPenalty(Penalty, Count), Node));<br>-    ++Count;<br>+    Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));<br>+    ++(*Count);<br>   }<br><br>   /// \brief If the \p State's next token is an r_brace closing a nested block,<br>@@ -548,7 +929,7 @@ private:<br>   /// break or don't break.<br>   bool formatChildren(LineState &State, bool NewLine, bool DryRun,<br>                       unsigned &Penalty) {<br>-    const FormatToken &Previous = *State.NextToken->Previous;<br>+    FormatToken &Previous = *State.NextToken->Previous;<br>     const FormatToken *LBrace = State.NextToken->getPreviousNonComment();<br>     if (!LBrace || LBrace->isNot(tok::l_brace) ||<br>         LBrace->BlockKind != BK_Block || Previous.Children.size() == 0)<br>@@ -557,29 +938,15 @@ private:<br>       return true;<br><br>     if (NewLine) {<br>-      unsigned ParentIndent = State.Stack.back().Indent;<br>-      for (SmallVector<AnnotatedLine *, 1>::const_iterator<br>-               I = Previous.Children.begin(),<br>-               E = Previous.Children.end();<br>-           I != E; ++I) {<br>-        unsigned Indent =<br>-            ParentIndent + ((*I)->Level - Line.Level - 1) * Style.IndentWidth;<br>-        if (!DryRun) {<br>-          unsigned Newlines = std::min((*I)->First->NewlinesBefore,<br>-                                       Style.MaxEmptyLinesToKeep + 1);<br>-          Newlines = std::max(1u, Newlines);<br>-          Whitespaces->replaceWhitespace(<br>-              *(*I)->First, Newlines, (*I)->Level, /*Spaces=*/Indent,<br>-              /*StartOfTokenColumn=*/Indent, Line.InPPDirective);<br>-        }<br>-        UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style, **I);<br>-        Penalty += Formatter.format(Indent, DryRun);<br>-      }<br>+      int AdditionalIndent = State.Stack.back().Indent -<br>+                             Previous.Children[0]->Level * Style.IndentWidth;<br>+      Penalty += format(Previous.Children, DryRun, AdditionalIndent);<br>       return true;<br>     }<br><br>+    // Cannot merge multiple statements into a single line.<br>     if (Previous.Children.size() > 1)<br>-      return false; // Cannot merge multiple statements into a single line.<br>+      return false; <br><br>     // We can't put the closing "}" on a line with a trailing comment.<br>     if (Previous.Children[0]->Last->isTrailingComment())<br>@@ -590,25 +957,20 @@ private:<br>           *Previous.Children[0]->First,<br>           /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1,<br>           /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);<br>-      UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style,<br>-                                       *Previous.Children[0]);<br>-      Penalty += Formatter.format(State.Column + 1, DryRun);<br>     }<br>+    Penalty += format(*Previous.Children[0], State.Column + 1, DryRun);<br><br>     State.Column += 1 + Previous.Children[0]->Last->TotalLength;<br>     return true;<br>   }<br><br>+  SourceManager &SourceMgr;<br>+  SmallVectorImpl<CharSourceRange> &Ranges;<br>   ContinuationIndenter *Indenter;<br>   WhitespaceManager *Whitespaces;<br>   FormatStyle Style;<br>-  const AnnotatedLine &Line;<br><br>   llvm::SpecificBumpPtrAllocator<StateNode> Allocator;<br>-  QueueType Queue;<br>-  // Increasing count of \c StateNode items we have created. This is used<br>-  // to create a deterministic order independent of the container.<br>-  unsigned Count;<br> };<br><br> class FormatTokenLexer {<br>@@ -831,7 +1193,7 @@ public:<br>             const std::vector<CharSourceRange> &Ranges)<br>       : Style(Style), Lex(Lex), SourceMgr(SourceMgr),<br>         Whitespaces(SourceMgr, Style, inputUsesCRLF(Lex.getBuffer())),<br>-        Ranges(Ranges), UnwrappedLines(1),<br>+        Ranges(Ranges.begin(), Ranges.end()), UnwrappedLines(1),<br>         Encoding(encoding::detectEncoding(Lex.getBuffer())) {<br>     DEBUG(llvm::dbgs() << "File encoding: "<br>                        << (Encoding == encoding::Encoding_UTF8 ? "UTF8"<br>@@ -875,120 +1237,20 @@ public:<br>   tooling::Replacements format(SmallVectorImpl<AnnotatedLine *> &AnnotatedLines,<br>                                bool StructuralError, FormatTokenLexer &Tokens) {<br>     TokenAnnotator Annotator(Style, Tokens.getIdentTable().get("in"));<br>-    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>-      Annotator.annotate(*AnnotatedLines[i]);<br>-    }<br>-    deriveLocalStyle(AnnotatedLines);<br>-    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>-      Annotator.calculateFormattingInformation(*AnnotatedLines[i]);<br>-    }<br>-<br>-    Annotator.setCommentLineLevels(AnnotatedLines);<br>-<br>-    std::vector<int> IndentForLevel;<br>-    bool PreviousLineWasTouched = false;<br>-    const AnnotatedLine *PreviousLine = NULL;<br>-    bool FormatPPDirective = false;<br>-    for (SmallVectorImpl<AnnotatedLine *>::iterator I = AnnotatedLines.begin(),<br>-                                                    E = AnnotatedLines.end();<br>-         I != E; ++I) {<br>-      const AnnotatedLine &TheLine = **I;<br>-      const FormatToken *FirstTok = TheLine.First;<br>-      int Offset = getIndentOffset(*TheLine.First);<br>-<br>-      // Check whether this line is part of a formatted preprocessor directive.<br>-      if (FirstTok->HasUnescapedNewline)<br>-        FormatPPDirective = false;<br>-      if (!FormatPPDirective && TheLine.InPPDirective &&<br>-          (touchesLine(TheLine) || touchesPPDirective(I + 1, E)))<br>-        FormatPPDirective = true;<br>-<br>-      // Determine indent and try to merge multiple unwrapped lines.<br>-      while (IndentForLevel.size() <= TheLine.Level)<br>-        IndentForLevel.push_back(-1);<br>-      IndentForLevel.resize(TheLine.Level + 1);<br>-      unsigned Indent = getIndent(IndentForLevel, TheLine.Level);<br>-      if (static_cast<int>(Indent) + Offset >= 0)<br>-        Indent += Offset;<br>-      tryFitMultipleLinesInOne(Indent, I, E);<br>-<br>-      bool WasMoved = PreviousLineWasTouched && FirstTok->NewlinesBefore == 0;<br>-      if (TheLine.First->is(tok::eof)) {<br>-        if (PreviousLineWasTouched) {<br>-          unsigned Newlines = std::min(FirstTok->NewlinesBefore, 1u);<br>-          Whitespaces.replaceWhitespace(*TheLine.First, Newlines,<br>-                                        /*IndentLevel=*/0, /*Spaces=*/0,<br>-                                        /*TargetColumn=*/0);<br>-        }<br>-      } else if (TheLine.Type != LT_Invalid &&<br>-                 (WasMoved || FormatPPDirective || touchesLine(TheLine))) {<br>-        unsigned LevelIndent = getIndent(IndentForLevel, TheLine.Level);<br>-        if (FirstTok->WhitespaceRange.isValid()) {<br>-          formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, Indent,<br>-                           TheLine.InPPDirective);<br>-        } else {<br>-          Indent = LevelIndent = FirstTok->OriginalColumn;<br>-        }<br>-        ContinuationIndenter Indenter(Style, SourceMgr, Whitespaces, Encoding,<br>-                                      BinPackInconclusiveFunctions);<br>-<br>-        // If everything fits on a single line, just put it there.<br>-        unsigned ColumnLimit = Style.ColumnLimit;<br>-        AnnotatedLine *NextLine = *(I + 1);<br>-        if ((I + 1) != E && NextLine->InPPDirective &&<br>-            !NextLine->First->HasUnescapedNewline)<br>-          ColumnLimit = getColumnLimit(TheLine.InPPDirective);<br>-<br>-        if (TheLine.Last->TotalLength + Indent <= ColumnLimit) {<br>-          LineState State =<br>-              Indenter.getInitialState(Indent, &TheLine, /*DryRun=*/false);<br>-          while (State.NextToken != NULL)<br>-            Indenter.addTokenToState(State, false, false);<br>-        } else if (Style.ColumnLimit == 0) {<br>-          NoColumnLimitFormatter Formatter(&Indenter);<br>-          Formatter.format(Indent, &TheLine);<br>-        } else {<br>-          UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style,<br>-                                           TheLine);<br>-          Formatter.format(Indent);<br>-        }<br>-<br>-        IndentForLevel[TheLine.Level] = LevelIndent;<br>-        PreviousLineWasTouched = true;<br>-      } else {<br>-        // Format the first token if necessary, and notify the WhitespaceManager<br>-        // about the unchanged whitespace.<br>-        for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {<br>-          if (Tok == TheLine.First &&<br>-              (Tok->NewlinesBefore > 0 || Tok->IsFirst)) {<br>-            unsigned LevelIndent = Tok->OriginalColumn;<br>-            // Remove trailing whitespace of the previous line if it was<br>-            // touched.<br>-            if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) {<br>-              formatFirstToken(*Tok, PreviousLine, TheLine.Level, LevelIndent,<br>-                               TheLine.InPPDirective);<br>-            } else {<br>-              Whitespaces.addUntouchableToken(*Tok, TheLine.InPPDirective);<br>-            }<br>-<br>-            if (static_cast<int>(LevelIndent) - Offset >= 0)<br>-              LevelIndent -= Offset;<br>-            if (Tok->isNot(tok::comment))<br>-              IndentForLevel[TheLine.Level] = LevelIndent;<br>-          } else {<br>-            Whitespaces.addUntouchableToken(*Tok, TheLine.InPPDirective);<br>-          }<br>-        }<br>-        // If we did not reformat this unwrapped line, the column at the end of<br>-        // the last token is unchanged - thus, we can calculate the end of the<br>-        // last token.<br>-        PreviousLineWasTouched = false;<br>-      }<br>-      for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {<br>-        Tok->Finalized = true;<br>-      }<br>-      PreviousLine = *I;<br>+    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>+      Annotator.annotate(*AnnotatedLines[i]);<br>+    }<br>+    deriveLocalStyle(AnnotatedLines);<br>+    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>+      Annotator.calculateFormattingInformation(*AnnotatedLines[i]);<br>     }<br>+<br>+    Annotator.setCommentLineLevels(AnnotatedLines);<br>+    ContinuationIndenter Indenter(Style, SourceMgr, Whitespaces, Encoding,<br>+                                  BinPackInconclusiveFunctions);<br>+    UnwrappedLineFormatter Formatter(SourceMgr, Ranges, &Indenter, &Whitespaces,<br>+                                     Style);<br>+    Formatter.format(AnnotatedLines, /*DryRun=*/false);<br>     return Whitespaces.generateReplacements();<br>   }<br><br>@@ -1051,228 +1313,6 @@ private:<br>         HasBinPackedFunction || !HasOnePerLineFunction;<br>   }<br><br>-  /// \brief Get the indent of \p Level from \p IndentForLevel.<br>-  ///<br>-  /// \p IndentForLevel must contain the indent for the level \c l<br>-  /// at \p IndentForLevel[l], or a value < 0 if the indent for<br>-  /// that level is unknown.<br>-  unsigned getIndent(const std::vector<int> IndentForLevel, unsigned Level) {<br>-    if (IndentForLevel[Level] != -1)<br>-      return IndentForLevel[Level];<br>-    if (Level == 0)<br>-      return 0;<br>-    return getIndent(IndentForLevel, Level - 1) + Style.IndentWidth;<br>-  }<br>-<br>-  /// \brief Get the offset of the line relatively to the level.<br>-  ///<br>-  /// For example, 'public:' labels in classes are offset by 1 or 2<br>-  /// characters to the left from their level.<br>-  int getIndentOffset(const FormatToken &RootToken) {<br>-    if (RootToken.isAccessSpecifier(false) || RootToken.isObjCAccessSpecifier())<br>-      return Style.AccessModifierOffset;<br>-    return 0;<br>-  }<br>-<br>-  /// \brief Tries to merge lines into one.<br>-  ///<br>-  /// This will change \c Line and \c AnnotatedLine to contain the merged line,<br>-  /// if possible; note that \c I will be incremented when lines are merged.<br>-  void tryFitMultipleLinesInOne(unsigned Indent,<br>-                                SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>-                                SmallVectorImpl<AnnotatedLine *>::iterator E) {<br>-    // We can never merge stuff if there are trailing line comments.<br>-    AnnotatedLine *TheLine = *I;<br>-    if (TheLine->Last->Type == TT_LineComment)<br>-      return;<br>-<br>-    if (Indent > Style.ColumnLimit)<br>-      return;<br>-<br>-    unsigned Limit = Style.ColumnLimit - Indent;<br>-    // If we already exceed the column limit, we set 'Limit' to 0. The different<br>-    // tryMerge..() functions can then decide whether to still do merging.<br>-    Limit = TheLine->Last->TotalLength > Limit<br>-                ? 0<br>-                : Limit - TheLine->Last->TotalLength;<br>-<br>-    if (I + 1 == E || (*(I + 1))->Type == LT_Invalid)<br>-      return;<br>-<br>-    if (TheLine->Last->is(tok::l_brace)) {<br>-      tryMergeSimpleBlock(I, E, Limit);<br>-    } else if (Style.AllowShortIfStatementsOnASingleLine &&<br>-               TheLine->First->is(tok::kw_if)) {<br>-      tryMergeSimpleControlStatement(I, E, Limit);<br>-    } else if (Style.AllowShortLoopsOnASingleLine &&<br>-               TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {<br>-      tryMergeSimpleControlStatement(I, E, Limit);<br>-    } else if (TheLine->InPPDirective && (TheLine->First->HasUnescapedNewline ||<br>-                                          TheLine->First->IsFirst)) {<br>-      tryMergeSimplePPDirective(I, E, Limit);<br>-    }<br>-  }<br>-<br>-  void tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>-                                 SmallVectorImpl<AnnotatedLine *>::iterator E,<br>-                                 unsigned Limit) {<br>-    if (Limit == 0)<br>-      return;<br>-    AnnotatedLine &Line = **I;<br>-    if (!(*(I + 1))->InPPDirective || (*(I + 1))->First->HasUnescapedNewline)<br>-      return;<br>-    if (I + 2 != E && (*(I + 2))->InPPDirective &&<br>-        !(*(I + 2))->First->HasUnescapedNewline)<br>-      return;<br>-    if (1 + (*(I + 1))->Last->TotalLength > Limit)<br>-      return;<br>-    join(Line, **(++I));<br>-  }<br>-<br>-  void<br>-  tryMergeSimpleControlStatement(SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>-                                 SmallVectorImpl<AnnotatedLine *>::iterator E,<br>-                                 unsigned Limit) {<br>-    if (Limit == 0)<br>-      return;<br>-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman &&<br>-        (*(I + 1))->First->is(tok::l_brace))<br>-      return;<br>-    if ((*(I + 1))->InPPDirective != (*I)->InPPDirective ||<br>-        ((*(I + 1))->InPPDirective && (*(I + 1))->First->HasUnescapedNewline))<br>-      return;<br>-    AnnotatedLine &Line = **I;<br>-    if (Line.Last->isNot(tok::r_paren))<br>-      return;<br>-    if (1 + (*(I + 1))->Last->TotalLength > Limit)<br>-      return;<br>-    if ((*(I + 1))->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,<br>-                                   tok::kw_while) ||<br>-        (*(I + 1))->First->Type == TT_LineComment)<br>-      return;<br>-    // Only inline simple if's (no nested if or else).<br>-    if (I + 2 != E && Line.First->is(tok::kw_if) &&<br>-        (*(I + 2))->First->is(tok::kw_else))<br>-      return;<br>-    join(Line, **(++I));<br>-  }<br>-<br>-  void tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::iterator &I,<br>-                           SmallVectorImpl<AnnotatedLine *>::iterator E,<br>-                           unsigned Limit) {<br>-    // No merging if the brace already is on the next line.<br>-    if (Style.BreakBeforeBraces != FormatStyle::BS_Attach)<br>-      return;<br>-<br>-    // First, check that the current line allows merging. This is the case if<br>-    // we're not in a control flow statement and the last token is an opening<br>-    // brace.<br>-    AnnotatedLine &Line = **I;<br>-    if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,<br>-                            tok::kw_else, tok::kw_try, tok::kw_catch,<br>-                            tok::kw_for,<br>-                            // This gets rid of all ObjC @ keywords and methods.<br>-                            tok::at, tok::minus, tok::plus))<br>-      return;<br>-<br>-    FormatToken *Tok = (*(I + 1))->First;<br>-    if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&<br>-        (Tok->getNextNonComment() == NULL ||<br>-         Tok->getNextNonComment()->is(tok::semi))) {<br>-      // We merge empty blocks even if the line exceeds the column limit.<br>-      Tok->SpacesRequiredBefore = 0;<br>-      Tok->CanBreakBefore = true;<br>-      join(Line, **(I + 1));<br>-      I += 1;<br>-    } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) {<br>-      // Check that we still have three lines and they fit into the limit.<br>-      if (I + 2 == E || (*(I + 2))->Type == LT_Invalid ||<br>-          !nextTwoLinesFitInto(I, Limit))<br>-        return;<br>-<br>-      // Second, check that the next line does not contain any braces - if it<br>-      // does, readability declines when putting it into a single line.<br>-      if ((*(I + 1))->Last->Type == TT_LineComment || Tok->MustBreakBefore)<br>-        return;<br>-      do {<br>-        if (Tok->isOneOf(tok::l_brace, tok::r_brace))<br>-          return;<br>-        Tok = Tok->Next;<br>-      } while (Tok != NULL);<br>-<br>-      // Last, check that the third line contains a single closing brace.<br>-      Tok = (*(I + 2))->First;<br>-      if (Tok->getNextNonComment() != NULL || Tok->isNot(tok::r_brace) ||<br>-          Tok->MustBreakBefore)<br>-        return;<br>-<br>-      join(Line, **(I + 1));<br>-      join(Line, **(I + 2));<br>-      I += 2;<br>-    }<br>-  }<br>-<br>-  bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::iterator I,<br>-                           unsigned Limit) {<br>-    return 1 + (*(I + 1))->Last->TotalLength + 1 +<br>-               (*(I + 2))->Last->TotalLength <=<br>-           Limit;<br>-  }<br>-<br>-  void join(AnnotatedLine &A, const AnnotatedLine &B) {<br>-    assert(!A.Last->Next);<br>-    assert(!B.First->Previous);<br>-    A.Last->Next = B.First;<br>-    B.First->Previous = A.Last;<br>-    unsigned LengthA = A.Last->TotalLength + B.First->SpacesRequiredBefore;<br>-    for (FormatToken *Tok = B.First; Tok; Tok = Tok->Next) {<br>-      Tok->TotalLength += LengthA;<br>-      A.Last = Tok;<br>-    }<br>-  }<br>-<br>-  bool touchesRanges(const CharSourceRange &Range) {<br>-    for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {<br>-      if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),<br>-                                               Ranges[i].getBegin()) &&<br>-          !SourceMgr.isBeforeInTranslationUnit(Ranges[i].getEnd(),<br>-                                               Range.getBegin()))<br>-        return true;<br>-    }<br>-    return false;<br>-  }<br>-<br>-  bool touchesLine(const AnnotatedLine &TheLine) {<br>-    const FormatToken *First = TheLine.First;<br>-    const FormatToken *Last = TheLine.Last;<br>-    CharSourceRange LineRange = CharSourceRange::getCharRange(<br>-        First->WhitespaceRange.getBegin().getLocWithOffset(<br>-            First->LastNewlineOffset),<br>-        Last->getStartOfNonWhitespace().getLocWithOffset(<br>-            Last->TokenText.size() - 1));<br>-    return touchesRanges(LineRange);<br>-  }<br>-<br>-  bool touchesPPDirective(SmallVectorImpl<AnnotatedLine *>::iterator I,<br>-                          SmallVectorImpl<AnnotatedLine *>::iterator E) {<br>-    for (; I != E; ++I) {<br>-      if ((*I)->First->HasUnescapedNewline)<br>-        return false;<br>-      if (touchesLine(**I))<br>-        return true;<br>-    }<br>-    return false;<br>-  }<br>-<br>-  bool touchesEmptyLineBefore(const AnnotatedLine &TheLine) {<br>-    const FormatToken *First = TheLine.First;<br>-    CharSourceRange LineRange = CharSourceRange::getCharRange(<br>-        First->WhitespaceRange.getBegin(),<br>-        First->WhitespaceRange.getBegin().getLocWithOffset(<br>-            First->LastNewlineOffset));<br>-    return touchesRanges(LineRange);<br>-  }<br>-<br>   virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) {<br>     assert(!UnwrappedLines.empty());<br>     UnwrappedLines.back().push_back(TheLine);<br>@@ -1282,45 +1322,11 @@ private:<br>     UnwrappedLines.push_back(SmallVector<UnwrappedLine, 16>());<br>   }<br><br>-  /// \brief Add a new line and the required indent before the first Token<br>-  /// of the \c UnwrappedLine if there was no structural parsing error.<br>-  void formatFirstToken(FormatToken &RootToken,<br>-                        const AnnotatedLine *PreviousLine, unsigned IndentLevel,<br>-                        unsigned Indent, bool InPPDirective) {<br>-    unsigned Newlines =<br>-        std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);<br>-    // Remove empty lines before "}" where applicable.<br>-    if (<a href="http://RootToken.is">RootToken.is</a>(tok::r_brace) &&<br>-        (!RootToken.Next ||<br>-         (RootToken.Next->is(tok::semi) && !RootToken.Next->Next)))<br>-      Newlines = std::min(Newlines, 1u);<br>-    if (Newlines == 0 && !RootToken.IsFirst)<br>-      Newlines = 1;<br>-<br>-    // Insert extra new line before access specifiers.<br>-    if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) &&<br>-        RootToken.isAccessSpecifier() && RootToken.NewlinesBefore == 1)<br>-      ++Newlines;<br>-<br>-    // Remove empty lines after access specifiers.<br>-    if (PreviousLine && PreviousLine->First->isAccessSpecifier())<br>-      Newlines = std::min(1u, Newlines);<br>-<br>-    Whitespaces.replaceWhitespace(<br>-        RootToken, Newlines, IndentLevel, Indent, Indent,<br>-        InPPDirective && !RootToken.HasUnescapedNewline);<br>-  }<br>-<br>-  unsigned getColumnLimit(bool InPPDirective) const {<br>-    // In preprocessor directives reserve two chars for trailing " \"<br>-    return Style.ColumnLimit - (InPPDirective ? 2 : 0);<br>-  }<br>-<br>   FormatStyle Style;<br>   Lexer &Lex;<br>   SourceManager &SourceMgr;<br>   WhitespaceManager Whitespaces;<br>-  std::vector<CharSourceRange> Ranges;<br>+  SmallVector<CharSourceRange, 8> Ranges;<br>   SmallVector<SmallVector<UnwrappedLine, 16>, 2> UnwrappedLines;<br><br>   encoding::Encoding Encoding;<br><br>Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=194090&r1=194089&r2=194090&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=194090&r1=194089&r2=194090&view=diff</a><br>==============================================================================<br>--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)<br>+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Tue Nov  5 13:10:03 2013<br>@@ -1013,22 +1013,21 @@ private:<br><br> void<br> TokenAnnotator::setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines) {<br>-  if (Lines.empty())<br>-    return;<br>-<br>   const AnnotatedLine *NextNonCommentLine = NULL;<br>-  for (unsigned i = Lines.size() - 1; i > 0; --i) {<br>-    if (NextNonCommentLine && Lines[i]->First->is(tok::comment) &&<br>-        !Lines[i]->First->Next)<br>-      Lines[i]->Level = NextNonCommentLine->Level;<br>+  for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),<br>+                                                          E = Lines.rend();<br>+       I != E; ++I) {<br>+    if (NextNonCommentLine && (*I)->First->is(tok::comment) &&<br>+        (*I)->First->Next == NULL)<br>+      (*I)->Level = NextNonCommentLine->Level;<br>     else<br>-      NextNonCommentLine =<br>-          Lines[i]->First->isNot(tok::r_brace) ? Lines[i] : NULL;<br>+      NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : NULL;<br>+<br>+    setCommentLineLevels((*I)->Children);<br>   }<br> }<br><br> void TokenAnnotator::annotate(AnnotatedLine &Line) {<br>-  setCommentLineLevels(Line.Children);<br>   for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),<br>                                                   E = Line.Children.end();<br>        I != E; ++I) {<br><br>Modified: cfe/trunk/unittests/Format/FormatTest.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=194090&r1=194089&r2=194090&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=194090&r1=194089&r2=194090&view=diff</a><br>==============================================================================<br>--- cfe/trunk/unittests/Format/FormatTest.cpp (original)<br>+++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Nov  5 13:10:03 2013<br>@@ -2447,6 +2447,45 @@ TEST_F(FormatTest, LayoutNestedBlocks) {<br>                    "  // comment\n"<br>                    "  int  j;\n"<br>                    "});"));<br>+<br>+  verifyFormat("DEBUG({\n"<br>+               "  if (a)\n"<br>+               "    return;\n"<br>+               "});");<br>+  verifyGoogleFormat("DEBUG({\n"<br>+                     "  if (a) return;\n"<br>+                     "});");<br>+  FormatStyle Style = getGoogleStyle();<br>+  Style.ColumnLimit = 45;<br>+  verifyFormat("Debug(aaaaa, {\n"<br>+               "               if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"<br>+               "                 return;\n"<br>+               "             },\n"<br>+               "      a);", Style);<br>+<br>+  EXPECT_EQ("Debug({\n"<br>+            "        if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"<br>+            "          return;\n"<br>+            "      },\n"<br>+            "      a);",<br>+            format("Debug({\n"<br>+                   "        if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"<br>+                   "             return;\n"<br>+                   "      },\n"<br>+                   "      a);",<br>+                   50, 1, getLLVMStyle()));<br>+}<br>+<br>+TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) {<br>+  EXPECT_EQ("DEBUG({\n"<br>+            "  int        i;\n"<br>+            "  int j;\n"<br>+            "});",<br>+            format("DEBUG(   {\n"<br>+                   "  int        i;\n"<br>+                   "  int        j;\n"<br>+                   "}   )  ;",<br>+                   40, 1, getLLVMStyle()));<br> }<br><br> TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) {<br><br><br>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits<br></blockquote></div><br></div></body></html>