]> granicus.if.org Git - clang/commitdiff
clang-format: Fix incorrect enum parsing / layouting.
authorDaniel Jasper <djasper@google.com>
Fri, 13 Sep 2013 09:20:45 +0000 (09:20 +0000)
committerDaniel Jasper <djasper@google.com>
Fri, 13 Sep 2013 09:20:45 +0000 (09:20 +0000)
Before:
  enum {
    Bar = Foo < int,
    int > ::value
  };

After:
  enum {
    Bar = Foo<int, int>::value
  };

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190674 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Format/ContinuationIndenter.cpp
lib/Format/Format.cpp
lib/Format/FormatToken.cpp
lib/Format/TokenAnnotator.cpp
lib/Format/UnwrappedLineParser.cpp
lib/Format/UnwrappedLineParser.h
unittests/Format/FormatTest.cpp

index f1924c3776d01a0f39e75c593ba391374aa2d3f2..7066e15d5de100cf9ff74f336d9d9e6ffe395167 100644 (file)
@@ -106,8 +106,10 @@ bool ContinuationIndenter::mustBreak(const LineState &State) {
   const FormatToken &Previous = *Current.Previous;
   if (Current.MustBreakBefore || Current.Type == TT_InlineASMColon)
     return true;
-  if (!Style.Cpp11BracedListStyle && Current.is(tok::r_brace) &&
-      State.Stack.back().BreakBeforeClosingBrace)
+  if ((!Style.Cpp11BracedListStyle ||
+       (Current.MatchingParen &&
+        Current.MatchingParen->BlockKind == BK_Block)) &&
+      Current.is(tok::r_brace) && State.Stack.back().BreakBeforeClosingBrace)
     return true;
   if (Previous.is(tok::semi) && State.LineContainsContinuedForLoopSection)
     return true;
@@ -224,7 +226,9 @@ unsigned ContinuationIndenter::addTokenToState(LineState &State, bool Newline,
         State.Column <= Style.ColumnLimit / 2)
       Penalty += Style.PenaltyBreakFirstLessLess;
 
-    if (Current.is(tok::r_brace)) {
+    if (Current.is(tok::l_brace) && Current.BlockKind == BK_Block) {
+      State.Column = State.FirstIndent;
+    } else if (Current.is(tok::r_brace)) {
       if (Current.MatchingParen &&
           (Current.MatchingParen->BlockKind == BK_BracedInit ||
            !Current.MatchingParen->Children.empty()))
@@ -524,14 +528,15 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
         //                      });
         for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i)
           State.Stack.pop_back();
-        NewIndent = State.Stack.back().LastSpace;
+        NewIndent = State.Stack.back().LastSpace + Style.IndentWidth;
       } else {
         NewIndent = State.Stack.back().LastSpace +
                     (Style.Cpp11BracedListStyle ? 4 : Style.IndentWidth);
       }
       const FormatToken *NextNoComment = Current.getNextNonComment();
-      AvoidBinPacking = NextNoComment &&
-                        NextNoComment->Type == TT_DesignatedInitializerPeriod;
+      AvoidBinPacking = Current.BlockKind == BK_Block ||
+                        (NextNoComment &&
+                         NextNoComment->Type == TT_DesignatedInitializerPeriod);
     } else {
       NewIndent = 4 + std::max(State.Stack.back().LastSpace,
                                State.Stack.back().StartOfFunctionCall);
@@ -545,6 +550,7 @@ unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
     State.Stack.push_back(ParenState(NewIndent, State.Stack.back().LastSpace,
                                      AvoidBinPacking,
                                      State.Stack.back().NoLineBreak));
+    State.Stack.back().BreakBeforeParameter = Current.BlockKind == BK_Block;
     ++State.ParenLevel;
   }
 
index 52f8b07475d427dfe80d12e0fc207f1ca09b99fa..034f6e6ee87dd0883354b547004c97e27187d6a6 100644 (file)
@@ -529,7 +529,7 @@ private:
                E = LBrace.Children.end();
            I != E; ++I) {
         unsigned Indent =
-            ParentIndent + ((*I)->Level - Line.Level) * Style.IndentWidth;
+            ParentIndent + ((*I)->Level - Line.Level - 1) * Style.IndentWidth;
         if (!DryRun) {
           unsigned Newlines = std::min((*I)->First->NewlinesBefore,
                                        Style.MaxEmptyLinesToKeep + 1);
index 49e0ce83375b2ee53b30fd8c778f958df6a7da25..7469216a147c889d26272c16b824e52fe2b494e4 100644 (file)
@@ -36,6 +36,7 @@ unsigned CommaSeparatedList::format(LineState &State,
   // Ensure that we start on the opening brace.
   const FormatToken *LBrace = State.NextToken->Previous->Previous;
   if (LBrace->isNot(tok::l_brace) ||
+      LBrace->BlockKind == BK_Block ||
       LBrace->Next->Type == TT_DesignatedInitializerPeriod)
     return 0;
 
index dec631fcfb3bb68c37701751aafdb1f9716153c0..db17135a0c7438ba6c458fcd16c2b6c9dc7b7422 100644 (file)
@@ -1057,6 +1057,12 @@ void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
     } else if (Current->Type == TT_CtorInitializerComma &&
                Style.BreakConstructorInitializersBeforeComma) {
       Current->MustBreakBefore = true;
+    } else if (Current->Previous->BlockKind == BK_Block &&
+               Current->isNot(tok::r_brace)) {
+      Current->MustBreakBefore = true;
+    } else if (Current->is(tok::l_brace) && (Current->BlockKind == BK_Block)) {
+      Current->MustBreakBefore =
+          Style.BreakBeforeBraces == FormatStyle::BS_Allman;
     }
     Current->CanBreakBefore =
         Current->MustBreakBefore || canBreakBefore(Line, *Current);
index f70de5f6d88e981264c031a819e43b02befe0f4d..3fb46f2f56fbcfac8797a01f41c1ffc85c844be0 100644 (file)
@@ -759,7 +759,8 @@ bool UnwrappedLineParser::tryToParseBracedList() {
   return true;
 }
 
-void UnwrappedLineParser::parseBracedList() {
+bool UnwrappedLineParser::parseBracedList(bool ContinueOnSemicolons) {
+  bool HasError = false;
   nextToken();
 
   // FIXME: Once we have an expression parser in the UnwrappedLineParser,
@@ -786,10 +787,13 @@ void UnwrappedLineParser::parseBracedList() {
       break;
     case tok::r_brace:
       nextToken();
-      return;
+      return !HasError;
     case tok::semi:
-      // Probably a missing closing brace. Bail out.
-      return;
+      HasError = true;
+      if (!ContinueOnSemicolons)
+        return !HasError;
+      nextToken();
+      break;
     case tok::comma:
       nextToken();
       break;
@@ -798,6 +802,7 @@ void UnwrappedLineParser::parseBracedList() {
       break;
     }
   } while (!eof());
+  return false;
 }
 
 void UnwrappedLineParser::parseReturn() {
@@ -1046,42 +1051,14 @@ void UnwrappedLineParser::parseEnum() {
     if (FormatTok->Tok.is(tok::identifier))
       nextToken();
   }
-  bool HasError = false;
   if (FormatTok->Tok.is(tok::l_brace)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-      addUnwrappedLine();
-    nextToken();
-    addUnwrappedLine();
-    ++Line->Level;
-    do {
-      switch (FormatTok->Tok.getKind()) {
-      case tok::l_paren:
-        parseParens();
-        break;
-      case tok::r_brace:
-        addUnwrappedLine();
-        nextToken();
-        --Line->Level;
-        if (HasError) {
-          if (FormatTok->is(tok::semi))
-            nextToken();
-          addUnwrappedLine();
-        }
-        return;
-      case tok::semi:
-        HasError = true;
-        nextToken();
-        addUnwrappedLine();
-        break;
-      case tok::comma:
-        nextToken();
-        addUnwrappedLine();
-        break;
-      default:
+    FormatTok->BlockKind = BK_Block;
+    bool HasError = !parseBracedList(/*ContinueOnSemicolons=*/true);
+    if (HasError) {
+      if (FormatTok->is(tok::semi))
         nextToken();
-        break;
-      }
-    } while (!eof());
+      addUnwrappedLine();
+    }
   }
   // We fall through to parsing a structural element afterwards, so that in
   // enum A {} n, m;
index c79c35e1b9d62d4f4601a0f323f581ce373dd4f5..3acdbd60a5836271258f264c0e9d1976b0b6fdc5 100644 (file)
@@ -79,7 +79,7 @@ private:
   void parsePPUnknown();
   void parseStructuralElement();
   bool tryToParseBracedList();
-  void parseBracedList();
+  bool parseBracedList(bool ContinueOnSemicolons = false);
   void parseReturn();
   void parseParens();
   void parseIfThenElse();
index 2500c8e4a714f2371ea8d0c7bc99e1e4af069815..5202073e16e42df7760cf94eea19d42429f586d7 100644 (file)
@@ -1530,12 +1530,23 @@ TEST_F(FormatTest, FormatsEnum) {
                "  Four = (Zero && (One ^ Two)) | (One << Two),\n"
                "  Five = (One, Two, Three, Four, 5)\n"
                "};");
+  verifyGoogleFormat("enum {\n"
+                     "  Zero,\n"
+                     "  One = 1,\n"
+                     "  Two = One + 1,\n"
+                     "  Three = (One + Two),\n"
+                     "  Four = (Zero && (One ^ Two)) | (One << Two),\n"
+                     "  Five = (One, Two, Three, Four, 5)\n"
+                     "};");
   verifyFormat("enum Enum {};");
   verifyFormat("enum {};");
-  verifyFormat("enum X E {\n} d;");
-  verifyFormat("enum __attribute__((...)) E {\n} d;");
-  verifyFormat("enum __declspec__((...)) E {\n} d;");
+  verifyFormat("enum X E {} d;");
+  verifyFormat("enum __attribute__((...)) E {} d;");
+  verifyFormat("enum __declspec__((...)) E {} d;");
   verifyFormat("enum X f() {\n  a();\n  return 42;\n}");
+  verifyFormat("enum {\n"
+               "  Bar = Foo<int, int>::value\n"
+               "};");
 }
 
 TEST_F(FormatTest, FormatsEnumsWithErrors) {
@@ -1563,9 +1574,9 @@ TEST_F(FormatTest, FormatsEnumStruct) {
                "};");
   verifyFormat("enum struct Enum {};");
   verifyFormat("enum struct {};");
-  verifyFormat("enum struct X E {\n} d;");
-  verifyFormat("enum struct __attribute__((...)) E {\n} d;");
-  verifyFormat("enum struct __declspec__((...)) E {\n} d;");
+  verifyFormat("enum struct X E {} d;");
+  verifyFormat("enum struct __attribute__((...)) E {} d;");
+  verifyFormat("enum struct __declspec__((...)) E {} d;");
   verifyFormat("enum struct X f() {\n  a();\n  return 42;\n}");
 }
 
@@ -1580,9 +1591,9 @@ TEST_F(FormatTest, FormatsEnumClass) {
                "};");
   verifyFormat("enum class Enum {};");
   verifyFormat("enum class {};");
-  verifyFormat("enum class X E {\n} d;");
-  verifyFormat("enum class __attribute__((...)) E {\n} d;");
-  verifyFormat("enum class __declspec__((...)) E {\n} d;");
+  verifyFormat("enum class X E {} d;");
+  verifyFormat("enum class __attribute__((...)) E {} d;");
+  verifyFormat("enum class __declspec__((...)) E {} d;");
   verifyFormat("enum class X f() {\n  a();\n  return 42;\n}");
 }