[PATCH] Formatter explicitly handles try/catch blocks.

Diego Alexander Rojas alexander.rojas at gmail.com
Sun Jan 12 05:24:31 PST 2014


This patch attempts to solve Bug 18418 by explicitly handling
try/catch blocks, so they
are consistent with the brace braking style.

This patch does not yet fix the style in function try blocks.

The differences in the output produced with each style are:

Allman style doesn't change.

Before (using attach, linux, stroustrup):
try {
  // Do something
}
catch (...) {
  // Do something
}

After:
try {
  // Do something
} catch (...) {
  // Do something
}

Before (GNU):
try
{
  // Do something
}
catch (...)
{
  // Do something
}

After:
try
  {
    // Do something
  }
catch (...)
  {
    // Do something
  }


--
Diego Alexander Rojas Páez

E-Mail:     alexander.rojas at gmail.com
Mobile:     +49 (151) 5249 5452
Address:  Stefan-George-Ring 46
               81929, Munich
               Germany

-------------- next part --------------
Index: lib/Format/UnwrappedLineParser.cpp
===================================================================
--- lib/Format/UnwrappedLineParser.cpp (revision 199037)
+++ lib/Format/UnwrappedLineParser.cpp (working copy)
@@ -621,6 +621,9 @@
   case tok::kw_private:
     parseAccessSpecifier();
     return;
+  case tok::kw_try:
+    parseTryCatch();
+    return;
   case tok::kw_if:
     parseIfThenElse();
     return;
@@ -1028,6 +1031,50 @@
   }
 }

+void UnwrappedLineParser::parseTryCatch() {
+  assert(FormatTok->Tok.is(tok::kw_try) && "'try' expected");
+  nextToken();
+  bool NeedsUnwrappedLine = false;
+  if (FormatTok->Tok.is(tok::l_brace)) {
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
+    parseBlock(/*MustBeDeclaration=*/false);
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
+      addUnwrappedLine();
+    } else {
+      NeedsUnwrappedLine = true;
+    }
+  } else if (!FormatTok->Tok.is(tok::kw_catch)) {
+    // The C++ standard requires a compound-statement after a try.
+    // If there's none, we try to assume there's a structuralElement
+    // and try to continue.
+    StructuralError = true;
+    addUnwrappedLine();
+    ++Line->Level;
+    parseStructuralElement();
+    --Line->Level;
+  }
+  while (FormatTok->Tok.is(tok::kw_catch)) {
+    nextToken();
+    if (FormatTok->Tok.is(tok::l_paren))
+      parseParens();
+    NeedsUnwrappedLine = false;
+    if (FormatTok->Tok.is(tok::l_brace)) {
+      CompoundStatementIndenter Indenter(this, Style, Line->Level);
+      parseBlock(/*MustBeDeclaration=*/false);
+      if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+          Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
+        addUnwrappedLine();
+      } else {
+        NeedsUnwrappedLine = true;
+      }
+    }
+  }
+  if (NeedsUnwrappedLine) {
+    addUnwrappedLine();
+  }
+}
+
 void UnwrappedLineParser::parseNamespace() {
   assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");
   nextToken();
Index: lib/Format/UnwrappedLineParser.h
===================================================================
--- lib/Format/UnwrappedLineParser.h (revision 199037)
+++ lib/Format/UnwrappedLineParser.h (working copy)
@@ -85,6 +85,7 @@
   void parseReturn();
   void parseParens();
   void parseSquare();
+  void parseTryCatch();
   void parseIfThenElse();
   void parseForOrWhileLoop();
   void parseDoWhile();
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp (revision 199037)
+++ unittests/Format/FormatTest.cpp (working copy)
@@ -1810,15 +1810,11 @@
 }

 TEST_F(FormatTest, FormatTryCatch) {
-  // FIXME: Handle try-catch explicitly in the UnwrappedLineParser, then we'll
-  // also not create single-line-blocks.
   verifyFormat("try {\n"
                "  throw a * b;\n"
-               "}\n"
-               "catch (int a) {\n"
+               "} catch (int a) {\n"
                "  // Do nothing.\n"
-               "}\n"
-               "catch (...) {\n"
+               "} catch (...) {\n"
                "  exit(42);\n"
                "}");

@@ -2271,9 +2267,8 @@
             "  f(x)\n"
             "  try {\n"
             "    q();\n"
+            "  } catch (...) {\n"
             "  }\n"
-            "  catch (...) {\n"
-            "  }\n"
             "}\n",
             format("int q() {\n"
                    "f(x)\n"
@@ -2288,8 +2283,7 @@
   EXPECT_EQ("class A {\n"
             "  A() : t(0) {}\n"
             "  A(X x)\n" // FIXME: function-level try blocks are broken.
-            "  try : t(0) {\n"
-            "  }\n"
+            "  try : t(0) {}\n"
             "  catch (...) {\n"
             "  }\n"
             "};",
@@ -7172,9 +7166,8 @@
 TEST_F(FormatTest, CatchExceptionReferenceBinding) {
   verifyFormat("void f() {\n"
                "  try {\n"
+               "  } catch (const Exception &e) {\n"
                "  }\n"
-               "  catch (const Exception &e) {\n"
-               "  }\n"
                "}\n",
                getLLVMStyle());
 }




More information about the cfe-commits mailing list