r208302 - clang-format: Initial support for try-catch.

Daniel Jasper djasper at google.com
Thu May 8 04:58:27 PDT 2014


Author: djasper
Date: Thu May  8 06:58:24 2014
New Revision: 208302

URL: http://llvm.org/viewvc/llvm-project?rev=208302&view=rev
Log:
clang-format: Initial support for try-catch.

Most of this patch was created by Alexander Rojas in
http://reviews.llvm.org/D2555
Thank you!

Synced and addressed review comments.

Modified:
    cfe/trunk/lib/Format/UnwrappedLineParser.cpp
    cfe/trunk/lib/Format/UnwrappedLineParser.h
    cfe/trunk/unittests/Format/FormatTest.cpp
    cfe/trunk/unittests/Format/FormatTestJS.cpp

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=208302&r1=208301&r2=208302&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Thu May  8 06:58:24 2014
@@ -675,6 +675,9 @@ void UnwrappedLineParser::parseStructura
   case tok::kw_case:
     parseCaseLabel();
     return;
+  case tok::kw_try:
+    parseTryCatch();
+    return;
   case tok::kw_extern:
     nextToken();
     if (FormatTok->Tok.is(tok::string_literal)) {
@@ -755,6 +758,10 @@ void UnwrappedLineParser::parseStructura
       // Otherwise this was a braced init list, and the structural
       // element continues.
       break;
+    case tok::kw_try:
+      // We arrive here when parsing function-try blocks.
+      parseTryCatch();
+      return;
     case tok::identifier: {
       StringRef Text = FormatTok->TokenText;
       nextToken();
@@ -1070,6 +1077,72 @@ void UnwrappedLineParser::parseIfThenEls
     addUnwrappedLine();
   }
 }
+
+void UnwrappedLineParser::parseTryCatch() {
+  assert(FormatTok->is(tok::kw_try) && "'try' expected");
+  nextToken();
+  bool NeedsUnwrappedLine = false;
+  if (FormatTok->is(tok::colon)) {
+    // We are in a function try block, what comes is an initializer list.
+    nextToken();
+    while (FormatTok->is(tok::identifier)) {
+      nextToken();
+      if (FormatTok->is(tok::l_paren))
+        parseParens();
+      else
+        StructuralError = true;
+      if (FormatTok->is(tok::comma))
+        nextToken();
+    }
+  }
+  if (FormatTok->is(tok::l_brace)) {
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
+    parseBlock(/*MustBeDeclaration=*/false);
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
+      addUnwrappedLine();
+    } else {
+      NeedsUnwrappedLine = true;
+    }
+  } else if (!FormatTok->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->is(tok::kw_catch) ||
+         (Style.Language == FormatStyle::LK_JavaScript &&
+          FormatTok->TokenText == "finally")) {
+    nextToken();
+    while (FormatTok->isNot(tok::l_brace)) {
+      if (FormatTok->is(tok::l_paren)) {
+        parseParens();
+        continue;
+      }
+      if (FormatTok->isOneOf(tok::semi, tok::r_brace))
+        return;
+      nextToken();
+    }
+    NeedsUnwrappedLine = false;
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
+    parseBlock(/*MustBeDeclaration=*/false);
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
+      addUnwrappedLine();
+    } else {
+      NeedsUnwrappedLine = true;
+    }
+  }
+  if (NeedsUnwrappedLine) {
+    addUnwrappedLine();
+  }
+}
 
 void UnwrappedLineParser::parseNamespace() {
   assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");

Modified: cfe/trunk/lib/Format/UnwrappedLineParser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.h?rev=208302&r1=208301&r2=208302&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.h Thu May  8 06:58:24 2014
@@ -85,6 +85,7 @@ private:
   void parseParens();
   void parseSquare();
   void parseIfThenElse();
+  void parseTryCatch();
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel();

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=208302&r1=208301&r2=208302&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu May  8 06:58:24 2014
@@ -2000,32 +2000,81 @@ TEST_F(FormatTest, FormatsInlineASM) {
 }
 
 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"
                "}");
 
   // Function-level try statements.
-  verifyFormat("int f() try { return 4; }\n"
-               "catch (...) {\n"
+  verifyFormat("int f() try { return 4; } catch (...) {\n"
                "  return 5;\n"
                "}");
   verifyFormat("class A {\n"
                "  int a;\n"
-               "  A() try : a(0) {}\n"
-               "  catch (...) {\n"
+               "  A() try : a(0) {\n"
+               "  } catch (...) {\n"
                "    throw;\n"
                "  }\n"
                "};\n");
 }
 
+TEST_F(FormatTest, IncompleteTryCatchBlocks) {
+  verifyFormat("try {\n"
+               "  f();\n"
+               "} catch {\n"
+               "  g();\n"
+               "}");
+  verifyFormat("try {\n"
+               "  f();\n"
+               "} catch (A a) MACRO(x) {\n"
+               "  g();\n"
+               "} catch (B b) MACRO(x) {\n"
+               "  g();\n"
+               "}");
+}
+
+TEST_F(FormatTest, FormatTryCatchBraceStyles) {
+  FormatStyle Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BS_Attach;
+  verifyFormat("try {\n"
+               "  // something\n"
+               "} catch (...) {\n"
+               "  // something\n"
+               "}",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+  verifyFormat("try {\n"
+               "  // something\n"
+               "}\n"
+               "catch (...) {\n"
+               "  // something\n"
+               "}",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("try\n"
+               "{\n"
+               "  // something\n"
+               "}\n"
+               "catch (...)\n"
+               "{\n"
+               "  // something\n"
+               "}",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_GNU;
+  verifyFormat("try\n"
+               "  {\n"
+               "    // something\n"
+               "  }\n"
+               "catch (...)\n"
+               "  {\n"
+               "    // something\n"
+               "  }",
+               Style);
+}
+
 TEST_F(FormatTest, FormatObjCTryCatch) {
   verifyFormat("@try {\n"
                "  f();\n"
@@ -2453,8 +2502,7 @@ TEST_F(FormatTest, MacroCallsWithoutTrai
             "  F(x)\n"
             "  try {\n"
             "    Q();\n"
-            "  }\n"
-            "  catch (...) {\n"
+            "  } catch (...) {\n"
             "  }\n"
             "}\n",
             format("int q() {\n"
@@ -2471,8 +2519,7 @@ TEST_F(FormatTest, MacroCallsWithoutTrai
             "  A() : t(0) {}\n"
             "  A(X x)\n" // FIXME: function-level try blocks are broken.
             "  try : t(0) {\n"
-            "  }\n"
-            "  catch (...) {\n"
+            "  } catch (...) {\n"
             "  }\n"
             "};",
             format("class A {\n"
@@ -7752,8 +7799,7 @@ TEST_F(FormatTest, GNUBraceBreaking) {
 TEST_F(FormatTest, CatchExceptionReferenceBinding) {
   verifyFormat("void f() {\n"
                "  try {\n"
-               "  }\n"
-               "  catch (const Exception &e) {\n"
+               "  } catch (const Exception &e) {\n"
                "  }\n"
                "}\n",
                getLLVMStyle());

Modified: cfe/trunk/unittests/Format/FormatTestJS.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestJS.cpp?rev=208302&r1=208301&r2=208302&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTestJS.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestJS.cpp Thu May  8 06:58:24 2014
@@ -118,6 +118,16 @@ TEST_F(FormatTestJS, ClosureStyleComment
   verifyFormat("var x = /** @type {foo} */ (bar);");
 }
 
+TEST_F(FormatTestJS, TryCatch) {
+  verifyFormat("try {\n"
+               "  f();\n"
+               "} catch (e) {\n"
+               "  g();\n"
+               "} finally {\n"
+               "  h();\n"
+               "}");
+}
+
 TEST_F(FormatTestJS, RegexLiteralClassification) {
   // Regex literals.
   verifyFormat("var regex = /abc/;");





More information about the cfe-commits mailing list