[cfe-commits] r172058 - in /cfe/trunk: lib/Format/Format.cpp lib/Format/UnwrappedLineParser.cpp lib/Format/UnwrappedLineParser.h unittests/Format/FormatTest.cpp

Manuel Klimek klimek at google.com
Thu Jan 10 03:52:21 PST 2013


Author: klimek
Date: Thu Jan 10 05:52:21 2013
New Revision: 172058

URL: http://llvm.org/viewvc/llvm-project?rev=172058&view=rev
Log:
Fix layout of blocks inside statements.

Previously, we would not indent:
SOME_MACRO({
  int i;
});
correctly. This is fixed by adding the trailing }); to the unwrapped
line starting with SOME_MACRO({, so the formatter can correctly match
the braces and indent accordingly.

Also fixes incorrect parsing of initializer lists, like:
int a[] = { 1 };

Modified:
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp
    cfe/trunk/lib/Format/UnwrappedLineParser.h
    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=172058&r1=172057&r2=172058&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Thu Jan 10 05:52:21 2013
@@ -279,7 +279,9 @@
 
     if (Newline) {
       unsigned WhitespaceStartColumn = State.Column;
-      if (Previous.is(tok::l_brace)) {
+      if (Current.is(tok::r_brace)) {
+        State.Column = Line.Level * 2;
+      } else if (Previous.is(tok::l_brace)) {
         // FIXME: This does not work with nested static initializers.
         // Implement a better handling for static initializers and similar
         // constructs.

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=172058&r1=172057&r2=172058&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Thu Jan 10 05:52:21 2013
@@ -76,6 +76,40 @@
   FormatToken Token;
 };
 
+class ScopedLineState {
+public:
+  ScopedLineState(UnwrappedLineParser &Parser) : Parser(Parser) {
+    PreBlockLine = Parser.Line.take();
+    Parser.Line.reset(new UnwrappedLine(*PreBlockLine));
+    assert(Parser.LastInCurrentLine == NULL ||
+           Parser.LastInCurrentLine->Children.empty());
+    PreBlockLastToken = Parser.LastInCurrentLine;
+    PreBlockRootTokenInitialized = Parser.RootTokenInitialized;
+    Parser.RootTokenInitialized = false;
+    Parser.LastInCurrentLine = NULL;
+  }
+
+  ~ScopedLineState() {
+    if (Parser.RootTokenInitialized) {
+      Parser.addUnwrappedLine();
+    }
+    assert(!Parser.RootTokenInitialized);
+    Parser.Line.reset(PreBlockLine);
+    Parser.RootTokenInitialized = PreBlockRootTokenInitialized;
+    Parser.LastInCurrentLine = PreBlockLastToken;
+    assert(Parser.LastInCurrentLine == NULL ||
+           Parser.LastInCurrentLine->Children.empty());
+    Parser.MustBreakBeforeNextToken = true;
+  }
+
+private:
+  UnwrappedLineParser &Parser;
+
+  UnwrappedLine *PreBlockLine;
+  FormatToken* PreBlockLastToken;
+  bool PreBlockRootTokenInitialized;
+};
+
 UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
                                          FormatTokenSource &Tokens,
                                          UnwrappedLineConsumer &Callback)
@@ -204,6 +238,7 @@
 }
 
 void UnwrappedLineParser::parseStructuralElement() {
+  assert(!FormatTok.Tok.is(tok::l_brace));
   parseComments();
 
   int TokenNumber = 0;
@@ -289,6 +324,10 @@
       parseParens();
       break;
     case tok::l_brace:
+      // A block outside of parentheses must be the last part of a
+      // structural element.
+      // FIXME: Figure out cases where this is not true, and add projections for
+      // them (the one we know is missing are lambdas).
       parseBlock();
       addUnwrappedLine();
       return;
@@ -301,9 +340,9 @@
       break;
     case tok::equal:
       nextToken();
-      // Skip initializers as they will be formatted by a later step.
-      if (FormatTok.Tok.is(tok::l_brace))
-        nextToken();
+      if (FormatTok.Tok.is(tok::l_brace)) {
+        parseBracedList();
+      }
       break;
     default:
       nextToken();
@@ -312,6 +351,24 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseBracedList() {
+  nextToken();
+
+  do {
+    switch (FormatTok.Tok.getKind()) {
+    case tok::l_brace:
+      parseBracedList();
+      break;
+    case tok::r_brace:
+      nextToken();
+      return;
+    default:
+      nextToken();
+      break;
+    }
+  } while (!eof());
+}
+
 void UnwrappedLineParser::parseParens() {
   assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
   nextToken();
@@ -323,6 +380,15 @@
     case tok::r_paren:
       nextToken();
       return;
+    case tok::l_brace:
+      {
+        nextToken();
+        ScopedLineState LineState(*this);
+        Line->Level += 1;
+        parseLevel(/*HasOpeningBrace=*/true);
+        Line->Level -= 1;
+      }
+      break;
     default:
       nextToken();
       break;
@@ -626,22 +692,8 @@
   while (!Line->InPPDirective && FormatTok.Tok.is(tok::hash) &&
          ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
           FormatTok.IsFirst)) {
-    UnwrappedLine* StoredLine = Line.take();
-    Line.reset(new UnwrappedLine(*StoredLine));
-    assert(LastInCurrentLine == NULL || LastInCurrentLine->Children.empty());
-    FormatToken *StoredLastInCurrentLine = LastInCurrentLine;
-    bool PreviousInitialized = RootTokenInitialized;
-    RootTokenInitialized = false;
-    LastInCurrentLine = NULL;
-
+    ScopedLineState BlockState(*this);
     parsePPDirective();
-
-    assert(!RootTokenInitialized);
-    Line.reset(StoredLine);
-    RootTokenInitialized = PreviousInitialized;
-    LastInCurrentLine = StoredLastInCurrentLine;
-    assert(LastInCurrentLine == NULL || LastInCurrentLine->Children.empty());
-    MustBreakBeforeNextToken = true;
   }
 }
 

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=172058&r1=172057&r2=172058&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Thu Jan 10 05:52:21 2013
@@ -131,6 +131,7 @@
   void parsePPUnknown();
   void parseComments();
   void parseStructuralElement();
+  void parseBracedList();
   void parseParens();
   void parseIfThenElse();
   void parseForOrWhileLoop();
@@ -163,6 +164,8 @@
   const FormatStyle &Style;
   FormatTokenSource *Tokens;
   UnwrappedLineConsumer &Callback;
+
+  friend class ScopedLineState;
 };
 
 } // end namespace format

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=172058&r1=172057&r2=172058&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Jan 10 05:52:21 2013
@@ -615,6 +615,30 @@
       "               trailing);", getLLVMStyleWithColumns(69));
 }
 
+TEST_F(FormatTest, LayoutBlockInsideParens) {
+  EXPECT_EQ("functionCall({\n"
+            "  int i;\n"
+            "});", format(" functionCall ( {int i;} );"));
+}
+
+TEST_F(FormatTest, LayoutBlockInsideStatement) {
+  EXPECT_EQ("SOME_MACRO {\n"
+            "  int i;\n"
+            "}\n"
+            "int i;", format("  SOME_MACRO  {int i;}  int i;"));
+}
+
+TEST_F(FormatTest, LayoutNestedBlocks) {
+  verifyFormat("void AddOsStrings(unsigned bitmask) {\n"
+               "  struct s {\n"
+               "    int i;\n"
+               "  };\n"
+               "  s kBitsToOs[] = { { 10 } };\n"
+               "  for (int i = 0; i < 10; ++i)\n"
+               "    return;\n"
+               "}");
+}
+
 //===----------------------------------------------------------------------===//
 // Line break tests.
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list