<div dir="ltr">Addressed in r190042.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Sep 5, 2013 at 12:33 PM, Manuel Klimek <span dir="ltr"><<a href="mailto:klimek@google.com" target="_blank">klimek@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="h5">On Thu, Sep 5, 2013 at 11:29 AM, Daniel Jasper <span dir="ltr"><<a href="mailto:djasper@google.com" target="_blank">djasper@google.com</a>></span> wrote:<br>
</div></div><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: djasper<br>
Date: Thu Sep  5 04:29:45 2013<br>
New Revision: 190038<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=190038&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=190038&view=rev</a><br>
Log:<br>
clang-format: Enable formatting of nested blocks.<br>
<br>
Among other things, this enables (better) formatting lambdas and<br>
constructs like:<br>
  MACRO({<br>
          long_statement();<br>
          long_statement_2();<br>
        },<br>
        {<br>
          long_statement();<br>
          long_statement_2();<br>
        },<br>
        { short_statement(); }, "");<br>
<br>
This fixes <a href="http://llvm.org/PR15381" target="_blank">llvm.org/PR15381</a>.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Format/ContinuationIndenter.cpp<br>
    cfe/trunk/lib/Format/ContinuationIndenter.h<br>
    cfe/trunk/lib/Format/Format.cpp<br>
    cfe/trunk/lib/Format/FormatToken.h<br>
    cfe/trunk/lib/Format/TokenAnnotator.cpp<br>
    cfe/trunk/lib/Format/TokenAnnotator.h<br>
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp<br>
    cfe/trunk/lib/Format/UnwrappedLineParser.h<br>
    cfe/trunk/unittests/Format/FormatTest.cpp<br>
<br>
Modified: cfe/trunk/lib/Format/ContinuationIndenter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.cpp?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/ContinuationIndenter.cpp (original)<br>
+++ cfe/trunk/lib/Format/ContinuationIndenter.cpp Thu Sep  5 04:29:45 2013<br>
@@ -55,20 +55,20 @@ static bool startsSegmentOfBuilderTypeCa<br>
<br>
 ContinuationIndenter::ContinuationIndenter(const FormatStyle &Style,<br>
                                            SourceManager &SourceMgr,<br>
-                                           const AnnotatedLine &Line,<br>
-                                           unsigned FirstIndent,<br>
                                            WhitespaceManager &Whitespaces,<br>
                                            encoding::Encoding Encoding,<br>
                                            bool BinPackInconclusiveFunctions)<br>
-    : Style(Style), SourceMgr(SourceMgr), Line(Line), FirstIndent(FirstIndent),<br>
-      Whitespaces(Whitespaces), Encoding(Encoding),<br>
+    : Style(Style), SourceMgr(SourceMgr), Whitespaces(Whitespaces),<br>
+      Encoding(Encoding),<br>
       BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}<br>
<br>
-LineState ContinuationIndenter::getInitialState() {<br>
-  // Initialize state dependent on indent.<br>
+LineState ContinuationIndenter::getInitialState(unsigned FirstIndent,<br>
+                                                const AnnotatedLine *Line) {<br>
   LineState State;<br>
+  State.FirstIndent = FirstIndent;<br>
   State.Column = FirstIndent;<br>
-  State.NextToken = Line.First;<br>
+  State.Line = Line;<br>
+  State.NextToken = Line->First;<br>
   State.Stack.push_back(ParenState(FirstIndent, FirstIndent,<br>
                                    /*AvoidBinPacking=*/false,<br>
                                    /*NoLineBreak=*/false));<br>
@@ -95,7 +95,7 @@ bool ContinuationIndenter::canBreak(cons<br>
   // The opening "{" of a braced list has to be on the same line as the first<br>
   // element if it is nested in another braced init list or function call.<br>
   if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&<br>
-      Previous.Previous &&<br>
+      Previous.BlockKind == BK_BracedInit && Previous.Previous &&<br>
       Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma))<br>
     return false;<br>
   // This prevents breaks like:<br>
@@ -183,8 +183,8 @@ bool ContinuationIndenter::mustBreak(con<br>
     return true;<br>
<br>
   if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&<br>
-      Line.MightBeFunctionDecl && State.Stack.back().BreakBeforeParameter &&<br>
-      State.ParenLevel == 0)<br>
+      State.Line->MightBeFunctionDecl &&<br>
+      State.Stack.back().BreakBeforeParameter && State.ParenLevel == 0)<br>
     return true;<br>
   if (startsSegmentOfBuilderTypeCall(Current) &&<br>
       (State.Stack.back().CallContinuation != 0 ||<br>
@@ -234,10 +234,7 @@ unsigned ContinuationIndenter::addTokenT<br>
       Penalty += Style.PenaltyBreakFirstLessLess;<br>
<br>
     if (Current.is(tok::r_brace)) {<br>
-      if (Current.BlockKind == BK_BracedInit)<br>
-        State.Column = State.Stack[State.Stack.size() - 2].LastSpace;<br>
-      else<br>
-        State.Column = FirstIndent;<br>
+      State.Column = State.Stack[State.Stack.size() - 2].LastSpace;<br>
     } else if (Current.is(tok::string_literal) &&<br>
                State.StartOfStringLiteral != 0) {<br>
       State.Column = State.StartOfStringLiteral;<br>
@@ -261,7 +258,7 @@ unsigned ContinuationIndenter::addTokenT<br>
                  Current.is(tok::kw_operator)) &&<br>
                 State.ParenLevel == 0 &&<br>
                 (!Style.IndentFunctionDeclarationAfterType ||<br>
-                 Line.StartsDefinition))) {<br>
+                 State.Line->StartsDefinition))) {<br>
       State.Column = State.Stack.back().Indent;<br>
     } else if (Current.Type == TT_ObjCSelectorName) {<br>
       if (State.Stack.back().ColonPos > Current.CodePointCount) {<br>
@@ -280,14 +277,15 @@ unsigned ContinuationIndenter::addTokenT<br>
                Previous.Type == TT_ObjCMethodExpr) {<br>
       State.Column = ContinuationIndent;<br>
     } else if (Current.Type == TT_CtorInitializerColon) {<br>
-      State.Column = FirstIndent + Style.ConstructorInitializerIndentWidth;<br>
+      State.Column =<br>
+          State.FirstIndent + Style.ConstructorInitializerIndentWidth;<br>
     } else if (Current.Type == TT_CtorInitializerComma) {<br>
       State.Column = State.Stack.back().Indent;<br>
     } else {<br>
       State.Column = State.Stack.back().Indent;<br>
       // Ensure that we fall back to indenting 4 spaces instead of just<br>
       // flushing continuations left.<br>
-      if (State.Column == FirstIndent)<br>
+      if (State.Column == State.FirstIndent)<br>
         State.Column += 4;<br>
     }<br>
<br>
@@ -306,7 +304,7 @@ unsigned ContinuationIndenter::addTokenT<br>
         NewLines = std::max(NewLines, std::min(Current.NewlinesBefore,<br>
                                                Style.MaxEmptyLinesToKeep + 1));<br>
       Whitespaces.replaceWhitespace(Current, NewLines, State.Column,<br>
-                                    State.Column, Line.InPPDirective);<br>
+                                    State.Column, State.Line->InPPDirective);<br>
     }<br>
<br>
     if (!Current.isTrailingComment())<br>
@@ -337,13 +335,13 @@ unsigned ContinuationIndenter::addTokenT<br>
       if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) ||<br>
             Previous.Type == TT_BinaryOperator) ||<br>
           (!Style.AllowAllParametersOfDeclarationOnNextLine &&<br>
-           Line.MustBeDeclaration))<br>
+           State.Line->MustBeDeclaration))<br>
         State.Stack.back().BreakBeforeParameter = true;<br>
     }<br>
<br>
   } else {<br>
     if (Current.is(tok::equal) &&<br>
-        (Line.First->is(tok::kw_for) || State.ParenLevel == 0) &&<br>
+        (State.Line->First->is(tok::kw_for) || State.ParenLevel == 0) &&<br>
         State.Stack.back().VariablePos == 0) {<br>
       State.Stack.back().VariablePos = State.Column;<br>
       // Move over * and & if they are bound to the variable name.<br>
@@ -403,21 +401,18 @@ unsigned ContinuationIndenter::addTokenT<br>
     else if (Previous.Type == TT_InheritanceColon)<br>
       State.Stack.back().Indent = State.Column;<br>
     else if (Previous.opensScope()) {<br>
-      // If a function has multiple parameters (including a single parameter<br>
-      // that is a binary expression) or a trailing call, indent all<br>
-      // parameters from the opening parenthesis. This avoids confusing<br>
-      // indents like:<br>
-      //   OuterFunction(InnerFunctionCall(<br>
-      //       ParameterToInnerFunction),<br>
-      //                 SecondParameterToOuterFunction);<br>
+      // If a function has a trailing call, indent all parameters from the<br>
+      // opening parenthesis. This avoids confusing indents like:<br>
+      //   OuterFunction(InnerFunctionCall( // break<br>
+      //       ParameterToInnerFunction))   // break<br>
+      //       .SecondInnerFunctionCall();<br>
       bool HasTrailingCall = false;<br>
       if (Previous.MatchingParen) {<br>
         const FormatToken *Next = Previous.MatchingParen->getNextNonComment();<br>
         HasTrailingCall = Next && Next->isMemberAccess();<br>
       }<br>
-      if (startsBinaryExpression(Current) ||<br>
-          (HasTrailingCall &&<br>
-           State.Stack[State.Stack.size() - 2].CallContinuation == 0))<br>
+      if (HasTrailingCall &&<br>
+          State.Stack[State.Stack.size() - 2].CallContinuation == 0)<br>
         State.Stack.back().LastSpace = State.Column;<br>
     }<br>
   }<br>
@@ -434,7 +429,7 @@ unsigned ContinuationIndenter::moveState<br>
     State.Stack.back().AvoidBinPacking = true;<br>
   if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)<br>
     State.Stack.back().FirstLessLess = State.Column;<br>
-  if (Current.is(tok::l_square) &&<br>
+  if (Current.is(tok::l_square) && Current.Type != TT_LambdaLSquare &&<br>
       State.Stack.back().StartOfArraySubscripts == 0)<br>
     State.Stack.back().StartOfArraySubscripts = State.Column;<br>
   if (Current.is(tok::question))<br>
@@ -485,6 +480,14 @@ unsigned ContinuationIndenter::moveState<br>
     NewParenState.Indent =<br>
         std::max(std::max(State.Column, NewParenState.Indent),<br>
                  State.Stack.back().LastSpace);<br>
+    // Do not indent relative to the fake parentheses inserted for "." or "->".<br>
+    // This is a special case to make the following to statements consistent:<br>
+    //   OuterFunction(InnerFunctionCall( // break<br>
+    //       ParameterToInnerFunction));<br>
+    //   OuterFunction(SomeObject.InnerFunctionCall( // break<br>
+    //       ParameterToInnerFunction));<br>
+    if (*I > prec::Unknown)<br>
+      NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);<br>
<br>
     // Always indent conditional expressions. Never indent expression where<br>
     // the 'operator' is ',', ';' or an assignment (i.e. *I <=<br>
@@ -504,17 +507,22 @@ unsigned ContinuationIndenter::moveState<br>
   // prepare for the following tokens.<br>
   if (Current.opensScope()) {<br>
     unsigned NewIndent;<br>
-    unsigned LastSpace = State.Stack.back().LastSpace;<br>
     bool AvoidBinPacking;<br>
     if (Current.is(tok::l_brace)) {<br>
-      NewIndent =<br>
-          LastSpace + (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);<br>
+      if (Current.MatchingParen && Current.BlockKind == BK_Block) {<br>
+        for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i)<br>
+          State.Stack.pop_back();<br></blockquote><div><br></div></div></div><div>Can you please add a comment why this is ok / necessary here :)</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


+        NewIndent = State.Stack.back().LastSpace;<br>
+      } else {<br>
+        NewIndent = State.Stack.back().LastSpace +<br>
+                    (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);<br>
+      }<br>
       const FormatToken *NextNoComment = Current.getNextNonComment();<br>
       AvoidBinPacking = NextNoComment &&<br>
                         NextNoComment->Type == TT_DesignatedInitializerPeriod;<br>
     } else {<br>
-      NewIndent =<br>
-          4 + std::max(LastSpace, State.Stack.back().StartOfFunctionCall);<br>
+      NewIndent = 4 + std::max(State.Stack.back().LastSpace,<br>
+                               State.Stack.back().StartOfFunctionCall);<br>
       AvoidBinPacking = !Style.BinPackParameters ||<br>
                         (Style.ExperimentalAutoDetectBinPacking &&<br>
                          (Current.PackingKind == PPK_OnePerLine ||<br>
@@ -522,7 +530,8 @@ unsigned ContinuationIndenter::moveState<br>
                            Current.PackingKind == PPK_Inconclusive)));<br>
     }<br>
<br>
-    State.Stack.push_back(ParenState(NewIndent, LastSpace, AvoidBinPacking,<br>
+    State.Stack.push_back(ParenState(NewIndent, State.Stack.back().LastSpace,<br>
+                                     AvoidBinPacking,<br>
                                      State.Stack.back().NoLineBreak));<br>
     ++State.ParenLevel;<br>
   }<br>
@@ -531,7 +540,8 @@ unsigned ContinuationIndenter::moveState<br>
   // one line and put one per line if they don't.<br>
   if (Current.is(tok::l_square) && Current.Type == TT_ObjCMethodExpr &&<br>
       Current.MatchingParen != NULL) {<br>
-    if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())<br>
+    if (getLengthToMatchingParen(Current) + State.Column ><br>
+        getColumnLimit(State))<br>
       State.Stack.back().BreakBeforeParameter = true;<br>
   }<br>
<br>
@@ -539,7 +549,7 @@ unsigned ContinuationIndenter::moveState<br>
   // stacks.<br>
   if (State.Stack.size() > 1 &&<br>
       (Current.isOneOf(tok::r_paren, tok::r_square) ||<br>
-       (Current.is(tok::r_brace) && State.NextToken != Line.First) ||<br>
+       (Current.is(tok::r_brace) && State.NextToken != State.Line->First) ||<br>
        State.NextToken->Type == TT_TemplateCloser)) {<br>
     State.Stack.pop_back();<br>
     --State.ParenLevel;<br>
@@ -552,10 +562,13 @@ unsigned ContinuationIndenter::moveState<br>
   }<br>
<br>
   // Remove scopes created by fake parenthesis.<br>
-  for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {<br>
-    unsigned VariablePos = State.Stack.back().VariablePos;<br>
-    State.Stack.pop_back();<br>
-    State.Stack.back().VariablePos = VariablePos;<br>
+  if (Current.isNot(tok::r_brace) ||<br>
+      (Current.MatchingParen && Current.MatchingParen->BlockKind != BK_Block)) {<br>
+    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {<br>
+      unsigned VariablePos = State.Stack.back().VariablePos;<br>
+      State.Stack.pop_back();<br>
+      State.Stack.back().VariablePos = VariablePos;<br>
+    }<br>
   }<br>
<br>
   if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) {<br>
@@ -568,6 +581,10 @@ unsigned ContinuationIndenter::moveState<br>
   State.Column += Current.CodePointCount;<br>
   State.NextToken = State.NextToken->Next;<br>
   unsigned Penalty = breakProtrudingToken(Current, State, DryRun);<br>
+  if (State.Column > getColumnLimit(State)) {<br>
+    unsigned ExcessCharacters = State.Column - getColumnLimit(State);<br>
+    Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;<br>
+  }<br>
<br>
   // If the previous has a special role, let it consume tokens as appropriate.<br>
   // It is necessary to start at the previous token for the only implemented<br>
@@ -593,8 +610,8 @@ ContinuationIndenter::addMultilineString<br>
   // for all other lines is constant, and we ignore it.<br>
   State.Column = Current.CodePointsInLastLine;<br>
<br>
-  if (ColumnsUsed > getColumnLimit())<br>
-    return Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit());<br>
+  if (ColumnsUsed > getColumnLimit(State))<br>
+    return Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit(State));<br>
   return 0;<br>
 }<br>
<br>
@@ -623,15 +640,15 @@ unsigned ContinuationIndenter::breakProt<br>
     if (Current.IsUnterminatedLiteral)<br>
       return 0;<br>
<br>
-    Token.reset(new BreakableStringLiteral(Current, StartColumn,<br>
-                                           Line.InPPDirective, Encoding));<br>
+    Token.reset(new BreakableStringLiteral(<br>
+        Current, StartColumn, State.Line->InPPDirective, Encoding));<br>
   } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {<br>
     unsigned OriginalStartColumn =<br>
         SourceMgr.getSpellingColumnNumber(Current.getStartOfNonWhitespace()) -<br>
         1;<br>
     Token.reset(new BreakableBlockComment(<br>
         Style, Current, StartColumn, OriginalStartColumn, !Current.Previous,<br>
-        Line.InPPDirective, Encoding));<br>
+        State.Line->InPPDirective, Encoding));<br>
   } else if (Current.Type == TT_LineComment &&<br>
              (Current.Previous == NULL ||<br>
               Current.Previous->Type != TT_ImplicitStringLiteral)) {<br>
@@ -648,14 +665,15 @@ unsigned ContinuationIndenter::breakProt<br>
     }<br>
<br>
     Token.reset(new BreakableLineComment(Current, StartColumn,<br>
-                                         Line.InPPDirective, Encoding));<br>
+                                         State.Line->InPPDirective, Encoding));<br>
   } else {<br>
     return 0;<br>
   }<br>
-  if (Current.UnbreakableTailLength >= getColumnLimit())<br>
+  if (Current.UnbreakableTailLength >= getColumnLimit(State))<br>
     return 0;<br>
<br>
-  unsigned RemainingSpace = getColumnLimit() - Current.UnbreakableTailLength;<br>
+  unsigned RemainingSpace =<br>
+      getColumnLimit(State) - Current.UnbreakableTailLength;<br>
   bool BreakInserted = false;<br>
   unsigned Penalty = 0;<br>
   unsigned RemainingTokenColumns = 0;<br>
@@ -668,7 +686,7 @@ unsigned ContinuationIndenter::breakProt<br>
         Token->getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);<br>
     while (RemainingTokenColumns > RemainingSpace) {<br>
       BreakableToken::Split Split =<br>
-          Token->getSplit(LineIndex, TailOffset, getColumnLimit());<br>
+          Token->getSplit(LineIndex, TailOffset, getColumnLimit(State));<br>
       if (Split.first == StringRef::npos) {<br>
         // The last line's penalty is handled in addNextStateToQueue().<br>
         if (LineIndex < EndIndex - 1)<br>
@@ -685,9 +703,9 @@ unsigned ContinuationIndenter::breakProt<br>
       Penalty += Current.SplitPenalty;<br>
       unsigned ColumnsUsed =<br>
           Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);<br>
-      if (ColumnsUsed > getColumnLimit()) {<br>
-        Penalty +=<br>
-            Style.PenaltyExcessCharacter * (ColumnsUsed - getColumnLimit());<br>
+      if (ColumnsUsed > getColumnLimit(State)) {<br>
+        Penalty += Style.PenaltyExcessCharacter *<br>
+                   (ColumnsUsed - getColumnLimit(State));<br>
       }<br>
       TailOffset += Split.first + Split.second;<br>
       RemainingTokenColumns = NewRemainingTokenColumns;<br>
@@ -714,9 +732,9 @@ unsigned ContinuationIndenter::breakProt<br>
   return Penalty;<br>
 }<br>
<br>
-unsigned ContinuationIndenter::getColumnLimit() const {<br>
+unsigned ContinuationIndenter::getColumnLimit(const LineState &State) const {<br>
   // In preprocessor directives reserve two chars for trailing " \"<br>
-  return Style.ColumnLimit - (Line.InPPDirective ? 2 : 0);<br>
+  return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);<br>
 }<br>
<br>
 bool ContinuationIndenter::NextIsMultilineString(const LineState &State) {<br>
<br>
Modified: cfe/trunk/lib/Format/ContinuationIndenter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.h?rev=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/ContinuationIndenter.h?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/ContinuationIndenter.h (original)<br>
+++ cfe/trunk/lib/Format/ContinuationIndenter.h Thu Sep  5 04:29:45 2013<br>
@@ -35,14 +35,13 @@ public:<br>
   /// \brief Constructs a \c ContinuationIndenter to format \p Line starting in<br>
   /// column \p FirstIndent.<br>
   ContinuationIndenter(const FormatStyle &Style, SourceManager &SourceMgr,<br>
-                       const AnnotatedLine &Line, unsigned FirstIndent,<br>
                        WhitespaceManager &Whitespaces,<br>
                        encoding::Encoding Encoding,<br>
                        bool BinPackInconclusiveFunctions);<br>
<br>
-  /// \brief Get the initial state, i.e. the state after placing the line's<br>
-  /// first token.<br>
-  LineState getInitialState();<br>
+  /// \brief Get the initial state, i.e. the state after placing \p Line's<br>
+  /// first token at \p FirstIndent.<br>
+  LineState getInitialState(unsigned FirstIndent, const AnnotatedLine *Line);<br>
<br>
   // FIXME: canBreak and mustBreak aren't strictly indentation-related. Find a<br>
   // better home.<br>
@@ -65,7 +64,7 @@ public:<br>
<br>
   /// \brief Get the column limit for this line. This is the style's column<br>
   /// limit, potentially reduced for preprocessor definitions.<br>
-  unsigned getColumnLimit() const;<br>
+  unsigned getColumnLimit(const LineState &State) const;<br>
<br>
 private:<br>
   /// \brief Mark the next token as consumed in \p State and modify its stacks<br>
@@ -101,8 +100,6 @@ private:<br>
<br>
   FormatStyle Style;<br>
   SourceManager &SourceMgr;<br>
-  const AnnotatedLine &Line;<br>
-  const unsigned FirstIndent;<br>
   WhitespaceManager &Whitespaces;<br>
   encoding::Encoding Encoding;<br>
   bool BinPackInconclusiveFunctions;<br>
@@ -271,6 +268,14 @@ struct LineState {<br>
   /// FIXME: Come up with a better algorithm instead.<br>
   bool IgnoreStackForComparison;<br>
<br>
+  /// \brief The indent of the first token.<br>
+  unsigned FirstIndent;<br>
+<br>
+  /// \brief The line that is being formatted.<br>
+  ///<br>
+  /// Does not need to be considered for memoization because it doesn't change.<br>
+  const AnnotatedLine *Line;<br>
+<br>
   /// \brief Comparison operator to be able to used \c LineState in \c map.<br>
   bool operator<(const LineState &Other) const {<br>
     if (NextToken != Other.NextToken)<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=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/Format.cpp (original)<br>
+++ cfe/trunk/lib/Format/Format.cpp Thu Sep  5 04:29:45 2013<br>
@@ -324,8 +324,8 @@ public:<br>
<br>
   /// \brief Formats the line starting at \p State, simply keeping all of the<br>
   /// input's line breaking decisions.<br>
-  void format() {<br>
-    LineState State = Indenter->getInitialState();<br>
+  void format(unsigned FirstIndent, const AnnotatedLine *Line) {<br>
+    LineState State = Indenter->getInitialState(FirstIndent, Line);<br>
     while (State.NextToken != NULL) {<br>
       bool Newline =<br>
           Indenter->mustBreak(State) ||<br>
@@ -341,12 +341,16 @@ private:<br>
 class UnwrappedLineFormatter {<br>
 public:<br>
   UnwrappedLineFormatter(ContinuationIndenter *Indenter,<br>
+                         WhitespaceManager *Whitespaces,<br>
                          const FormatStyle &Style, const AnnotatedLine &Line)<br>
-      : Indenter(Indenter), Style(Style), Line(Line), Count(0) {}<br>
+      : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), Line(Line),<br>
+        Count(0) {}<br>
<br>
-  /// \brief Formats an \c UnwrappedLine.<br>
-  void format() {<br>
-    LineState State = Indenter->getInitialState();<br>
+  /// \brief Formats an \c UnwrappedLine 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>
+    LineState State = Indenter->getInitialState(FirstIndent, &Line);<br>
<br>
     // If the ObjC method declaration does not fit on a line, we should format<br>
     // it with one arg per line.<br>
@@ -354,7 +358,7 @@ public:<br>
       State.Stack.back().BreakBeforeParameter = true;<br>
<br>
     // Find best solution in solution space.<br>
-    analyzeSolutionSpace(State);<br>
+    return analyzeSolutionSpace(State, DryRun);<br>
   }<br>
<br>
 private:<br>
@@ -388,8 +392,10 @@ private:<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.<br>
-  void analyzeSolutionSpace(LineState &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> Seen;<br>
<br>
     // Insert start element into queue.<br>
@@ -398,9 +404,11 @@ private:<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>
-      unsigned Penalty = Queue.top().first.first;<br>
+      Penalty = Queue.top().first.first;<br>
       StateNode *Node = Queue.top().second;<br>
       if (Node->State.NextToken == NULL) {<br>
         DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");<br>
@@ -424,12 +432,16 @@ private:<br>
     if (Queue.empty())<br>
       // We were unable to find a solution, do nothing.<br>
       // FIXME: Add diagnostic?<br>
-      return;<br>
+      return 0;<br>
<br>
     // Reconstruct the solution.<br>
-    reconstructPath(InitialState, Queue.top().second);<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>
@@ -441,8 +453,10 @@ private:<br>
     }<br>
     for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();<br>
          I != E; ++I) {<br>
-      unsigned Penalty = Indenter->addTokenToState(State, (*I)->NewLine, false);<br>
-      (void)Penalty;<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>
@@ -466,18 +480,80 @@ private:<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>
-    if (Node->State.Column > Indenter->getColumnLimit()) {<br>
-      unsigned ExcessCharacters =<br>
-          Node->State.Column - Indenter->getColumnLimit();<br>
-      Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;<br>
-    }<br>
<br>
     Queue.push(QueueItem(OrderedPenalty(Penalty, Count), Node));<br>
     ++Count;<br>
   }<br>
<br>
+  /// \brief Format all children of \p Tok assuming the parent is indented to<br>
+  /// \p ParentIndent.<br></blockquote><div><br></div></div></div><div>ParentIndent is not a parameter...</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+  ///<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>
+    const FormatToken &LBrace = *State.NextToken->Previous;<br>
+    if (LBrace.isNot(tok::l_brace) || LBrace.BlockKind != BK_Block ||<br>
+        LBrace.Children.size() == 0)<br>
+      return true; // The previous token does not open a block. Nothing to do.<br></blockquote><div><br></div></div><div>Why's that not an assert?</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


+<br>
+    if (NewLine) {<br>
+      unsigned ParentIndent = State.Stack.back().Indent;<br>
+      for (SmallVector<AnnotatedLine *, 1>::const_iterator<br>
+               I = LBrace.Children.begin(),<br>
+               E = LBrace.Children.end();<br>
+           I != E; ++I) {<br>
+        unsigned Indent =<br>
+            ParentIndent + ((*I)->Level - Line.Level) * Style.IndentWidth;<br>
+        if (!DryRun)<br>
+          Whitespaces->replaceWhitespace(<br>
+              *(*I)->First, /*Newlines=*/1, /*Spaces=*/Indent,<br>
+              /*StartOfTokenColumn=*/Indent, Line.InPPDirective);<br>
+        UnwrappedLineFormatter Formatter(Indenter, Whitespaces, Style, **I);<br>
+        Penalty += Formatter.format(Indent, DryRun);<br>
+      }<br>
+      return true;<br>
+    }<br>
+<br>
+    if (LBrace.Children.size() > 1)<br>
+      return false; // Cannot merge multiple statements into a single line.<br>
+<br>
+    // We can't put the closing "}" on a line with a trailing comment.<br>
+    if (LBrace.Children[0]->Last->isTrailingComment())<br>
+      return false;<br>
+<br>
+    if (!DryRun) {<br>
+      Whitespaces->replaceWhitespace(*LBrace.Children[0]->First,<br>
+                                     /*Newlines=*/0, /*Spaces=*/1,<br>
+                                     /*StartOfTokenColumn=*/State.Column,<br>
+                                     State.Line->InPPDirective);<br>
+    }<br>
+<br>
+    State.Column += 1 + LBrace.Children[0]->Last->TotalLength;<br>
+    return true;<br>
+  }<br>
+<br>
   ContinuationIndenter *Indenter;<br>
+  WhitespaceManager *Whitespaces;<br>
   FormatStyle Style;<br>
   const AnnotatedLine &Line;<br>
<br>
@@ -654,7 +730,12 @@ public:<br>
                        << "\n");<br>
   }<br>
<br>
-  virtual ~Formatter() {}<br>
+  virtual ~Formatter() {<br>
+    for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>
+      delete AnnotatedLines[i];<br>
+    }<br>
+    AnnotatedLines.clear();<br></blockquote><div><br></div></div></div><div>I would not do the clear(), as the object is not reachable afterwards...</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


+  }<br>
<br>
   tooling::Replacements format() {<br>
     FormatTokenLexer Tokens(Lex, SourceMgr, Style, Encoding);<br>
@@ -663,23 +744,23 @@ public:<br>
     bool StructuralError = Parser.parse();<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>
+      Annotator.annotate(*AnnotatedLines[i]);<br>
     }<br>
     deriveLocalStyle();<br>
     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>
-      Annotator.calculateFormattingInformation(AnnotatedLines[i]);<br>
+      Annotator.calculateFormattingInformation(*AnnotatedLines[i]);<br>
     }<br>
<br>
     // Adapt level to the next line if this is a comment.<br>
     // FIXME: Can/should this be done in the UnwrappedLineParser?<br>
     const AnnotatedLine *NextNonCommentLine = NULL;<br>
     for (unsigned i = AnnotatedLines.size() - 1; i > 0; --i) {<br>
-      if (NextNonCommentLine && AnnotatedLines[i].First->is(tok::comment) &&<br>
-          !AnnotatedLines[i].First->Next)<br>
-        AnnotatedLines[i].Level = NextNonCommentLine->Level;<br>
+      if (NextNonCommentLine && AnnotatedLines[i]->First->is(tok::comment) &&<br>
+          !AnnotatedLines[i]->First->Next)<br>
+        AnnotatedLines[i]->Level = NextNonCommentLine->Level;<br>
       else<br>
-        NextNonCommentLine = AnnotatedLines[i].First->isNot(tok::r_brace)<br>
-                                 ? &AnnotatedLines[i]<br>
+        NextNonCommentLine = AnnotatedLines[i]->First->isNot(tok::r_brace)<br>
+                                 ? AnnotatedLines[i]<br>
                                  : NULL;<br>
     }<br>
<br>
@@ -687,10 +768,10 @@ public:<br>
     bool PreviousLineWasTouched = false;<br>
     const FormatToken *PreviousLineLastToken = 0;<br>
     bool FormatPPDirective = false;<br>
-    for (std::vector<AnnotatedLine>::iterator I = AnnotatedLines.begin(),<br>
-                                              E = AnnotatedLines.end();<br>
+    for (std::vector<AnnotatedLine *>::iterator I = AnnotatedLines.begin(),<br>
+                                                E = AnnotatedLines.end();<br>
          I != E; ++I) {<br>
-      const AnnotatedLine &TheLine = *I;<br>
+      const AnnotatedLine &TheLine = **I;<br>
       const FormatToken *FirstTok = TheLine.First;<br>
       int Offset = getIndentOffset(*TheLine.First);<br>
<br>
@@ -729,26 +810,27 @@ public:<br>
         } else {<br>
           Indent = LevelIndent = FirstTok->OriginalColumn;<br>
         }<br>
-        ContinuationIndenter Indenter(Style, SourceMgr, TheLine, Indent,<br>
-                                      Whitespaces, Encoding,<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>
-        if ((I + 1) != E && (I + 1)->InPPDirective &&<br>
-            !(I + 1)->First->HasUnescapedNewline)<br>
-          ColumnLimit = Indenter.getColumnLimit();<br>
+        AnnotatedLine *NextLine = *(I + 1);<br>
+        if ((I + 1) != E && NextLine->InPPDirective &&<br>
+            !NextLine->First->HasUnescapedNewline)<br>
+          ColumnLimit = getColumnLimit(TheLine.InPPDirective);<br>
<br>
-        if (I->Last->TotalLength + Indent <= ColumnLimit) {<br>
-          LineState State = Indenter.getInitialState();<br>
+        if (TheLine.Last->TotalLength + Indent <= ColumnLimit) {<br>
+          LineState State = Indenter.getInitialState(Indent, &TheLine);<br>
           while (State.NextToken != NULL)<br>
             Indenter.addTokenToState(State, false, false);<br>
         } else if (Style.ColumnLimit == 0) {<br>
           NoColumnLimitFormatter Formatter(&Indenter);<br>
-          Formatter.format();<br>
+          Formatter.format(Indent, &TheLine);<br>
         } else {<br>
-          UnwrappedLineFormatter Formatter(&Indenter, Style, TheLine);<br>
-          Formatter.format();<br>
+          UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style,<br>
+                                           TheLine);<br>
+          Formatter.format(Indent);<br>
         }<br>
<br>
         IndentForLevel[TheLine.Level] = LevelIndent;<br>
@@ -783,7 +865,7 @@ public:<br>
         // last token.<br>
         PreviousLineWasTouched = false;<br>
       }<br>
-      PreviousLineLastToken = I->Last;<br>
+      PreviousLineLastToken = TheLine.Last;<br>
     }<br>
     return Whitespaces.generateReplacements();<br>
   }<br>
@@ -796,9 +878,9 @@ private:<br>
     bool HasBinPackedFunction = false;<br>
     bool HasOnePerLineFunction = false;<br>
     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {<br>
-      if (!AnnotatedLines[i].First->Next)<br>
+      if (!AnnotatedLines[i]->First->Next)<br>
         continue;<br>
-      FormatToken *Tok = AnnotatedLines[i].First->Next;<br>
+      FormatToken *Tok = AnnotatedLines[i]->First->Next;<br>
       while (Tok->Next) {<br>
         if (Tok->Type == TT_PointerOrReference) {<br>
           bool SpacesBefore =<br>
@@ -866,10 +948,11 @@ private:<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>
-                                std::vector<AnnotatedLine>::iterator &I,<br>
-                                std::vector<AnnotatedLine>::iterator E) {<br>
+                                std::vector<AnnotatedLine *>::iterator &I,<br>
+                                std::vector<AnnotatedLine *>::iterator E) {<br>
     // We can never merge stuff if there are trailing line comments.<br>
-    if (I->Last->Type == TT_LineComment)<br>
+    AnnotatedLine *TheLine = *I;<br>
+    if (TheLine->Last->Type == TT_LineComment)<br>
       return;<br>
<br>
     if (Indent > Style.ColumnLimit)<br>
@@ -878,70 +961,72 @@ private:<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 = I->Last->TotalLength > Limit ? 0 : Limit - I->Last->TotalLength;<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>
+    if (I + 1 == E || (*(I + 1))->Type == LT_Invalid)<br>
       return;<br>
<br>
-    if (I->Last->is(tok::l_brace)) {<br>
+    if (TheLine->Last->is(tok::l_brace)) {<br>
       tryMergeSimpleBlock(I, E, Limit);<br>
     } else if (Style.AllowShortIfStatementsOnASingleLine &&<br>
-               I->First->is(tok::kw_if)) {<br>
+               TheLine->First->is(tok::kw_if)) {<br>
       tryMergeSimpleControlStatement(I, E, Limit);<br>
     } else if (Style.AllowShortLoopsOnASingleLine &&<br>
-               I->First->isOneOf(tok::kw_for, tok::kw_while)) {<br>
+               TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {<br>
       tryMergeSimpleControlStatement(I, E, Limit);<br>
-    } else if (I->InPPDirective &&<br>
-               (I->First->HasUnescapedNewline || I->First->IsFirst)) {<br>
+    } else if (TheLine->InPPDirective && (TheLine->First->HasUnescapedNewline ||<br>
+                                          TheLine->First->IsFirst)) {<br>
       tryMergeSimplePPDirective(I, E, Limit);<br>
     }<br>
   }<br>
<br>
-  void tryMergeSimplePPDirective(std::vector<AnnotatedLine>::iterator &I,<br>
-                                 std::vector<AnnotatedLine>::iterator E,<br>
+  void tryMergeSimplePPDirective(std::vector<AnnotatedLine *>::iterator &I,<br>
+                                 std::vector<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>
+    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>
+    if (I + 2 != E && (*(I + 2))->InPPDirective &&<br>
+        !(*(I + 2))->First->HasUnescapedNewline)<br>
       return;<br>
-    if (1 + (I + 1)->Last->TotalLength > Limit)<br>
+    if (1 + (*(I + 1))->Last->TotalLength > Limit)<br>
       return;<br>
-    join(Line, *(++I));<br>
+    join(Line, **(++I));<br>
   }<br>
<br>
-  void tryMergeSimpleControlStatement(std::vector<AnnotatedLine>::iterator &I,<br>
-                                      std::vector<AnnotatedLine>::iterator E,<br>
+  void tryMergeSimpleControlStatement(std::vector<AnnotatedLine *>::iterator &I,<br>
+                                      std::vector<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>
+        (*(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>
+    if ((*(I + 1))->InPPDirective != (*I)->InPPDirective ||<br>
+        ((*(I + 1))->InPPDirective && (*(I + 1))->First->HasUnescapedNewline))<br>
       return;<br>
-    AnnotatedLine &Line = *I;<br>
+    AnnotatedLine &Line = **I;<br>
     if (Line.Last->isNot(tok::r_paren))<br>
       return;<br>
-    if (1 + (I + 1)->Last->TotalLength > Limit)<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>
+    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>
+        (*(I + 2))->First->is(tok::kw_else))<br>
       return;<br>
-    join(Line, *(++I));<br>
+    join(Line, **(++I));<br>
   }<br>
<br>
-  void tryMergeSimpleBlock(std::vector<AnnotatedLine>::iterator &I,<br>
-                           std::vector<AnnotatedLine>::iterator E,<br>
+  void tryMergeSimpleBlock(std::vector<AnnotatedLine *>::iterator &I,<br>
+                           std::vector<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>
@@ -950,7 +1035,7 @@ private:<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>
+    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>
@@ -958,24 +1043,24 @@ private:<br>
                             tok::at, tok::minus, tok::plus))<br>
       return;<br>
<br>
-    FormatToken *Tok = (I + 1)->First;<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>
+      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>
+      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>
+      if ((*(I + 1))->Last->Type == TT_LineComment || Tok->MustBreakBefore)<br>
         return;<br>
       do {<br>
         if (Tok->isOneOf(tok::l_brace, tok::r_brace))<br>
@@ -984,20 +1069,21 @@ private:<br>
       } while (Tok != NULL);<br>
<br>
       // Last, check that the third line contains a single closing brace.<br>
-      Tok = (I + 2)->First;<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>
+      join(Line, **(I + 1));<br>
+      join(Line, **(I + 2));<br>
       I += 2;<br>
     }<br>
   }<br>
<br>
-  bool nextTwoLinesFitInto(std::vector<AnnotatedLine>::iterator I,<br>
+  bool nextTwoLinesFitInto(std::vector<AnnotatedLine *>::iterator I,<br>
                            unsigned Limit) {<br>
-    return 1 + (I + 1)->Last->TotalLength + 1 + (I + 2)->Last->TotalLength <=<br>
+    return 1 + (*(I + 1))->Last->TotalLength + 1 +<br>
+               (*(I + 2))->Last->TotalLength <=<br>
            Limit;<br>
   }<br>
<br>
@@ -1034,12 +1120,12 @@ private:<br>
     return touchesRanges(LineRange);<br>
   }<br>
<br>
-  bool touchesPPDirective(std::vector<AnnotatedLine>::iterator I,<br>
-                          std::vector<AnnotatedLine>::iterator E) {<br>
+  bool touchesPPDirective(std::vector<AnnotatedLine *>::iterator I,<br>
+                          std::vector<AnnotatedLine *>::iterator E) {<br>
     for (; I != E; ++I) {<br>
-      if (I->First->HasUnescapedNewline)<br>
+      if ((*I)->First->HasUnescapedNewline)<br>
         return false;<br>
-      if (touchesLine(*I))<br>
+      if (touchesLine(**I))<br>
         return true;<br>
     }<br>
     return false;<br>
@@ -1055,7 +1141,7 @@ private:<br>
   }<br>
<br>
   virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) {<br>
-    AnnotatedLines.push_back(AnnotatedLine(TheLine));<br>
+    AnnotatedLines.push_back(new AnnotatedLine(TheLine));<br>
   }<br>
<br>
   /// \brief Add a new line and the required indent before the first Token<br>
@@ -1084,12 +1170,17 @@ private:<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>
-  std::vector<AnnotatedLine> AnnotatedLines;<br>
+  std::vector<AnnotatedLine *> AnnotatedLines;<br>
<br>
   encoding::Encoding Encoding;<br>
   bool BinPackInconclusiveFunctions;<br>
<br>
Modified: cfe/trunk/lib/Format/FormatToken.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/FormatToken.h (original)<br>
+++ cfe/trunk/lib/Format/FormatToken.h Thu Sep  5 04:29:45 2013<br>
@@ -36,6 +36,7 @@ enum TokenType {<br>
   TT_InlineASMColon,<br>
   TT_InheritanceColon,<br>
   TT_FunctionTypeLParen,<br>
+  TT_LambdaLSquare,<br>
   TT_LineComment,<br>
   TT_ObjCArrayLiteral,<br>
   TT_ObjCBlockLParen,<br>
@@ -75,6 +76,7 @@ enum ParameterPackingKind {<br>
 };<br>
<br>
 class TokenRole;<br>
+class AnnotatedLine;<br>
<br>
 /// \brief A wrapper around a \c Token storing information about the<br>
 /// whitespace characters preceeding it.<br>
@@ -335,6 +337,8 @@ struct FormatToken {<br>
   FormatToken *Previous;<br>
   FormatToken *Next;<br>
<br>
+  SmallVector<AnnotatedLine *, 1> Children;<br>
+<br>
 private:<br>
   // Disallow copying.<br>
   FormatToken(const FormatToken &) LLVM_DELETED_FUNCTION;<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=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)<br>
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Thu Sep  5 04:29:45 2013<br>
@@ -182,7 +182,7 @@ private:<br>
     FormatToken *Left = CurrentToken->Previous;<br>
     FormatToken *Parent = Left->getPreviousNonComment();<br>
     bool StartsObjCMethodExpr =<br>
-        Contexts.back().CanBeExpression &&<br>
+        Contexts.back().CanBeExpression && Left->Type != TT_LambdaLSquare &&<br>
         (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,<br>
                                     tok::kw_return, tok::kw_throw) ||<br>
          Parent->isUnaryOperator() || Parent->Type == TT_ObjCForIn ||<br>
@@ -522,7 +522,7 @@ private:<br>
<br>
     // Reset token type in case we have already looked at it and then recovered<br>
     // from an error (e.g. failure to find the matching >).<br>
-    if (CurrentToken != NULL)<br>
+    if (CurrentToken != NULL && CurrentToken->Type != TT_LambdaLSquare)<br>
       CurrentToken->Type = TT_Unknown;<br>
   }<br>
<br>
@@ -974,6 +974,11 @@ private:<br>
 } // end anonymous namespace<br>
<br>
 void TokenAnnotator::annotate(AnnotatedLine &Line) {<br>
+  for (std::vector<AnnotatedLine *>::iterator I = Line.Children.begin(),<br>
+                                              E = Line.Children.end();<br>
+       I != E; ++I) {<br>
+    annotate(**I);<br>
+  }<br>
   AnnotatingParser Parser(Style, Line, Ident_in);<br>
   Line.Type = Parser.parseLine();<br>
   if (Line.Type == LT_Invalid)<br>
@@ -1026,7 +1031,7 @@ void TokenAnnotator::calculateFormatting<br>
     }<br>
     Current->CanBreakBefore =<br>
         Current->MustBreakBefore || canBreakBefore(Line, *Current);<br>
-    if (Current->MustBreakBefore ||<br>
+    if (Current->MustBreakBefore || !Current->Children.empty() ||<br>
         (Current->is(tok::string_literal) && Current->isMultiline()))<br>
       Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit;<br>
     else<br>
@@ -1048,9 +1053,13 @@ void TokenAnnotator::calculateFormatting<br>
       Current->Role->precomputeFormattingInfos(Current);<br>
   }<br>
<br>
-  DEBUG({<br>
-    printDebugInfo(Line);<br>
-  });<br>
+  DEBUG({ printDebugInfo(Line); });<br>
+<br>
+  for (std::vector<AnnotatedLine *>::iterator I = Line.Children.begin(),<br>
+                                              E = Line.Children.end();<br>
+       I != E; ++I) {<br>
+    calculateFormattingInformation(**I);<br>
+  }<br>
 }<br>
<br>
 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {<br>
@@ -1212,7 +1221,7 @@ bool TokenAnnotator::spaceRequiredBetwee<br>
   if (Right.is(tok::r_square))<br>
     return Right.Type == TT_ObjCArrayLiteral;<br>
   if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr &&<br>
-      Left.isNot(tok::numeric_constant))<br>
+      Right.Type != TT_LambdaLSquare && Left.isNot(tok::numeric_constant))<br>
     return false;<br>
   if (Left.is(tok::colon))<br>
     return Left.Type != TT_ObjCMethodExpr;<br>
@@ -1233,7 +1242,7 @@ bool TokenAnnotator::spaceRequiredBetwee<br>
   if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)<br>
     return false;<br>
   if (Left.is(tok::l_brace) && Right.is(tok::r_brace))<br>
-    return false; // No spaces in "{}".<br>
+    return !Left.Children.empty(); // No spaces in "{}".<br>
   if (Left.is(tok::l_brace) || Right.is(tok::r_brace))<br>
     return !Style.Cpp11BracedListStyle;<br>
   if (Right.Type == TT_UnaryOperator)<br>
@@ -1355,11 +1364,13 @@ bool TokenAnnotator::canBreakBefore(cons<br>
     // change the "binding" behavior of a comment.<br>
     return false;<br>
<br>
+  if (Right.is(tok::r_paren) || Right.Type == TT_TemplateCloser)<br>
+    return false;<br>
+<br>
   // We only break before r_brace if there was a corresponding break before<br>
   // the l_brace, which is tracked by BreakBeforeClosingBrace.<br>
-  if (Right.isOneOf(tok::r_brace, tok::r_paren) ||<br>
-      Right.Type == TT_TemplateCloser)<br>
-    return false;<br>
+  if (Right.is(tok::r_brace))<br>
+    return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block;<br>
<br>
   // Allow breaking after a trailing 'const', e.g. after a method declaration,<br>
   // unless it is follow by ';', '{' or '='.<br>
<br>
Modified: cfe/trunk/lib/Format/TokenAnnotator.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.h?rev=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.h?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/TokenAnnotator.h (original)<br>
+++ cfe/trunk/lib/Format/TokenAnnotator.h Thu Sep  5 04:29:45 2013<br>
@@ -38,31 +38,53 @@ enum LineType {<br>
 class AnnotatedLine {<br>
 public:<br>
   AnnotatedLine(const UnwrappedLine &Line)<br>
-      : First(Line.Tokens.front()), Level(Line.Level),<br>
+      : First(Line.Tokens.front().Tok), Level(Line.Level),<br>
         InPPDirective(Line.InPPDirective),<br>
         MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),<br>
         StartsDefinition(false) {<br>
     assert(!Line.Tokens.empty());<br>
     FormatToken *Current = First;<br>
-    for (std::list<FormatToken *>::const_iterator I = ++Line.Tokens.begin(),<br>
-                                                  E = Line.Tokens.end();<br>
+    for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(),<br>
+                                                      E = Line.Tokens.end();<br>
          I != E; ++I) {<br>
-      Current->Next = *I;<br>
-      (*I)->Previous = Current;<br>
+      const UnwrappedLineNode &Node = *I;<br>
+      Current->Next = I->Tok;<br>
+      I->Tok->Previous = Current;<br>
       Current = Current->Next;<br>
+      for (SmallVectorImpl<UnwrappedLine>::const_iterator<br>
+               I = Node.Children.begin(),<br>
+               E = Node.Children.end();<br>
+           I != E; ++I) {<br>
+        Children.push_back(new AnnotatedLine(*I));<br>
+        Current->Children.push_back(Children.back());<br>
+      }<br>
     }<br>
     Last = Current;<br>
   }<br>
<br>
+  ~AnnotatedLine() {<br>
+    for (unsigned i = 0, e = Children.size(); i != e; ++i) {<br>
+      delete Children[i];<br>
+    }<br>
+    Children.clear();<br></blockquote><div><br></div></div></div><div>Same here...</div><div><div class="h5"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+  }<br>
+<br>
   FormatToken *First;<br>
   FormatToken *Last;<br>
<br>
+  std::vector<AnnotatedLine *> Children;<br>
+<br>
   LineType Type;<br>
   unsigned Level;<br>
   bool InPPDirective;<br>
   bool MustBeDeclaration;<br>
   bool MightBeFunctionDecl;<br>
   bool StartsDefinition;<br>
+<br>
+private:<br>
+  // Disallow copying.<br>
+  AnnotatedLine(const AnnotatedLine &) LLVM_DELETED_FUNCTION;<br>
+  void operator=(const AnnotatedLine &) LLVM_DELETED_FUNCTION;<br>
 };<br>
<br>
 /// \brief Determines extra information about the tokens comprising an<br>
<br>
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Thu Sep  5 04:29:45 2013<br>
@@ -122,9 +122,12 @@ class ScopedLineState {<br>
 public:<br>
   ScopedLineState(UnwrappedLineParser &Parser,<br>
                   bool SwitchToPreprocessorLines = false)<br>
-      : Parser(Parser), SwitchToPreprocessorLines(SwitchToPreprocessorLines) {<br>
+      : Parser(Parser) {<br>
+    OriginalLines = Parser.CurrentLines;<br>
     if (SwitchToPreprocessorLines)<br>
       Parser.CurrentLines = &Parser.PreprocessorDirectives;<br>
+    else if (!Parser.Line->Tokens.empty())<br>
+      Parser.CurrentLines = &Parser.Line->Tokens.back().Children;<br>
     PreBlockLine = Parser.Line.take();<br>
     Parser.Line.reset(new UnwrappedLine());<br>
     Parser.Line->Level = PreBlockLine->Level;<br>
@@ -137,16 +140,16 @@ public:<br>
     }<br>
     assert(Parser.Line->Tokens.empty());<br>
     Parser.Line.reset(PreBlockLine);<br>
-    Parser.MustBreakBeforeNextToken = true;<br>
-    if (SwitchToPreprocessorLines)<br>
-      Parser.CurrentLines = &Parser.Lines;<br>
+    if (Parser.CurrentLines == &Parser.PreprocessorDirectives)<br>
+      Parser.MustBreakBeforeNextToken = true;<br>
+    Parser.CurrentLines = OriginalLines;<br>
   }<br>
<br>
 private:<br>
   UnwrappedLineParser &Parser;<br>
-  const bool SwitchToPreprocessorLines;<br>
<br>
   UnwrappedLine *PreBlockLine;<br>
+  SmallVectorImpl<UnwrappedLine> *OriginalLines;<br>
 };<br>
<br>
 namespace {<br>
@@ -191,7 +194,8 @@ bool UnwrappedLineParser::parse() {<br>
   Tokens = &TokenSource;<br>
   readToken();<br>
   parseFile();<br>
-  for (std::vector<UnwrappedLine>::iterator I = Lines.begin(), E = Lines.end();<br>
+  for (SmallVectorImpl<UnwrappedLine>::iterator I = Lines.begin(),<br>
+                                                E = Lines.end();<br>
        I != E; ++I) {<br>
     Callback.consumeUnwrappedLine(*I);<br>
   }<br>
@@ -670,6 +674,8 @@ void UnwrappedLineParser::parseStructura<br>
 }<br>
<br>
 void UnwrappedLineParser::tryToParseLambda() {<br>
+  assert(FormatTok->is(tok::l_square));<br>
+  FormatToken &LSquare = *FormatTok;<br>
   if (!tryToParseLambdaIntroducer()) {<br>
     return;<br>
   }<br>
@@ -681,7 +687,6 @@ void UnwrappedLineParser::tryToParseLamb<br>
     switch (FormatTok->Tok.getKind()) {<br>
       case tok::l_brace:<br>
         break;<br>
-        return;<br>
       case tok::l_paren:<br>
         parseParens();<br>
         break;<br>
@@ -694,6 +699,7 @@ void UnwrappedLineParser::tryToParseLamb<br>
         break;<br>
     }<br>
   }<br>
+  LSquare.Type = TT_LambdaLSquare;<br>
   parseChildBlock();<br>
 }<br>
<br>
@@ -1183,23 +1189,39 @@ void UnwrappedLineParser::parseObjCProto<br>
   parseObjCUntilAtEnd();<br>
 }<br>
<br>
+static void printDebugInfo(const UnwrappedLine &Line, StringRef Prefix = "") {<br>
+  llvm::dbgs() << Prefix << "Line(" << Line.Level << ")"<br>
+               << (Line.InPPDirective ? " MACRO" : "") << ": ";<br>
+  for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),<br>
+                                                    E = Line.Tokens.end();<br>
+       I != E; ++I) {<br>
+    llvm::dbgs() << I->Tok->Tok.getName() << " ";<br>
+  }<br>
+  for (std::list<UnwrappedLineNode>::const_iterator I = Line.Tokens.begin(),<br>
+                                                    E = Line.Tokens.end();<br>
+       I != E; ++I) {<br>
+    const UnwrappedLineNode &Node = *I;<br>
+    for (SmallVectorImpl<UnwrappedLine>::const_iterator<br>
+             I = Node.Children.begin(),<br>
+             E = Node.Children.end();<br>
+         I != E; ++I) {<br>
+      printDebugInfo(*I, "\nChild: ");<br>
+    }<br>
+  }<br>
+  llvm::dbgs() << "\n";<br>
+}<br>
+<br>
 void UnwrappedLineParser::addUnwrappedLine() {<br>
   if (Line->Tokens.empty())<br>
     return;<br>
   DEBUG({<br>
-    llvm::dbgs() << "Line(" << Line->Level << ")"<br>
-                 << (Line->InPPDirective ? " MACRO" : "") << ": ";<br>
-    for (std::list<FormatToken *>::iterator I = Line->Tokens.begin(),<br>
-                                            E = Line->Tokens.end();<br>
-         I != E; ++I) {<br>
-      llvm::dbgs() << (*I)->Tok.getName() << " ";<br>
-    }<br>
-    llvm::dbgs() << "\n";<br>
+    if (CurrentLines == &Lines)<br>
+      printDebugInfo(*Line);<br>
   });<br>
   CurrentLines->push_back(*Line);<br>
   Line->Tokens.clear();<br>
   if (CurrentLines == &Lines && !PreprocessorDirectives.empty()) {<br>
-    for (std::vector<UnwrappedLine>::iterator<br>
+    for (SmallVectorImpl<UnwrappedLine>::iterator<br>
              I = PreprocessorDirectives.begin(),<br>
              E = PreprocessorDirectives.end();<br>
          I != E; ++I) {<br>
@@ -1273,9 +1295,9 @@ void UnwrappedLineParser::readToken() {<br>
 }<br>
<br>
 void UnwrappedLineParser::pushToken(FormatToken *Tok) {<br>
-  Line->Tokens.push_back(Tok);<br>
+  Line->Tokens.push_back(UnwrappedLineNode(Tok));<br>
   if (MustBreakBeforeNextToken) {<br>
-    Line->Tokens.back()->MustBreakBefore = true;<br>
+    Line->Tokens.back().Tok->MustBreakBefore = true;<br>
     MustBreakBeforeNextToken = false;<br>
   }<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)<br>
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Thu Sep  5 04:29:45 2013<br>
@@ -24,6 +24,8 @@<br>
 namespace clang {<br>
 namespace format {<br>
<br>
+struct UnwrappedLineNode;<br>
+<br>
 /// \brief An unwrapped line is a sequence of \c Token, that we would like to<br>
 /// put on a single line if there was no column limit.<br>
 ///<br>
@@ -35,7 +37,7 @@ struct UnwrappedLine {<br>
<br>
   // FIXME: Don't use std::list here.<br>
   /// \brief The \c Tokens comprising this \c UnwrappedLine.<br>
-  std::list<FormatToken *> Tokens;<br>
+  std::list<UnwrappedLineNode> Tokens;<br>
<br>
   /// \brief The indent level of the \c UnwrappedLine.<br>
   unsigned Level;<br>
@@ -119,18 +121,18 @@ private:<br>
   bool MustBreakBeforeNextToken;<br>
<br>
   // The parsed lines. Only added to through \c CurrentLines.<br>
-  std::vector<UnwrappedLine> Lines;<br>
+  SmallVector<UnwrappedLine, 8> Lines;<br>
<br>
   // Preprocessor directives are parsed out-of-order from other unwrapped lines.<br>
   // Thus, we need to keep a list of preprocessor directives to be reported<br>
   // after an unwarpped line that has been started was finished.<br>
-  std::vector<UnwrappedLine> PreprocessorDirectives;<br>
+  SmallVector<UnwrappedLine, 4> PreprocessorDirectives;<br>
<br>
   // New unwrapped lines are added via CurrentLines.<br>
   // Usually points to \c &Lines. While parsing a preprocessor directive when<br>
   // there is an unfinished previous unwrapped line, will point to<br>
   // \c &PreprocessorDirectives.<br>
-  std::vector<UnwrappedLine> *CurrentLines;<br>
+  SmallVectorImpl<UnwrappedLine> *CurrentLines;<br>
<br>
   // We store for each line whether it must be a declaration depending on<br>
   // whether we are in a compound statement or not.<br>
@@ -162,6 +164,14 @@ private:<br>
   friend class ScopedLineState;<br>
 };<br>
<br>
+struct UnwrappedLineNode {<br>
+  UnwrappedLineNode() : Tok(NULL) {}<br>
+  UnwrappedLineNode(FormatToken *Tok) : Tok(Tok) {}<br>
+<br>
+  FormatToken *Tok;<br>
+  SmallVector<UnwrappedLine, 0> Children;<br>
+};<br>
+<br>
 } // end namespace format<br>
 } // end namespace clang<br>
<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=190038&r1=190037&r2=190038&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=190038&r1=190037&r2=190038&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)<br>
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Sep  5 04:29:45 2013<br>
@@ -110,7 +110,7 @@ TEST_F(FormatTest, MessUp) {<br>
 // Basic function tests.<br>
 //===----------------------------------------------------------------------===//<br>
<br>
-TEST_F(FormatTest, DoesNotChangeCorrectlyFormatedCode) {<br>
+TEST_F(FormatTest, DoesNotChangeCorrectlyFormattedCode) {<br>
   EXPECT_EQ(";", format(";"));<br>
 }<br>
<br>
@@ -1496,7 +1496,9 @@ TEST_F(FormatTest, FormatsClasses) {<br>
                "                     public G {};");<br>
<br>
   verifyFormat("class\n"<br>
-               "    ReallyReallyLongClassName {\n};",<br>
+               "    ReallyReallyLongClassName {\n"<br>
+               "  int i;\n"<br>
+               "};",<br>
                getLLVMStyleWithColumns(32));<br>
 }<br>
<br>
@@ -2184,23 +2186,37 @@ TEST_F(FormatTest, LayoutStatementsAroun<br>
 }<br>
<br>
 TEST_F(FormatTest, LayoutBlockInsideParens) {<br>
+  EXPECT_EQ("functionCall({ int i; });", format(" functionCall ( {int i;} );"));<br>
   EXPECT_EQ("functionCall({\n"<br>
             "  int i;\n"<br>
+            "  int j;\n"<br>
             "});",<br>
-            format(" functionCall ( {int i;} );"));<br>
-<br>
-  // FIXME: This is bad, find a better and more generic solution.<br>
+            format(" functionCall ( {int i;int j;} );"));<br>
   EXPECT_EQ("functionCall({\n"<br>
-            "  int i;\n"<br>
-            "},\n"<br>
+            "               int i;\n"<br>
+            "               int j;\n"<br>
+            "             },\n"<br>
             "             aaaa, bbbb, cccc);",<br>
-            format(" functionCall ( {int i;},  aaaa,   bbbb, cccc);"));<br>
+            format(" functionCall ( {int i;int j;},  aaaa,   bbbb, cccc);"));<br>
+  EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });",<br>
+            format(" functionCall (aaaa,   bbbb, {int i;});"));<br>
+  EXPECT_EQ("functionCall(aaaa, bbbb, {\n"<br>
+            "  int i;\n"<br>
+            "  int j;\n"<br>
+            "});",<br>
+            format(" functionCall (aaaa,   bbbb, {int i;int j;});"));<br>
+  EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });",<br>
+            format(" functionCall (aaaa,   bbbb, {int i;});"));<br>
   verifyFormat(<br>
       "Aaa({\n"<br>
-      "  int i;\n"<br>
-      "},\n"<br>
+      "      int i; // break\n"<br>
+      "    },\n"<br>
       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"<br>
       "                                     ccccccccccccccccc));");<br>
+  verifyFormat("DEBUG({\n"<br>
+               "  if (a)\n"<br>
+               "    f();\n"<br>
+               "});");<br>
 }<br>
<br>
 TEST_F(FormatTest, LayoutBlockInsideStatement) {<br>
@@ -3681,7 +3697,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStar<br>
   verifyGoogleFormat("return sizeof(int**);");<br>
   verifyIndependentOfContext("Type **A = static_cast<Type **>(P);");<br>
   verifyGoogleFormat("Type** A = static_cast<Type**>(P);");<br>
-  verifyFormat("auto a = [](int **&, int ***) {\n};");<br>
+  verifyFormat("auto a = [](int **&, int ***) {};");<br>
<br>
   verifyIndependentOfContext("InvalidRegions[*R] = 0;");<br>
<br>
@@ -3865,7 +3881,7 @@ TEST_F(FormatTest, FormatsCasts) {<br>
   verifyFormat("f(foo).b;");<br>
   verifyFormat("f(foo)(b);");<br>
   verifyFormat("f(foo)[b];");<br>
-  verifyFormat("[](foo) {\n  return 4;\n}(bar);");<br>
+  verifyFormat("[](foo) { return 4; }(bar);");<br>
   verifyFormat("(*funptr)(foo)[4];");<br>
   verifyFormat("funptrs[4](foo)[4];");<br>
   verifyFormat("void f(int *);");<br>
@@ -6260,68 +6276,40 @@ TEST_F(FormatTest, FormatsProtocolBuffer<br>
 }<br>
<br>
 TEST_F(FormatTest, FormatsLambdas) {<br>
-  verifyFormat(<br>
-      "int c = [b]() mutable {\n"<br>
-      "  return [&b] {\n"<br>
-      "    return b++;\n"<br>
-      "  }();\n"<br>
-      "}();\n");<br>
-  verifyFormat(<br>
-      "int c = [&] {\n"<br>
-      "  [=] {\n"<br>
-      "    return b++;\n"<br>
-      "  }();\n"<br>
-      "}();\n");<br>
-  verifyFormat(<br>
-      "int c = [&, &a, a] {\n"<br>
-      "  [=, c, &d] {\n"<br>
-      "    return b++;\n"<br>
-      "  }();\n"<br>
-      "}();\n");<br>
-  verifyFormat(<br>
-      "int c = [&a, &a, a] {\n"<br>
-      "  [=, a, b, &c] {\n"<br>
-      "    return b++;\n"<br>
-      "  }();\n"<br>
-      "}();\n");<br>
-  verifyFormat(<br>
-      "auto c = {[&a, &a, a] {\n"<br>
-      "  [=, a, b, &c] {\n"<br>
-      "    return b++;\n"<br>
-      "  }();\n"<br>
-      "} }\n");<br>
-  verifyFormat(<br>
-      "auto c = {[&a, &a, a] {\n"<br>
-      "  [=, a, b, &c] {\n"<br>
-      "  }();\n"<br>
-      "} }\n");<br>
-  verifyFormat(<br>
-      "void f() {\n"<br>
-      "  other(x.begin(), x.end(), [&](int, int) {\n"<br>
-      "    return 1;\n"<br>
-      "  });\n"<br>
-      "}\n");<br>
+  verifyFormat("int c = [b]() mutable {\n"<br>
+               "  return [&b] { return b++; }();\n"<br>
+               "}();\n");<br>
+  verifyFormat("int c = [&] {\n"<br>
+               "  [=] { return b++; }();\n"<br>
+               "}();\n");<br>
+  verifyFormat("int c = [&, &a, a] {\n"<br>
+               "  [=, c, &d] { return b++; }();\n"<br>
+               "}();\n");<br>
+  verifyFormat("int c = [&a, &a, a] {\n"<br>
+               "  [=, a, b, &c] { return b++; }();\n"<br>
+               "}();\n");<br>
+  verifyFormat("auto c = { [&a, &a, a] {\n"<br>
+               "  [=, a, b, &c] { return b++; }();\n"<br>
+               "} }\n");<br>
+  verifyFormat("auto c = { [&a, &a, a] { [=, a, b, &c] { }(); } }\n");<br>
+  verifyFormat("void f() {\n"<br>
+               "  other(x.begin(), x.end(), [&](int, int) { return 1; });\n"<br>
+               "}\n");<br>
   // FIXME: The formatting is incorrect; this test currently checks that<br>
   // parsing of the unwrapped lines doesn't regress.<br>
-  verifyFormat(<br>
-      "void f() {\n"<br>
-      "  other(x.begin(), //\n"<br>
-      "        x.end(),   //\n"<br>
-      "                     [&](int, int) {\n"<br>
-      "    return 1;\n"<br>
-      "  });\n"<br>
-      "}\n");<br>
+  verifyFormat("void f() {\n"<br>
+               "  other(x.begin(), //\n"<br>
+               "        x.end(),   //\n"<br>
+               "                     [&](int, int) { return 1; });\n"<br>
+               "}\n");<br>
 }<br>
<br>
 TEST_F(FormatTest, FormatsBlocks) {<br>
   // FIXME: Make whitespace formatting consistent. Ask a ObjC dev how<br>
   // it would ideally look.<br>
-  verifyFormat("[operation setCompletionBlock:^{\n"<br>
-               "  [self onOperationDone];\n"<br>
-               "}];\n");<br>
-  verifyFormat("int i = {[operation setCompletionBlock : ^{\n"<br>
-               "  [self onOperationDone];\n"<br>
-               "}] };\n");<br>
+  verifyFormat("[operation setCompletionBlock:^{ [self onOperationDone]; }];");<br>
+  verifyFormat("int i = {[operation setCompletionBlock : ^{ [self "<br>
+               "onOperationDone]; }] };");<br>
 }<br>
<br>
 } // end namespace tooling<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">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></div></div><br></div></div>
</blockquote></div><br></div>