Index: lib/Format/UnwrappedLineParser.h =================================================================== --- lib/Format/UnwrappedLineParser.h +++ lib/Format/UnwrappedLineParser.h @@ -87,6 +87,8 @@ void parseIfThenElse(); void parseForOrWhileLoop(); void parseDoWhile(); + void parseTry(); + void parseCatch(); void parseLabel(); void parseCaseLabel(); void parseSwitch(); Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -643,6 +643,12 @@ case tok::kw_case: parseCaseLabel(); return; + case tok::kw_try: + parseTry(); + return; + case tok::kw_catch: + parseCatch(); + return; case tok::kw_extern: nextToken(); if (FormatTok->Tok.is(tok::string_literal)) { @@ -1073,6 +1079,48 @@ parseStructuralElement(); } +void UnwrappedLineParser::parseTry() { + assert(FormatTok->Tok.is(tok::kw_try) && "'try' expected"); + nextToken(); + + if (FormatTok->Tok.is(tok::l_brace)) { + CompoundStatementIndenter Indenter(this, Style, Line->Level); + parseBlock(/*MustBeDeclaration=*/false); + + if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) + addUnwrappedLine(); + } else { + // FIXME: Add error handling. + addUnwrappedLine(); + return; + } +} + +void UnwrappedLineParser::parseCatch() { + assert(FormatTok->Tok.is(tok::kw_catch) && "'catch' expected"); + nextToken(); + + if (FormatTok->Tok.is(tok::l_paren)) { + parseParens(); + } + + if (FormatTok->Tok.is(tok::l_brace)) { + CompoundStatementIndenter Indenter(this, Style, Line->Level); + parseBlock(/*MustBeDeclaration=*/false); + + if (FormatTok->Tok.is(tok::kw_catch)) { + if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) + addUnwrappedLine(); + } else { + addUnwrappedLine(); + } + } else { + // FIXME: Add error handling. + addUnwrappedLine(); + return; + } +} + void UnwrappedLineParser::parseLabel() { nextToken(); unsigned OldLineLevel = Line->Level; Index: test/Format/try-catch.cpp =================================================================== --- test/Format/try-catch.cpp +++ test/Format/try-catch.cpp @@ -0,0 +1,26 @@ +// RUN: grep -Ev "// *[A-Z0-9-]+:" %s > %t.cpp +// RUN: clang-format -style="{BasedOnStyle: Google, BreakBeforeBraces: Stroustrup}" %t.cpp | FileCheck %s -strict-whitespace -check-prefix=CHECK1 +// RUN: clang-format -style="{BasedOnStyle: Google, BreakBeforeBraces: GNU}" %t.cpp | FileCheck %s -strict-whitespace -check-prefix=CHECK2 +// CHECK1: {{^\ \ try\ \{}} +// CHECK1-NEXT: {{^\ \ \ \ g\(\);}} +// CHECK1-NEXT: {{^\ \ \} catch \(int\) \{}} +// CHECK1-NEXT: {{^\ \ \ \ g\(\);}} +// CHECK1-NEXT: {{^\ \ \} catch \(\.\.\.\) \{}} +// CHECK1-NEXT: {{^\ \ \ \ g\(\);}} +// CHECK1-NEXT: {{^\ \ [}]}} +// CHECK2: {{^\ \ try}} +// CHECK2-NEXT: {{^\ \ \ \ {}} +// CHECK2-NEXT: {{^\ \ \ \ \ \ g\(\);}} +// CHECK2-NEXT: {{^\ \ \ \ [}]}} +// CHECK2-NEXT: {{^\ \ catch \(int\)}} +// CHECK2-NEXT: {{^\ \ \ \ {}} +// CHECK2-NEXT: {{^\ \ \ \ \ \ g\(\);}} +// CHECK2-NEXT: {{^\ \ \ \ [}]}} +// CHECK2-NEXT: {{^\ \ catch \(\.\.\.\)}} +// CHECK2-NEXT: {{^\ \ \ \ {}} +// CHECK2-NEXT: {{^\ \ \ \ \ \ g\(\);}} +// CHECK2-NEXT: {{^\ \ \ \ [}]}} + +void g(); + +void f() { try { g(); } catch (int) { g(); } catch (...) { g(); } }