r175741 - Allow breaking between type and name in for loops.

Daniel Jasper djasper at google.com
Thu Feb 21 07:00:30 PST 2013


Author: djasper
Date: Thu Feb 21 09:00:29 2013
New Revision: 175741

URL: http://llvm.org/viewvc/llvm-project?rev=175741&view=rev
Log:
Allow breaking between type and name in for loops.

This fixes llvm.org/PR15033.

Also: Always break before a parameter, if the previous parameter was
split over multiple lines. This was necessary to make the right
decisions in for-loops, almost always makes the code more readable and
also fixes llvm.org/PR14873.

Before:
for (llvm::ArrayRef<NamedDecl *>::iterator I = FD->getDeclsInPrototypeScope()
         .begin(), E = FD->getDeclsInPrototypeScope().end();
     I != E; ++I) {
}
foo(bar(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
        ccccccccccccccccccccccccccccc), d, bar(e, f));

After:
for (llvm::ArrayRef<NamedDecl *>::iterator
         I = FD->getDeclsInPrototypeScope().begin(),
         E = FD->getDeclsInPrototypeScope().end();
     I != E; ++I) {
}
foo(bar(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
        ccccccccccccccccccccccccccccc),
    d, bar(e, f));

Modified:
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/lib/Format/TokenAnnotator.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=175741&r1=175740&r2=175741&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Thu Feb 21 09:00:29 2013
@@ -258,6 +258,12 @@ private:
   tooling::Replacements Replaces;
 };
 
+static bool isVarDeclName(const AnnotatedToken &Tok) {
+  return Tok.Parent != NULL && Tok.is(tok::identifier) &&
+         (Tok.Parent->Type == TT_PointerOrReference ||
+          Tok.Parent->is(tok::identifier));
+}
+
 class UnwrappedLineFormatter {
 public:
   UnwrappedLineFormatter(const FormatStyle &Style, SourceManager &SourceMgr,
@@ -512,7 +518,7 @@ private:
           State.Stack.back().ColonPos =
               State.Column + Current.FormatTok.TokenLength;
         }
-      } else if (Previous.Type == TT_ObjCMethodExpr) {
+      } else if (Previous.Type == TT_ObjCMethodExpr || isVarDeclName(Current)) {
         State.Column = State.Stack.back().Indent + 4;
       } else {
         State.Column = State.Stack.back().Indent;
@@ -610,7 +616,9 @@ private:
           (!Style.AllowAllParametersOfDeclarationOnNextLine &&
            Line.MustBeDeclaration))
         State.Stack.back().BreakBeforeParameter = true;
+    }
 
+    if (Newline) {
       // Any break on this level means that the parent level has been broken
       // and we need to avoid bin packing there.
       for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
@@ -634,13 +642,10 @@ private:
       State.Stack.back().FirstLessLess = State.Column;
     if (Current.is(tok::question))
       State.Stack.back().QuestionColumn = State.Column;
-    if (Current.Type == TT_CtorInitializerColon &&
-        Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
-      State.Stack.back().AvoidBinPacking = true;
-    if (Current.is(tok::l_brace) && Current.MatchingParen != NULL &&
-        !Current.MatchingParen->MustBreakBefore) {
-      if (getLengthToMatchingParen(Current) + State.Column > getColumnLimit())
-        State.Stack.back().BreakBeforeParameter = true;
+    if (Current.Type == TT_CtorInitializerColon) {
+      if (Style.ConstructorInitializerAllOnOneLineOrOnePerLine)
+        State.Stack.back().AvoidBinPacking = true;
+      State.Stack.back().BreakBeforeParameter = false;
     }
 
     // Insert scopes created by fake parenthesis.
@@ -908,7 +913,8 @@ private:
     if (State.NextToken->Parent->is(tok::comma) &&
         State.Stack.back().BreakBeforeParameter &&
         !isTrailingComment(*State.NextToken) &&
-        State.NextToken->isNot(tok::r_paren))
+        State.NextToken->isNot(tok::r_paren) &&
+        State.NextToken->isNot(tok::r_brace))
       return true;
     // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
     // out whether it is the first parameter. Clean this up.

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=175741&r1=175740&r2=175741&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Thu Feb 21 09:00:29 2013
@@ -886,9 +886,8 @@ unsigned TokenAnnotator::splitPenalty(co
   }
 
   // In for-loops, prefer breaking at ',' and ';'.
-  if (Line.First.is(tok::kw_for) &&
-      (Left.isNot(tok::comma) && Left.isNot(tok::semi)))
-    return 20;
+  if (Line.First.is(tok::kw_for) && Left.is(tok::equal))
+    return 4;
 
   if (Left.is(tok::semi))
     return 0;
@@ -1066,6 +1065,8 @@ bool TokenAnnotator::canBreakBefore(cons
   if (Left.Type == TT_RangeBasedForLoopColon ||
       Left.Type == TT_InheritanceColon)
     return true;
+  if (Right.Type == TT_RangeBasedForLoopColon)
+    return false;
   if (Left.Type == TT_PointerOrReference || Left.Type == TT_TemplateCloser ||
       Left.Type == TT_UnaryOperator || Left.Type == TT_ConditionalExpr ||
       Left.is(tok::question) || Left.is(tok::kw_operator))
@@ -1078,6 +1079,12 @@ bool TokenAnnotator::canBreakBefore(cons
     // change the "binding" behavior of a comment.
     return false;
 
+  // FIXME: We can probably remove this special case once we have implemented
+  // breaking after types in general.
+  if (Line.First.is(tok::kw_for) && !Right.Children.empty() &&
+      Right.Children[0].is(tok::equal))
+    return true;
+
   // Allow breaking after a trailing 'const', e.g. after a method declaration,
   // unless it is follow by ';', '{' or '='.
   if (Left.is(tok::kw_const) && Left.Parent != NULL &&

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=175741&r1=175740&r2=175741&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Feb 21 09:00:29 2013
@@ -278,9 +278,13 @@ TEST_F(FormatTest, FormatsForLoop) {
   verifyFormat(
       "for (MachineFun::iterator IIII = PrevIt, EEEE = F.end(); IIII != EEEE;\n"
       "     ++IIIII) {\n}");
-  verifyFormat("for (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaa =\n"
-               "         aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa;\n"
+  verifyFormat("for (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "         aaaaaaaaaaa = aaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaa;\n"
                "     aaaaaaaaaaa != aaaaaaaaaaaaaaaaaaa; ++aaaaaaaaaaa) {\n}");
+  verifyFormat("for (llvm::ArrayRef<NamedDecl *>::iterator\n"
+               "         I = FD->getDeclsInPrototypeScope().begin(),\n"
+               "         E = FD->getDeclsInPrototypeScope().end();\n"
+               "     I != E; ++I) {\n}");
 
   // FIXME: Not sure whether we want extra identation in line 3 here:
   verifyFormat(
@@ -1012,7 +1016,8 @@ TEST_F(FormatTest, LayoutStatementsAroun
                "#define A B\n"
                "                           withMoreParamters,\n"
                "                           whichStronglyInfluenceTheLayout),\n"
-               "        andMoreParameters), trailing);",
+               "        andMoreParameters),\n"
+               "    trailing);",
                getLLVMStyleWithColumns(69));
 }
 
@@ -1398,8 +1403,8 @@ TEST_F(FormatTest, BreaksConditionalExpr
       "unsigned Indent =\n"
       "    format(TheLine.First, IndentForLevel[TheLine.Level] >= 0\n"
       "                              ? IndentForLevel[TheLine.Level]\n"
-      "                              : TheLine * 2, TheLine.InPPDirective,\n"
-      "           PreviousEndOfLineColumn);",
+      "                              : TheLine * 2,\n"
+      "           TheLine.InPPDirective, PreviousEndOfLineColumn);",
       getLLVMStyleWithColumns(70));
 
 }
@@ -1414,11 +1419,10 @@ TEST_F(FormatTest, DeclarationsOfMultipl
                "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa),\n"
                "     bbbbbbbbbbbbbbbbbbbbbbbbb =\n"
                "     bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(bbbbbbbbbbbbbbbb);");
-
-  // FIXME: This is bad as we hide "d".
   verifyFormat(
-      "bool aaaaaaaaaaaaaaaaaaaaa = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb &&\n"
-      "                             cccccccccccccccccccccccccccc, d = e && f;");
+      "bool aaaaaaaaaaaaaaaaaaaaa =\n"
+      "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb && cccccccccccccccccccccccccccc,\n"
+      "     d = e && f;");
 
 }
 
@@ -2066,11 +2070,13 @@ TEST_F(FormatTest, LayoutBraceInitialize
 }
 
 TEST_F(FormatTest, LayoutTokensFollowingBlockInParentheses) {
+  // FIXME: This is bad, find a better and more generic solution.
   verifyFormat(
       "Aaa({\n"
       "  int i;\n"
-      "}, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
-      "                                    ccccccccccccccccc));");
+      "},\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
+      "                                     ccccccccccccccccc));");
 }
 
 TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {





More information about the cfe-commits mailing list