<div dir="ltr">For what it's worth, I would find it super helpful if there were class-level comments on the classes in lib/Format that briefly describe the main responsibility of each class and explain terminology ("An unwrapped line is a $concise explanation"). There are now enough classes in lib/Format that I'm always a bit confused about this when reading this code.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 10, 2014 at 11:00 AM, Daniel Jasper <span dir="ltr"><<a href="mailto:djasper@google.com" target="_blank">djasper@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: djasper<br>
Date: Wed Dec 10 13:00:42 2014<br>
New Revision: 223936<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=223936&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=223936&view=rev</a><br>
Log:<br>
clang-format: Factor out UnwrappedLineFormatter into a separate file.<br>
<br>
No functional changes intended.<br>
<br>
Added:<br>
    cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp<br>
    cfe/trunk/lib/Format/UnwrappedLineFormatter.h<br>
Modified:<br>
    cfe/trunk/lib/Format/CMakeLists.txt<br>
    cfe/trunk/lib/Format/Format.cpp<br>
<br>
Modified: cfe/trunk/lib/Format/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/CMakeLists.txt?rev=223936&r1=223935&r2=223936&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/CMakeLists.txt?rev=223936&r1=223935&r2=223936&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/CMakeLists.txt (original)<br>
+++ cfe/trunk/lib/Format/CMakeLists.txt Wed Dec 10 13:00:42 2014<br>
@@ -6,6 +6,7 @@ add_clang_library(clangFormat<br>
   Format.cpp<br>
   FormatToken.cpp<br>
   TokenAnnotator.cpp<br>
+  UnwrappedLineFormatter.cpp<br>
   UnwrappedLineParser.cpp<br>
   WhitespaceManager.cpp<br>
<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=223936&r1=223935&r2=223936&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=223936&r1=223935&r2=223936&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/Format.cpp (original)<br>
+++ cfe/trunk/lib/Format/Format.cpp Wed Dec 10 13:00:42 2014<br>
@@ -15,6 +15,7 @@<br>
<br>
 #include "ContinuationIndenter.h"<br>
 #include "TokenAnnotator.h"<br>
+#include "UnwrappedLineFormatter.h"<br>
 #include "UnwrappedLineParser.h"<br>
 #include "WhitespaceManager.h"<br>
 #include "clang/Basic/Diagnostic.h"<br>
@@ -589,779 +590,6 @@ std::string configurationAsText(const Fo<br>
<br>
 namespace {<br>
<br>
-bool startsExternCBlock(const AnnotatedLine &Line) {<br>
-  const FormatToken *Next = Line.First->getNextNonComment();<br>
-  const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr;<br>
-  return Line.First->is(tok::kw_extern) && Next && Next->isStringLiteral() &&<br>
-         NextNext && NextNext->is(tok::l_brace);<br>
-}<br>
-<br>
-class NoColumnLimitFormatter {<br>
-public:<br>
-  NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {}<br>
-<br>
-  /// \brief Formats the line starting at \p State, simply keeping all of the<br>
-  /// input's line breaking decisions.<br>
-  void format(unsigned FirstIndent, const AnnotatedLine *Line) {<br>
-    LineState State =<br>
-        Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false);<br>
-    while (State.NextToken) {<br>
-      bool Newline =<br>
-          Indenter->mustBreak(State) ||<br>
-          (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);<br>
-      Indenter->addTokenToState(State, Newline, /*DryRun=*/false);<br>
-    }<br>
-  }<br>
-<br>
-private:<br>
-  ContinuationIndenter *Indenter;<br>
-};<br>
-<br>
-class LineJoiner {<br>
-public:<br>
-  LineJoiner(const FormatStyle &Style) : Style(Style) {}<br>
-<br>
-  /// \brief Calculates how many lines can be merged into 1 starting at \p I.<br>
-  unsigned<br>
-  tryFitMultipleLinesInOne(unsigned Indent,<br>
-                           SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-                           SmallVectorImpl<AnnotatedLine *>::const_iterator E) {<br>
-    // We can never merge stuff if there are trailing line comments.<br>
-    const AnnotatedLine *TheLine = *I;<br>
-    if (TheLine->Last->is(TT_LineComment))<br>
-      return 0;<br>
-<br>
-    if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit)<br>
-      return 0;<br>
-<br>
-    unsigned Limit =<br>
-        Style.ColumnLimit == 0 ? UINT_MAX : 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 || I[1]->First->MustBreakBefore)<br>
-      return 0;<br>
-<br>
-    // FIXME: TheLine->Level != 0 might or might not be the right check to do.<br>
-    // If necessary, change to something smarter.<br>
-    bool MergeShortFunctions =<br>
-        Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All ||<br>
-        (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty &&<br>
-         I[1]->First->is(tok::r_brace)) ||<br>
-        (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline &&<br>
-         TheLine->Level != 0);<br>
-<br>
-    if (TheLine->Last->is(TT_FunctionLBrace) &&<br>
-        TheLine->First != TheLine->Last) {<br>
-      return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;<br>
-    }<br>
-    if (TheLine->Last->is(tok::l_brace)) {<br>
-      return Style.BreakBeforeBraces == FormatStyle::BS_Attach<br>
-                 ? tryMergeSimpleBlock(I, E, Limit)<br>
-                 : 0;<br>
-    }<br>
-    if (I[1]->First->is(TT_FunctionLBrace) &&<br>
-        Style.BreakBeforeBraces != FormatStyle::BS_Attach) {<br>
-      if (I[1]->Last->is(TT_LineComment))<br>
-        return 0;<br>
-<br>
-      // Check for Limit <= 2 to account for the " {".<br>
-      if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))<br>
-        return 0;<br>
-      Limit -= 2;<br>
-<br>
-      unsigned MergedLines = 0;<br>
-      if (MergeShortFunctions) {<br>
-        MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);<br>
-        // If we managed to merge the block, count the function header, which is<br>
-        // on a separate line.<br>
-        if (MergedLines > 0)<br>
-          ++MergedLines;<br>
-      }<br>
-      return MergedLines;<br>
-    }<br>
-    if (TheLine->First->is(tok::kw_if)) {<br>
-      return Style.AllowShortIfStatementsOnASingleLine<br>
-                 ? tryMergeSimpleControlStatement(I, E, Limit)<br>
-                 : 0;<br>
-    }<br>
-    if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {<br>
-      return Style.AllowShortLoopsOnASingleLine<br>
-                 ? tryMergeSimpleControlStatement(I, E, Limit)<br>
-                 : 0;<br>
-    }<br>
-    if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {<br>
-      return Style.AllowShortCaseLabelsOnASingleLine<br>
-                 ? tryMergeShortCaseLabels(I, E, Limit)<br>
-                 : 0;<br>
-    }<br>
-    if (TheLine->InPPDirective &&<br>
-        (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {<br>
-      return tryMergeSimplePPDirective(I, E, Limit);<br>
-    }<br>
-    return 0;<br>
-  }<br>
-<br>
-private:<br>
-  unsigned<br>
-  tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-                            SmallVectorImpl<AnnotatedLine *>::const_iterator E,<br>
-                            unsigned Limit) {<br>
-    if (Limit == 0)<br>
-      return 0;<br>
-    if (!I[1]->InPPDirective || I[1]->First->HasUnescapedNewline)<br>
-      return 0;<br>
-    if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)<br>
-      return 0;<br>
-    if (1 + I[1]->Last->TotalLength > Limit)<br>
-      return 0;<br>
-    return 1;<br>
-  }<br>
-<br>
-  unsigned tryMergeSimpleControlStatement(<br>
-      SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-      SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {<br>
-    if (Limit == 0)<br>
-      return 0;<br>
-    if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman ||<br>
-         Style.BreakBeforeBraces == FormatStyle::BS_GNU) &&<br>
-        (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine))<br>
-      return 0;<br>
-    if (I[1]->InPPDirective != (*I)->InPPDirective ||<br>
-        (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))<br>
-      return 0;<br>
-    Limit = limitConsideringMacros(I + 1, E, Limit);<br>
-    AnnotatedLine &Line = **I;<br>
-    if (Line.Last->isNot(tok::r_paren))<br>
-      return 0;<br>
-    if (1 + I[1]->Last->TotalLength > Limit)<br>
-      return 0;<br>
-    if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,<br>
-                             tok::kw_while, TT_LineComment))<br>
-      return 0;<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 0;<br>
-    return 1;<br>
-  }<br>
-<br>
-  unsigned tryMergeShortCaseLabels(<br>
-      SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-      SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {<br>
-    if (Limit == 0 || I + 1 == E ||<br>
-        I[1]->First->isOneOf(tok::kw_case, tok::kw_default))<br>
-      return 0;<br>
-    unsigned NumStmts = 0;<br>
-    unsigned Length = 0;<br>
-    bool InPPDirective = I[0]->InPPDirective;<br>
-    for (; NumStmts < 3; ++NumStmts) {<br>
-      if (I + 1 + NumStmts == E)<br>
-        break;<br>
-      const AnnotatedLine *Line = I[1 + NumStmts];<br>
-      if (Line->InPPDirective != InPPDirective)<br>
-        break;<br>
-      if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))<br>
-        break;<br>
-      if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,<br>
-                               tok::kw_while, tok::comment))<br>
-        return 0;<br>
-      Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.<br>
-    }<br>
-    if (NumStmts == 0 || NumStmts == 3 || Length > Limit)<br>
-      return 0;<br>
-    return NumStmts;<br>
-  }<br>
-<br>
-  unsigned<br>
-  tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-                      SmallVectorImpl<AnnotatedLine *>::const_iterator E,<br>
-                      unsigned Limit) {<br>
-    AnnotatedLine &Line = **I;<br>
-<br>
-    // Don't merge ObjC @ keywords and methods.<br>
-    if (Style.Language != FormatStyle::LK_Java &&<br>
-        Line.First->isOneOf(tok::at, tok::minus, tok::plus))<br>
-      return 0;<br>
-<br>
-    // Check that the current line allows merging. This depends on whether we<br>
-    // are in a control flow statements as well as several style flags.<br>
-    if (Line.First->isOneOf(tok::kw_else, tok::kw_case))<br>
-      return 0;<br>
-    if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try,<br>
-                            tok::kw_catch, tok::kw_for, tok::r_brace)) {<br>
-      if (!Style.AllowShortBlocksOnASingleLine)<br>
-        return 0;<br>
-      if (!Style.AllowShortIfStatementsOnASingleLine &&<br>
-          Line.First->is(tok::kw_if))<br>
-        return 0;<br>
-      if (!Style.AllowShortLoopsOnASingleLine &&<br>
-          Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for))<br>
-        return 0;<br>
-      // FIXME: Consider an option to allow short exception handling clauses on<br>
-      // a single line.<br>
-      if (Line.First->isOneOf(tok::kw_try, tok::kw_catch))<br>
-        return 0;<br>
-    }<br>
-<br>
-    FormatToken *Tok = I[1]->First;<br>
-    if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&<br>
-        (Tok->getNextNonComment() == nullptr ||<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>
-      return 1;<br>
-    } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace) &&<br>
-               !startsExternCBlock(Line)) {<br>
-      // We don't merge short records.<br>
-      if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct))<br>
-        return 0;<br>
-<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>
-        return 0;<br>
-      Limit = limitConsideringMacros(I + 2, E, Limit);<br>
-<br>
-      if (!nextTwoLinesFitInto(I, Limit))<br>
-        return 0;<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->is(TT_LineComment))<br>
-        return 0;<br>
-      do {<br>
-        if (Tok->is(tok::l_brace) && Tok->BlockKind != BK_BracedInit)<br>
-          return 0;<br>
-        Tok = Tok->Next;<br>
-      } while (Tok);<br>
-<br>
-      // Last, check that the third line starts with a closing brace.<br>
-      Tok = I[2]->First;<br>
-      if (Tok->isNot(tok::r_brace))<br>
-        return 0;<br>
-<br>
-      return 2;<br>
-    }<br>
-    return 0;<br>
-  }<br>
-<br>
-  /// Returns the modified column limit for \p I if it is inside a macro and<br>
-  /// needs a trailing '\'.<br>
-  unsigned<br>
-  limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-                         SmallVectorImpl<AnnotatedLine *>::const_iterator E,<br>
-                         unsigned Limit) {<br>
-    if (I[0]->InPPDirective && I + 1 != E &&<br>
-        !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) {<br>
-      return Limit < 2 ? 0 : Limit - 2;<br>
-    }<br>
-    return Limit;<br>
-  }<br>
-<br>
-  bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
-                           unsigned Limit) {<br>
-    if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)<br>
-      return false;<br>
-    return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;<br>
-  }<br>
-<br>
-  bool containsMustBreak(const AnnotatedLine *Line) {<br>
-    for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {<br>
-      if (Tok->MustBreakBefore)<br>
-        return true;<br>
-    }<br>
-    return false;<br>
-  }<br>
-<br>
-  const FormatStyle &Style;<br>
-};<br>
-<br>
-class UnwrappedLineFormatter {<br>
-public:<br>
-  UnwrappedLineFormatter(ContinuationIndenter *Indenter,<br>
-                         WhitespaceManager *Whitespaces,<br>
-                         const FormatStyle &Style)<br>
-      : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),<br>
-        Joiner(Style) {}<br>
-<br>
-  unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,<br>
-                  int AdditionalIndent = 0, bool FixBadIndentation = false) {<br>
-    // Try to look up already computed penalty in DryRun-mode.<br>
-    std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey(<br>
-        &Lines, AdditionalIndent);<br>
-    auto CacheIt = PenaltyCache.find(CacheKey);<br>
-    if (DryRun && CacheIt != PenaltyCache.end())<br>
-      return CacheIt->second;<br>
-<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>
-    const AnnotatedLine *PreviousLine = nullptr;<br>
-    for (SmallVectorImpl<AnnotatedLine *>::const_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>
-      // Determine indent and try to merge multiple unwrapped lines.<br>
-      unsigned Indent;<br>
-      if (TheLine.InPPDirective) {<br>
-        Indent = TheLine.Level * Style.IndentWidth;<br>
-      } else {<br>
-        while (IndentForLevel.size() <= TheLine.Level)<br>
-          IndentForLevel.push_back(-1);<br>
-        IndentForLevel.resize(TheLine.Level + 1);<br>
-        Indent = getIndent(IndentForLevel, TheLine.Level);<br>
-      }<br>
-      unsigned LevelIndent = Indent;<br>
-      if (static_cast<int>(Indent) + Offset >= 0)<br>
-        Indent += Offset;<br>
-<br>
-      // Merge multiple lines if possible.<br>
-      unsigned MergedLines = Joiner.tryFitMultipleLinesInOne(Indent, I, E);<br>
-      if (MergedLines > 0 && Style.ColumnLimit == 0) {<br>
-        // Disallow line merging if there is a break at the start of one of the<br>
-        // input lines.<br>
-        for (unsigned i = 0; i < MergedLines; ++i) {<br>
-          if (I[i + 1]->First->NewlinesBefore > 0)<br>
-            MergedLines = 0;<br>
-        }<br>
-      }<br>
-      if (!DryRun) {<br>
-        for (unsigned i = 0; i < MergedLines; ++i) {<br>
-          join(*I[i], *I[i + 1]);<br>
-        }<br>
-      }<br>
-      I += MergedLines;<br>
-<br>
-      bool FixIndentation =<br>
-          FixBadIndentation && (LevelIndent != FirstTok->OriginalColumn);<br>
-      if (TheLine.First->is(tok::eof)) {<br>
-        if (PreviousLine && PreviousLine->Affected && !DryRun) {<br>
-          // Remove the file's trailing whitespace.<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>
-                 (TheLine.Affected || FixIndentation)) {<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>
-            TheLine.Type == LT_ImportStatement) {<br>
-          LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun);<br>
-          while (State.NextToken) {<br>
-            formatChildren(State, /*Newline=*/false, /*DryRun=*/false, Penalty);<br>
-            Indenter->addTokenToState(State, /*Newline=*/false, DryRun);<br>
-          }<br>
-        } else if (Style.ColumnLimit == 0) {<br>
-          // FIXME: Implement nested blocks for 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>
-        if (!TheLine.InPPDirective)<br>
-          IndentForLevel[TheLine.Level] = LevelIndent;<br>
-      } else if (TheLine.ChildrenAffected) {<br>
-        format(TheLine.Children, DryRun);<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; 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.<br>
-              if ((PreviousLine && PreviousLine->Affected) ||<br>
-                  TheLine.LeadingEmptyLinesAffected) {<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) && !TheLine.InPPDirective)<br>
-              IndentForLevel[TheLine.Level] = LevelIndent;<br>
-          } else if (!DryRun) {<br>
-            Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);<br>
-          }<br>
-        }<br>
-      }<br>
-      if (!DryRun) {<br>
-        for (FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) {<br>
-          Tok->Finalized = true;<br>
-        }<br>
-      }<br>
-      PreviousLine = *I;<br>
-    }<br>
-    PenaltyCache[CacheKey] = Penalty;<br>
-    return Penalty;<br>
-  }<br>
-<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(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 (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>
-  /// \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>
-    StateNode(const LineState &State, bool NewLine, StateNode *Previous)<br>
-        : State(State), NewLine(NewLine), Previous(Previous) {}<br>
-    LineState State;<br>
-    bool NewLine;<br>
-    StateNode *Previous;<br>
-  };<br>
-<br>
-  /// \brief A pair of <penalty, count> that is used to prioritize the BFS on.<br>
-  ///<br>
-  /// In case of equal penalties, we want to prefer states that were inserted<br>
-  /// first. During state generation we make sure that we insert states first<br>
-  /// that break the line as late as possible.<br>
-  typedef std::pair<unsigned, unsigned> OrderedPenalty;<br>
-<br>
-  /// \brief An item in the prioritized BFS search queue. The \c StateNode's<br>
-  /// \c State has the given \c OrderedPenalty.<br>
-  typedef std::pair<OrderedPenalty, StateNode *> QueueItem;<br>
-<br>
-  /// \brief The BFS queue type.<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 (Style.Language == FormatStyle::LK_Java)<br>
-      return 0;<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 (RootToken.is(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>
-    if (RootToken.IsFirst && !RootToken.HasUnescapedNewline)<br>
-      Newlines = 0;<br>
-<br>
-    // Remove empty lines after "{".<br>
-    if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&<br>
-        PreviousLine->Last->is(tok::l_brace) &&<br>
-        PreviousLine->First->isNot(tok::kw_namespace) &&<br>
-        !startsExternCBlock(*PreviousLine))<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(RootToken, Newlines, IndentLevel, Indent,<br>
-                                   Indent, InPPDirective &&<br>
-                                               !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(ArrayRef<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>
-  void join(AnnotatedLine &A, const AnnotatedLine &B) {<br>
-    assert(!A.Last->Next);<br>
-    assert(!B.First->Previous);<br>
-    if (B.Affected)<br>
-      A.Affected = true;<br>
-    A.Last->Next = B.First;<br>
-    B.First->Previous = A.Last;<br>
-    B.First->CanBreakBefore = true;<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>
-  struct CompareLineStatePointers {<br>
-    bool operator()(LineState *obj1, LineState *obj2) const {<br>
-      return *obj1 < *obj2;<br>
-    }<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>
-  /// the solution space (\c LineStates are the nodes). The algorithm tries to<br>
-  /// find the shortest path (the one with lowest penalty) from \p InitialState<br>
-  /// to a state where all tokens are placed. Returns the penalty.<br>
-  ///<br>
-  /// If \p DryRun is \c false, directly applies the changes.<br>
-  unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun = false) {<br>
-    std::set<LineState *, CompareLineStatePointers> 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, nullptr);<br>
-    Queue.push(QueueItem(OrderedPenalty(0, Count), Node));<br>
-    ++Count;<br>
-<br>
-    unsigned Penalty = 0;<br>
-<br>
-    // While not empty, take first element and follow edges.<br>
-    while (!Queue.empty()) {<br>
-      Penalty = Queue.top().first.first;<br>
-      StateNode *Node = Queue.top().second;<br>
-      if (!Node->State.NextToken) {<br>
-        DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");<br>
-        break;<br>
-      }<br>
-      Queue.pop();<br>
-<br>
-      // Cut off the analysis of certain solutions if the analysis gets too<br>
-      // complex. See description of IgnoreStackForComparison.<br>
-      if (Count > 10000)<br>
-        Node->State.IgnoreStackForComparison = true;<br>
-<br>
-      if (!Seen.insert(&Node->State).second)<br>
-        // State already examined with lower penalty.<br>
-        continue;<br>
-<br>
-      FormatDecision LastFormat = Node->State.NextToken->Decision;<br>
-      if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)<br>
-        addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);<br>
-      if (LastFormat == FD_Unformatted || LastFormat == FD_Break)<br>
-        addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);<br>
-    }<br>
-<br>
-    if (Queue.empty()) {<br>
-      // We were unable to find a solution, do nothing.<br>
-      // FIXME: Add diagnostic?<br>
-      DEBUG(llvm::dbgs() << "Could not find a solution.\n");<br>
-      return 0;<br>
-    }<br>
-<br>
-    // Reconstruct the solution.<br>
-    if (!DryRun)<br>
-      reconstructPath(InitialState, Queue.top().second);<br>
-<br>
-    DEBUG(llvm::dbgs() << "Total number of analyzed states: " << Count << "\n");<br>
-    DEBUG(llvm::dbgs() << "---\n");<br>
-<br>
-    return Penalty;<br>
-  }<br>
-<br>
-  void reconstructPath(LineState &State, StateNode *Current) {<br>
-    std::deque<StateNode *> Path;<br>
-    // We do not need a break before the initial token.<br>
-    while (Current->Previous) {<br>
-      Path.push_front(Current);<br>
-      Current = Current->Previous;<br>
-    }<br>
-    for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();<br>
-         I != E; ++I) {<br>
-      unsigned Penalty = 0;<br>
-      formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty);<br>
-      Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false);<br>
-<br>
-      DEBUG({<br>
-        if ((*I)->NewLine) {<br>
-          llvm::dbgs() << "Penalty for placing "<br>
-                       << (*I)->Previous->State.NextToken->Tok.getName() << ": "<br>
-                       << Penalty << "\n";<br>
-        }<br>
-      });<br>
-    }<br>
-  }<br>
-<br>
-  /// \brief Add the following state to the analysis queue \c Queue.<br>
-  ///<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, unsigned *Count, QueueType *Queue) {<br>
-    if (NewLine && !Indenter->canBreak(PreviousNode->State))<br>
-      return;<br>
-    if (!NewLine && Indenter->mustBreak(PreviousNode->State))<br>
-      return;<br>
-<br>
-    StateNode *Node = new (Allocator.Allocate())<br>
-        StateNode(PreviousNode->State, NewLine, PreviousNode);<br>
-    if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))<br>
-      return;<br>
-<br>
-    Penalty += Indenter->addTokenToState(Node->State, NewLine, true);<br>
-<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>
-  /// format the nested block before it.<br>
-  ///<br>
-  /// Returns \c true if all children could be placed successfully and adapts<br>
-  /// \p Penalty as well as \p State. If \p DryRun is false, also directly<br>
-  /// creates changes using \c Whitespaces.<br>
-  ///<br>
-  /// The crucial idea here is that children always get formatted upon<br>
-  /// encountering the closing brace right after the nested block. Now, if we<br>
-  /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is<br>
-  /// \c false), the entire block has to be kept on the same line (which is only<br>
-  /// possible if it fits on the line, only contains a single statement, etc.<br>
-  ///<br>
-  /// If \p NewLine is true, we format the nested block on separate lines, i.e.<br>
-  /// break after the "{", format all lines with correct indentation and the put<br>
-  /// the closing "}" on yet another new line.<br>
-  ///<br>
-  /// This enables us to keep the simple structure of the<br>
-  /// \c UnwrappedLineFormatter, where we only have two options for each token:<br>
-  /// break or don't break.<br>
-  bool formatChildren(LineState &State, bool NewLine, bool DryRun,<br>
-                      unsigned &Penalty) {<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>
-      // The previous token does not open a block. Nothing to do. We don't<br>
-      // assert so that we can simply call this function for all tokens.<br>
-      return true;<br>
-<br>
-    if (NewLine) {<br>
-      int AdditionalIndent =<br>
-          State.FirstIndent - State.Line->Level * Style.IndentWidth;<br>
-      if (State.Stack.size() < 2 ||<br>
-          !State.Stack[State.Stack.size() - 2].NestedBlockInlined) {<br>
-        AdditionalIndent = State.Stack.back().Indent -<br>
-                           Previous.Children[0]->Level * Style.IndentWidth;<br>
-      }<br>
-<br>
-      Penalty += format(Previous.Children, DryRun, AdditionalIndent,<br>
-                        /*FixBadIndentation=*/true);<br>
-      return true;<br>
-    }<br>
-<br>
-    if (Previous.Children[0]->First->MustBreakBefore)<br>
-      return false;<br>
-<br>
-    // Cannot merge multiple statements into a single line.<br>
-    if (Previous.Children.size() > 1)<br>
-      return false;<br>
-<br>
-    // Cannot merge into one line if this line ends on a comment.<br>
-    if (Previous.is(tok::comment))<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>
-      return false;<br>
-<br>
-    // If the child line exceeds the column limit, we wouldn't want to merge it.<br>
-    // We add +2 for the trailing " }".<br>
-    if (Style.ColumnLimit > 0 &&<br>
-        Previous.Children[0]->Last->TotalLength + State.Column + 2 ><br>
-            Style.ColumnLimit)<br>
-      return false;<br>
-<br>
-    if (!DryRun) {<br>
-      Whitespaces->replaceWhitespace(<br>
-          *Previous.Children[0]->First,<br>
-          /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1,<br>
-          /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);<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>
-  ContinuationIndenter *Indenter;<br>
-  WhitespaceManager *Whitespaces;<br>
-  FormatStyle Style;<br>
-  LineJoiner Joiner;<br>
-<br>
-  llvm::SpecificBumpPtrAllocator<StateNode> Allocator;<br>
-<br>
-  // Cache to store the penalty of formatting a vector of AnnotatedLines<br>
-  // starting from a specific additional offset. Improves performance if there<br>
-  // are many nested blocks.<br>
-  std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,<br>
-           unsigned> PenaltyCache;<br>
-};<br>
-<br>
 class FormatTokenLexer {<br>
 public:<br>
   FormatTokenLexer(SourceManager &SourceMgr, FileID ID, FormatStyle &Style,<br>
<br>
Added: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=223936&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=223936&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (added)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Wed Dec 10 13:00:42 2014<br>
@@ -0,0 +1,699 @@<br>
+//===--- UnwrappedLineFormatter.cpp - Format C++ code ---------------------===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "UnwrappedLineFormatter.h"<br>
+#include "WhitespaceManager.h"<br>
+#include "llvm/Support/Debug.h"<br>
+<br>
+#define DEBUG_TYPE "format-formatter"<br>
+<br>
+namespace clang {<br>
+namespace format {<br>
+<br>
+namespace {<br>
+<br>
+bool startsExternCBlock(const AnnotatedLine &Line) {<br>
+  const FormatToken *Next = Line.First->getNextNonComment();<br>
+  const FormatToken *NextNext = Next ? Next->getNextNonComment() : nullptr;<br>
+  return Line.First->is(tok::kw_extern) && Next && Next->isStringLiteral() &&<br>
+         NextNext && NextNext->is(tok::l_brace);<br>
+}<br>
+<br>
+class LineJoiner {<br>
+public:<br>
+  LineJoiner(const FormatStyle &Style) : Style(Style) {}<br>
+<br>
+  /// \brief Calculates how many lines can be merged into 1 starting at \p I.<br>
+  unsigned<br>
+  tryFitMultipleLinesInOne(unsigned Indent,<br>
+                           SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+                           SmallVectorImpl<AnnotatedLine *>::const_iterator E) {<br>
+    // We can never merge stuff if there are trailing line comments.<br>
+    const AnnotatedLine *TheLine = *I;<br>
+    if (TheLine->Last->is(TT_LineComment))<br>
+      return 0;<br>
+<br>
+    if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit)<br>
+      return 0;<br>
+<br>
+    unsigned Limit =<br>
+        Style.ColumnLimit == 0 ? UINT_MAX : 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 || I[1]->First->MustBreakBefore)<br>
+      return 0;<br>
+<br>
+    // FIXME: TheLine->Level != 0 might or might not be the right check to do.<br>
+    // If necessary, change to something smarter.<br>
+    bool MergeShortFunctions =<br>
+        Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All ||<br>
+        (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Empty &&<br>
+         I[1]->First->is(tok::r_brace)) ||<br>
+        (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline &&<br>
+         TheLine->Level != 0);<br>
+<br>
+    if (TheLine->Last->is(TT_FunctionLBrace) &&<br>
+        TheLine->First != TheLine->Last) {<br>
+      return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;<br>
+    }<br>
+    if (TheLine->Last->is(tok::l_brace)) {<br>
+      return Style.BreakBeforeBraces == FormatStyle::BS_Attach<br>
+                 ? tryMergeSimpleBlock(I, E, Limit)<br>
+                 : 0;<br>
+    }<br>
+    if (I[1]->First->is(TT_FunctionLBrace) &&<br>
+        Style.BreakBeforeBraces != FormatStyle::BS_Attach) {<br>
+      if (I[1]->Last->is(TT_LineComment))<br>
+        return 0;<br>
+<br>
+      // Check for Limit <= 2 to account for the " {".<br>
+      if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))<br>
+        return 0;<br>
+      Limit -= 2;<br>
+<br>
+      unsigned MergedLines = 0;<br>
+      if (MergeShortFunctions) {<br>
+        MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);<br>
+        // If we managed to merge the block, count the function header, which is<br>
+        // on a separate line.<br>
+        if (MergedLines > 0)<br>
+          ++MergedLines;<br>
+      }<br>
+      return MergedLines;<br>
+    }<br>
+    if (TheLine->First->is(tok::kw_if)) {<br>
+      return Style.AllowShortIfStatementsOnASingleLine<br>
+                 ? tryMergeSimpleControlStatement(I, E, Limit)<br>
+                 : 0;<br>
+    }<br>
+    if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {<br>
+      return Style.AllowShortLoopsOnASingleLine<br>
+                 ? tryMergeSimpleControlStatement(I, E, Limit)<br>
+                 : 0;<br>
+    }<br>
+    if (TheLine->First->isOneOf(tok::kw_case, tok::kw_default)) {<br>
+      return Style.AllowShortCaseLabelsOnASingleLine<br>
+                 ? tryMergeShortCaseLabels(I, E, Limit)<br>
+                 : 0;<br>
+    }<br>
+    if (TheLine->InPPDirective &&<br>
+        (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {<br>
+      return tryMergeSimplePPDirective(I, E, Limit);<br>
+    }<br>
+    return 0;<br>
+  }<br>
+<br>
+private:<br>
+  unsigned<br>
+  tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+                            SmallVectorImpl<AnnotatedLine *>::const_iterator E,<br>
+                            unsigned Limit) {<br>
+    if (Limit == 0)<br>
+      return 0;<br>
+    if (!I[1]->InPPDirective || I[1]->First->HasUnescapedNewline)<br>
+      return 0;<br>
+    if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)<br>
+      return 0;<br>
+    if (1 + I[1]->Last->TotalLength > Limit)<br>
+      return 0;<br>
+    return 1;<br>
+  }<br>
+<br>
+  unsigned tryMergeSimpleControlStatement(<br>
+      SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+      SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {<br>
+    if (Limit == 0)<br>
+      return 0;<br>
+    if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman ||<br>
+         Style.BreakBeforeBraces == FormatStyle::BS_GNU) &&<br>
+        (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine))<br>
+      return 0;<br>
+    if (I[1]->InPPDirective != (*I)->InPPDirective ||<br>
+        (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))<br>
+      return 0;<br>
+    Limit = limitConsideringMacros(I + 1, E, Limit);<br>
+    AnnotatedLine &Line = **I;<br>
+    if (Line.Last->isNot(tok::r_paren))<br>
+      return 0;<br>
+    if (1 + I[1]->Last->TotalLength > Limit)<br>
+      return 0;<br>
+    if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,<br>
+                             tok::kw_while, TT_LineComment))<br>
+      return 0;<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 0;<br>
+    return 1;<br>
+  }<br>
+<br>
+  unsigned tryMergeShortCaseLabels(<br>
+      SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+      SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {<br>
+    if (Limit == 0 || I + 1 == E ||<br>
+        I[1]->First->isOneOf(tok::kw_case, tok::kw_default))<br>
+      return 0;<br>
+    unsigned NumStmts = 0;<br>
+    unsigned Length = 0;<br>
+    bool InPPDirective = I[0]->InPPDirective;<br>
+    for (; NumStmts < 3; ++NumStmts) {<br>
+      if (I + 1 + NumStmts == E)<br>
+        break;<br>
+      const AnnotatedLine *Line = I[1 + NumStmts];<br>
+      if (Line->InPPDirective != InPPDirective)<br>
+        break;<br>
+      if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))<br>
+        break;<br>
+      if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,<br>
+                               tok::kw_while, tok::comment))<br>
+        return 0;<br>
+      Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.<br>
+    }<br>
+    if (NumStmts == 0 || NumStmts == 3 || Length > Limit)<br>
+      return 0;<br>
+    return NumStmts;<br>
+  }<br>
+<br>
+  unsigned<br>
+  tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+                      SmallVectorImpl<AnnotatedLine *>::const_iterator E,<br>
+                      unsigned Limit) {<br>
+    AnnotatedLine &Line = **I;<br>
+<br>
+    // Don't merge ObjC @ keywords and methods.<br>
+    if (Style.Language != FormatStyle::LK_Java &&<br>
+        Line.First->isOneOf(tok::at, tok::minus, tok::plus))<br>
+      return 0;<br>
+<br>
+    // Check that the current line allows merging. This depends on whether we<br>
+    // are in a control flow statements as well as several style flags.<br>
+    if (Line.First->isOneOf(tok::kw_else, tok::kw_case))<br>
+      return 0;<br>
+    if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try,<br>
+                            tok::kw_catch, tok::kw_for, tok::r_brace)) {<br>
+      if (!Style.AllowShortBlocksOnASingleLine)<br>
+        return 0;<br>
+      if (!Style.AllowShortIfStatementsOnASingleLine &&<br>
+          Line.First->is(tok::kw_if))<br>
+        return 0;<br>
+      if (!Style.AllowShortLoopsOnASingleLine &&<br>
+          Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for))<br>
+        return 0;<br>
+      // FIXME: Consider an option to allow short exception handling clauses on<br>
+      // a single line.<br>
+      if (Line.First->isOneOf(tok::kw_try, tok::kw_catch))<br>
+        return 0;<br>
+    }<br>
+<br>
+    FormatToken *Tok = I[1]->First;<br>
+    if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&<br>
+        (Tok->getNextNonComment() == nullptr ||<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>
+      return 1;<br>
+    } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace) &&<br>
+               !startsExternCBlock(Line)) {<br>
+      // We don't merge short records.<br>
+      if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct))<br>
+        return 0;<br>
+<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>
+        return 0;<br>
+      Limit = limitConsideringMacros(I + 2, E, Limit);<br>
+<br>
+      if (!nextTwoLinesFitInto(I, Limit))<br>
+        return 0;<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->is(TT_LineComment))<br>
+        return 0;<br>
+      do {<br>
+        if (Tok->is(tok::l_brace) && Tok->BlockKind != BK_BracedInit)<br>
+          return 0;<br>
+        Tok = Tok->Next;<br>
+      } while (Tok);<br>
+<br>
+      // Last, check that the third line starts with a closing brace.<br>
+      Tok = I[2]->First;<br>
+      if (Tok->isNot(tok::r_brace))<br>
+        return 0;<br>
+<br>
+      return 2;<br>
+    }<br>
+    return 0;<br>
+  }<br>
+<br>
+  /// Returns the modified column limit for \p I if it is inside a macro and<br>
+  /// needs a trailing '\'.<br>
+  unsigned<br>
+  limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+                         SmallVectorImpl<AnnotatedLine *>::const_iterator E,<br>
+                         unsigned Limit) {<br>
+    if (I[0]->InPPDirective && I + 1 != E &&<br>
+        !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) {<br>
+      return Limit < 2 ? 0 : Limit - 2;<br>
+    }<br>
+    return Limit;<br>
+  }<br>
+<br>
+  bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,<br>
+                           unsigned Limit) {<br>
+    if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)<br>
+      return false;<br>
+    return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;<br>
+  }<br>
+<br>
+  bool containsMustBreak(const AnnotatedLine *Line) {<br>
+    for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {<br>
+      if (Tok->MustBreakBefore)<br>
+        return true;<br>
+    }<br>
+    return false;<br>
+  }<br>
+<br>
+  const FormatStyle &Style;<br>
+};<br>
+<br>
+class NoColumnLimitFormatter {<br>
+public:<br>
+  NoColumnLimitFormatter(ContinuationIndenter *Indenter) : Indenter(Indenter) {}<br>
+<br>
+  /// \brief Formats the line starting at \p State, simply keeping all of the<br>
+  /// input's line breaking decisions.<br>
+  void format(unsigned FirstIndent, const AnnotatedLine *Line) {<br>
+    LineState State =<br>
+        Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false);<br>
+    while (State.NextToken) {<br>
+      bool Newline =<br>
+          Indenter->mustBreak(State) ||<br>
+          (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);<br>
+      Indenter->addTokenToState(State, Newline, /*DryRun=*/false);<br>
+    }<br>
+  }<br>
+<br>
+private:<br>
+  ContinuationIndenter *Indenter;<br>
+};<br>
+<br>
+} // namespace<br>
+<br>
+unsigned<br>
+UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines,<br>
+                               bool DryRun, int AdditionalIndent,<br>
+                               bool FixBadIndentation) {<br>
+  LineJoiner Joiner(Style);<br>
+<br>
+  // Try to look up already computed penalty in DryRun-mode.<br>
+  std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey(<br>
+      &Lines, AdditionalIndent);<br>
+  auto CacheIt = PenaltyCache.find(CacheKey);<br>
+  if (DryRun && CacheIt != PenaltyCache.end())<br>
+    return CacheIt->second;<br>
+<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>
+  const AnnotatedLine *PreviousLine = nullptr;<br>
+  for (SmallVectorImpl<AnnotatedLine *>::const_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>
+    // Determine indent and try to merge multiple unwrapped lines.<br>
+    unsigned Indent;<br>
+    if (TheLine.InPPDirective) {<br>
+      Indent = TheLine.Level * Style.IndentWidth;<br>
+    } else {<br>
+      while (IndentForLevel.size() <= TheLine.Level)<br>
+        IndentForLevel.push_back(-1);<br>
+      IndentForLevel.resize(TheLine.Level + 1);<br>
+      Indent = getIndent(IndentForLevel, TheLine.Level);<br>
+    }<br>
+    unsigned LevelIndent = Indent;<br>
+    if (static_cast<int>(Indent) + Offset >= 0)<br>
+      Indent += Offset;<br>
+<br>
+    // Merge multiple lines if possible.<br>
+    unsigned MergedLines = Joiner.tryFitMultipleLinesInOne(Indent, I, E);<br>
+    if (MergedLines > 0 && Style.ColumnLimit == 0) {<br>
+      // Disallow line merging if there is a break at the start of one of the<br>
+      // input lines.<br>
+      for (unsigned i = 0; i < MergedLines; ++i) {<br>
+        if (I[i + 1]->First->NewlinesBefore > 0)<br>
+          MergedLines = 0;<br>
+      }<br>
+    }<br>
+    if (!DryRun) {<br>
+      for (unsigned i = 0; i < MergedLines; ++i) {<br>
+        join(*I[i], *I[i + 1]);<br>
+      }<br>
+    }<br>
+    I += MergedLines;<br>
+<br>
+    bool FixIndentation =<br>
+        FixBadIndentation && (LevelIndent != FirstTok->OriginalColumn);<br>
+    if (TheLine.First->is(tok::eof)) {<br>
+      if (PreviousLine && PreviousLine->Affected && !DryRun) {<br>
+        // Remove the file's trailing whitespace.<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>
+               (TheLine.Affected || FixIndentation)) {<br>
+      if (FirstTok->WhitespaceRange.isValid()) {<br>
+        if (!DryRun)<br>
+          formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level, Indent,<br>
+                           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>
+          TheLine.Type == LT_ImportStatement) {<br>
+        LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun);<br>
+        while (State.NextToken) {<br>
+          formatChildren(State, /*Newline=*/false, /*DryRun=*/false, Penalty);<br>
+          Indenter->addTokenToState(State, /*Newline=*/false, DryRun);<br>
+        }<br>
+      } else if (Style.ColumnLimit == 0) {<br>
+        // FIXME: Implement nested blocks for 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>
+      if (!TheLine.InPPDirective)<br>
+        IndentForLevel[TheLine.Level] = LevelIndent;<br>
+    } else if (TheLine.ChildrenAffected) {<br>
+      format(TheLine.Children, DryRun);<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; Tok = Tok->Next) {<br>
+        if (Tok == TheLine.First && (Tok->NewlinesBefore > 0 || Tok->IsFirst)) {<br>
+          unsigned LevelIndent = Tok->OriginalColumn;<br>
+          if (!DryRun) {<br>
+            // Remove trailing whitespace of the previous line.<br>
+            if ((PreviousLine && PreviousLine->Affected) ||<br>
+                TheLine.LeadingEmptyLinesAffected) {<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) && !TheLine.InPPDirective)<br>
+            IndentForLevel[TheLine.Level] = LevelIndent;<br>
+        } else if (!DryRun) {<br>
+          Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);<br>
+        }<br>
+      }<br>
+    }<br>
+    if (!DryRun) {<br>
+      for (FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) {<br>
+        Tok->Finalized = true;<br>
+      }<br>
+    }<br>
+    PreviousLine = *I;<br>
+  }<br>
+  PenaltyCache[CacheKey] = Penalty;<br>
+  return Penalty;<br>
+}<br>
+<br>
+unsigned UnwrappedLineFormatter::format(const AnnotatedLine &Line,<br>
+                                        unsigned FirstIndent, 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 (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>
+void UnwrappedLineFormatter::formatFirstToken(FormatToken &RootToken,<br>
+                                              const AnnotatedLine *PreviousLine,<br>
+                                              unsigned IndentLevel,<br>
+                                              unsigned Indent,<br>
+                                              bool InPPDirective) {<br>
+  unsigned Newlines =<br>
+      std::min(RootToken.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1);<br>
+  // Remove empty lines before "}" where applicable.<br>
+  if (RootToken.is(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>
+  if (RootToken.IsFirst && !RootToken.HasUnescapedNewline)<br>
+    Newlines = 0;<br>
+<br>
+  // Remove empty lines after "{".<br>
+  if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&<br>
+      PreviousLine->Last->is(tok::l_brace) &&<br>
+      PreviousLine->First->isNot(tok::kw_namespace) &&<br>
+      !startsExternCBlock(*PreviousLine))<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(RootToken, Newlines, IndentLevel, Indent,<br>
+                                 Indent, InPPDirective &&<br>
+                                             !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 UnwrappedLineFormatter::getIndent(ArrayRef<int> IndentForLevel,<br>
+                                           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>
+void UnwrappedLineFormatter::join(AnnotatedLine &A, const AnnotatedLine &B) {<br>
+  assert(!A.Last->Next);<br>
+  assert(!B.First->Previous);<br>
+  if (B.Affected)<br>
+    A.Affected = true;<br>
+  A.Last->Next = B.First;<br>
+  B.First->Previous = A.Last;<br>
+  B.First->CanBreakBefore = true;<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 UnwrappedLineFormatter::analyzeSolutionSpace(LineState &InitialState,<br>
+                                                      bool DryRun) {<br>
+  std::set<LineState *, CompareLineStatePointers> 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, nullptr);<br>
+  Queue.push(QueueItem(OrderedPenalty(0, Count), Node));<br>
+  ++Count;<br>
+<br>
+  unsigned Penalty = 0;<br>
+<br>
+  // While not empty, take first element and follow edges.<br>
+  while (!Queue.empty()) {<br>
+    Penalty = Queue.top().first.first;<br>
+    StateNode *Node = Queue.top().second;<br>
+    if (!Node->State.NextToken) {<br>
+      DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");<br>
+      break;<br>
+    }<br>
+    Queue.pop();<br>
+<br>
+    // Cut off the analysis of certain solutions if the analysis gets too<br>
+    // complex. See description of IgnoreStackForComparison.<br>
+    if (Count > 10000)<br>
+      Node->State.IgnoreStackForComparison = true;<br>
+<br>
+    if (!Seen.insert(&Node->State).second)<br>
+      // State already examined with lower penalty.<br>
+      continue;<br>
+<br>
+    FormatDecision LastFormat = Node->State.NextToken->Decision;<br>
+    if (LastFormat == FD_Unformatted || LastFormat == FD_Continue)<br>
+      addNextStateToQueue(Penalty, Node, /*NewLine=*/false, &Count, &Queue);<br>
+    if (LastFormat == FD_Unformatted || LastFormat == FD_Break)<br>
+      addNextStateToQueue(Penalty, Node, /*NewLine=*/true, &Count, &Queue);<br>
+  }<br>
+<br>
+  if (Queue.empty()) {<br>
+    // We were unable to find a solution, do nothing.<br>
+    // FIXME: Add diagnostic?<br>
+    DEBUG(llvm::dbgs() << "Could not find a solution.\n");<br>
+    return 0;<br>
+  }<br>
+<br>
+  // Reconstruct the solution.<br>
+  if (!DryRun)<br>
+    reconstructPath(InitialState, Queue.top().second);<br>
+<br>
+  DEBUG(llvm::dbgs() << "Total number of analyzed states: " << Count << "\n");<br>
+  DEBUG(llvm::dbgs() << "---\n");<br>
+<br>
+  return Penalty;<br>
+}<br>
+<br>
+void UnwrappedLineFormatter::reconstructPath(LineState &State,<br>
+                                             StateNode *Current) {<br>
+  std::deque<StateNode *> Path;<br>
+  // We do not need a break before the initial token.<br>
+  while (Current->Previous) {<br>
+    Path.push_front(Current);<br>
+    Current = Current->Previous;<br>
+  }<br>
+  for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();<br>
+       I != E; ++I) {<br>
+    unsigned Penalty = 0;<br>
+    formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty);<br>
+    Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false);<br>
+<br>
+    DEBUG({<br>
+      if ((*I)->NewLine) {<br>
+        llvm::dbgs() << "Penalty for placing "<br>
+                     << (*I)->Previous->State.NextToken->Tok.getName() << ": "<br>
+                     << Penalty << "\n";<br>
+      }<br>
+    });<br>
+  }<br>
+}<br>
+<br>
+void UnwrappedLineFormatter::addNextStateToQueue(unsigned Penalty,<br>
+                                                 StateNode *PreviousNode,<br>
+                                                 bool NewLine, unsigned *Count,<br>
+                                                 QueueType *Queue) {<br>
+  if (NewLine && !Indenter->canBreak(PreviousNode->State))<br>
+    return;<br>
+  if (!NewLine && Indenter->mustBreak(PreviousNode->State))<br>
+    return;<br>
+<br>
+  StateNode *Node = new (Allocator.Allocate())<br>
+      StateNode(PreviousNode->State, NewLine, PreviousNode);<br>
+  if (!formatChildren(Node->State, NewLine, /*DryRun=*/true, Penalty))<br>
+    return;<br>
+<br>
+  Penalty += Indenter->addTokenToState(Node->State, NewLine, true);<br>
+<br>
+  Queue->push(QueueItem(OrderedPenalty(Penalty, *Count), Node));<br>
+  ++(*Count);<br>
+}<br>
+<br>
+bool UnwrappedLineFormatter::formatChildren(LineState &State, bool NewLine,<br>
+                                            bool DryRun, unsigned &Penalty) {<br>
+  FormatToken &Previous = *State.NextToken->Previous;<br>
+  const FormatToken *LBrace = State.NextToken->getPreviousNonComment();<br>
+  if (!LBrace || LBrace->isNot(tok::l_brace) || LBrace->BlockKind != BK_Block ||<br>
+      Previous.Children.size() == 0)<br>
+    // The previous token does not open a block. Nothing to do. We don't<br>
+    // assert so that we can simply call this function for all tokens.<br>
+    return true;<br>
+<br>
+  if (NewLine) {<br>
+    int AdditionalIndent =<br>
+        State.FirstIndent - State.Line->Level * Style.IndentWidth;<br>
+    if (State.Stack.size() < 2 ||<br>
+        !State.Stack[State.Stack.size() - 2].NestedBlockInlined) {<br>
+      AdditionalIndent = State.Stack.back().Indent -<br>
+                         Previous.Children[0]->Level * Style.IndentWidth;<br>
+    }<br>
+<br>
+    Penalty += format(Previous.Children, DryRun, AdditionalIndent,<br>
+                      /*FixBadIndentation=*/true);<br>
+    return true;<br>
+  }<br>
+<br>
+  if (Previous.Children[0]->First->MustBreakBefore)<br>
+    return false;<br>
+<br>
+  // Cannot merge multiple statements into a single line.<br>
+  if (Previous.Children.size() > 1)<br>
+    return false;<br>
+<br>
+  // Cannot merge into one line if this line ends on a comment.<br>
+  if (Previous.is(tok::comment))<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>
+    return false;<br>
+<br>
+  // If the child line exceeds the column limit, we wouldn't want to merge it.<br>
+  // We add +2 for the trailing " }".<br>
+  if (Style.ColumnLimit > 0 &&<br>
+      Previous.Children[0]->Last->TotalLength + State.Column + 2 ><br>
+          Style.ColumnLimit)<br>
+    return false;<br>
+<br>
+  if (!DryRun) {<br>
+    Whitespaces->replaceWhitespace(<br>
+        *Previous.Children[0]->First,<br>
+        /*Newlines=*/0, /*IndentLevel=*/0, /*Spaces=*/1,<br>
+        /*StartOfTokenColumn=*/State.Column, State.Line->InPPDirective);<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>
+} // namespace format<br>
+} // namespace clang<br>
<br>
Added: cfe/trunk/lib/Format/UnwrappedLineFormatter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.h?rev=223936&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.h?rev=223936&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.h (added)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.h Wed Dec 10 13:00:42 2014<br>
@@ -0,0 +1,168 @@<br>
+//===--- UnwrappedLineFormatter.h - Format C++ code -------------*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+///<br>
+/// \file<br>
+/// \brief Implements a combinartorial exploration of all the different<br>
+/// linebreaks unwrapped lines can be formatted in.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H<br>
+#define LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H<br>
+<br>
+#include "ContinuationIndenter.h"<br>
+#include "clang/Format/Format.h"<br>
+#include <map><br>
+#include <queue><br>
+#include <string><br>
+<br>
+namespace clang {<br>
+namespace format {<br>
+<br>
+class ContinuationIndenter;<br>
+class WhitespaceManager;<br>
+<br>
+class UnwrappedLineFormatter {<br>
+public:<br>
+  UnwrappedLineFormatter(ContinuationIndenter *Indenter,<br>
+                         WhitespaceManager *Whitespaces,<br>
+                         const FormatStyle &Style)<br>
+      : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style) {}<br>
+<br>
+  unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,<br>
+                  int AdditionalIndent = 0, bool FixBadIndentation = false);<br>
+<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(const AnnotatedLine &Line, unsigned FirstIndent,<br>
+                  bool DryRun);<br>
+<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>
+    StateNode(const LineState &State, bool NewLine, StateNode *Previous)<br>
+        : State(State), NewLine(NewLine), Previous(Previous) {}<br>
+    LineState State;<br>
+    bool NewLine;<br>
+    StateNode *Previous;<br>
+  };<br>
+<br>
+  /// \brief A pair of <penalty, count> that is used to prioritize the BFS on.<br>
+  ///<br>
+  /// In case of equal penalties, we want to prefer states that were inserted<br>
+  /// first. During state generation we make sure that we insert states first<br>
+  /// that break the line as late as possible.<br>
+  typedef std::pair<unsigned, unsigned> OrderedPenalty;<br>
+<br>
+  /// \brief An item in the prioritized BFS search queue. The \c StateNode's<br>
+  /// \c State has the given \c OrderedPenalty.<br>
+  typedef std::pair<OrderedPenalty, StateNode *> QueueItem;<br>
+<br>
+  /// \brief The BFS queue type.<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 (Style.Language == FormatStyle::LK_Java)<br>
+      return 0;<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>
+<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(ArrayRef<int> IndentForLevel, unsigned Level);<br>
+<br>
+  void join(AnnotatedLine &A, const AnnotatedLine &B);<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>
+  struct CompareLineStatePointers {<br>
+    bool operator()(LineState *obj1, LineState *obj2) const {<br>
+      return *obj1 < *obj2;<br>
+    }<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>
+  /// the solution space (\c LineStates are the nodes). The algorithm tries to<br>
+  /// find the shortest path (the one with lowest penalty) from \p InitialState<br>
+  /// to a state where all tokens are placed. Returns the penalty.<br>
+  ///<br>
+  /// If \p DryRun is \c false, directly applies the changes.<br>
+  unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun = false);<br>
+<br>
+  void reconstructPath(LineState &State, StateNode *Current);<br>
+<br>
+  /// \brief Add the following state to the analysis queue \c Queue.<br>
+  ///<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, unsigned *Count, QueueType *Queue);<br>
+<br>
+  /// \brief If the \p State's next token is an r_brace closing a nested block,<br>
+  /// format the nested block before it.<br>
+  ///<br>
+  /// Returns \c true if all children could be placed successfully and adapts<br>
+  /// \p Penalty as well as \p State. If \p DryRun is false, also directly<br>
+  /// creates changes using \c Whitespaces.<br>
+  ///<br>
+  /// The crucial idea here is that children always get formatted upon<br>
+  /// encountering the closing brace right after the nested block. Now, if we<br>
+  /// are currently trying to keep the "}" on the same line (i.e. \p NewLine is<br>
+  /// \c false), the entire block has to be kept on the same line (which is only<br>
+  /// possible if it fits on the line, only contains a single statement, etc.<br>
+  ///<br>
+  /// If \p NewLine is true, we format the nested block on separate lines, i.e.<br>
+  /// break after the "{", format all lines with correct indentation and the put<br>
+  /// the closing "}" on yet another new line.<br>
+  ///<br>
+  /// This enables us to keep the simple structure of the<br>
+  /// \c UnwrappedLineFormatter, where we only have two options for each token:<br>
+  /// break or don't break.<br>
+  bool formatChildren(LineState &State, bool NewLine, bool DryRun,<br>
+                      unsigned &Penalty);<br>
+<br>
+  ContinuationIndenter *Indenter;<br>
+  WhitespaceManager *Whitespaces;<br>
+  FormatStyle Style;<br>
+<br>
+  llvm::SpecificBumpPtrAllocator<StateNode> Allocator;<br>
+<br>
+  // Cache to store the penalty of formatting a vector of AnnotatedLines<br>
+  // starting from a specific additional offset. Improves performance if there<br>
+  // are many nested blocks.<br>
+  std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,<br>
+           unsigned> PenaltyCache;<br>
+};<br>
+} // end namespace format<br>
+} // end namespace clang<br>
+<br>
+#endif // LLVM_CLANG_LIB_FORMAT_UNWRAPPEDLINEFORMATTER_H<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>