diff options
-rw-r--r-- | clang/lib/Format/Format.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Format/FormatToken.h | 4 | ||||
-rw-r--r-- | clang/lib/Format/TokenAnnotator.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineFormatter.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineFormatter.h | 7 | ||||
-rw-r--r-- | clang/lib/Format/UnwrappedLineParser.cpp | 7 | ||||
-rw-r--r-- | clang/unittests/Format/FormatTest.cpp | 27 |
7 files changed, 57 insertions, 12 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 128a5a78889..309b3221d81 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -1123,7 +1123,8 @@ public: ContinuationIndenter Indenter(Style, Tokens.getKeywords(), SourceMgr, Whitespaces, Encoding, BinPackInconclusiveFunctions); - UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style); + UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style, + Tokens.getKeywords()); Formatter.format(AnnotatedLines, /*DryRun=*/false); return Whitespaces.generateReplacements(); } @@ -1399,6 +1400,7 @@ LangOptions getFormattingLangOpts(const FormatStyle &Style) { LangOpts.Bool = 1; LangOpts.ObjC1 = 1; LangOpts.ObjC2 = 1; + LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. return LangOpts; } diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 4811e02dd22..036e1edacac 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -555,6 +555,7 @@ struct AdditionalKeywords { kw_package = &IdentTable.get("package"); kw_synchronized = &IdentTable.get("synchronized"); kw_throws = &IdentTable.get("throws"); + kw___except = &IdentTable.get("__except"); kw_option = &IdentTable.get("option"); kw_optional = &IdentTable.get("optional"); @@ -563,12 +564,13 @@ struct AdditionalKeywords { kw_returns = &IdentTable.get("returns"); } - // ObjC context sensitive keywords. + // Context sensitive keywords. IdentifierInfo *kw_in; IdentifierInfo *kw_CF_ENUM; IdentifierInfo *kw_CF_OPTIONS; IdentifierInfo *kw_NS_ENUM; IdentifierInfo *kw_NS_OPTIONS; + IdentifierInfo *kw___except; // JavaScript keywords. IdentifierInfo *kw_finally; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 02f80ae98d6..e00db2127d6 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1701,8 +1701,8 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line, (Style.SpaceBeforeParens != FormatStyle::SBPO_Never && (Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch, tok::kw_case) || - (Left.isOneOf(tok::kw_try, tok::kw_catch, tok::kw_new, - tok::kw_delete) && + (Left.isOneOf(tok::kw_try, Keywords.kw___except, tok::kw_catch, + tok::kw_new, tok::kw_delete) && (!Left.Previous || Left.Previous->isNot(tok::period))) || Left.IsForEachMacro)) || (Style.SpaceBeforeParens == FormatStyle::SBPO_Always && diff --git a/clang/lib/Format/UnwrappedLineFormatter.cpp b/clang/lib/Format/UnwrappedLineFormatter.cpp index 4844b66f9fd..0c744e493f0 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.cpp +++ b/clang/lib/Format/UnwrappedLineFormatter.cpp @@ -27,7 +27,8 @@ bool startsExternCBlock(const AnnotatedLine &Line) { class LineJoiner { public: - LineJoiner(const FormatStyle &Style) : Style(Style) {} + LineJoiner(const FormatStyle &Style, const AdditionalKeywords &Keywords) + : Style(Style), Keywords(Keywords) {} /// \brief Calculates how many lines can be merged into 1 starting at \p I. unsigned @@ -200,7 +201,9 @@ private: if (Line.First->isOneOf(tok::kw_else, tok::kw_case)) return 0; if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try, - tok::kw_catch, tok::kw_for, tok::r_brace)) { + tok::kw___try, tok::kw_catch, tok::kw___finally, + tok::kw_for, tok::r_brace) || + Line.First->is(Keywords.kw___except)) { if (!Style.AllowShortBlocksOnASingleLine) return 0; if (!Style.AllowShortIfStatementsOnASingleLine && @@ -211,7 +214,11 @@ private: return 0; // FIXME: Consider an option to allow short exception handling clauses on // a single line. - if (Line.First->isOneOf(tok::kw_try, tok::kw_catch)) + // FIXME: This isn't covered by tests. + // FIXME: For catch, __except, __finally the first token on the line + // is '}', so this isn't correct here. + if (Line.First->isOneOf(tok::kw_try, tok::kw___try, tok::kw_catch, + Keywords.kw___except, tok::kw___finally)) return 0; } @@ -286,6 +293,7 @@ private: } const FormatStyle &Style; + const AdditionalKeywords &Keywords; }; class NoColumnLimitFormatter { @@ -324,7 +332,7 @@ unsigned UnwrappedLineFormatter::format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun, int AdditionalIndent, bool FixBadIndentation) { - LineJoiner Joiner(Style); + LineJoiner Joiner(Style, Keywords); // Try to look up already computed penalty in DryRun-mode. std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey( diff --git a/clang/lib/Format/UnwrappedLineFormatter.h b/clang/lib/Format/UnwrappedLineFormatter.h index 3ae6dbc4db0..5e0261210d4 100644 --- a/clang/lib/Format/UnwrappedLineFormatter.h +++ b/clang/lib/Format/UnwrappedLineFormatter.h @@ -32,8 +32,10 @@ class UnwrappedLineFormatter { public: UnwrappedLineFormatter(ContinuationIndenter *Indenter, WhitespaceManager *Whitespaces, - const FormatStyle &Style) - : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style) {} + const FormatStyle &Style, + const AdditionalKeywords &Keywords) + : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style), + Keywords(Keywords) {} unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun, int AdditionalIndent = 0, bool FixBadIndentation = false); @@ -153,6 +155,7 @@ private: ContinuationIndenter *Indenter; WhitespaceManager *Whitespaces; FormatStyle Style; + const AdditionalKeywords &Keywords; llvm::SpecificBumpPtrAllocator<StateNode> Allocator; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 23b9d550fb1..47b3b9c6b89 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -374,6 +374,7 @@ void UnwrappedLineParser::calculateBraceTypes() { case tok::kw_for: case tok::kw_switch: case tok::kw_try: + case tok::kw___try: if (!LBraceStack.empty()) LBraceStack.back()->BlockKind = BK_Block; break; @@ -713,6 +714,7 @@ void UnwrappedLineParser::parseStructuralElement() { parseCaseLabel(); return; case tok::kw_try: + case tok::kw___try: parseTryCatch(); return; case tok::kw_extern: @@ -1149,7 +1151,7 @@ void UnwrappedLineParser::parseIfThenElse() { } void UnwrappedLineParser::parseTryCatch() { - assert(FormatTok->is(tok::kw_try) && "'try' expected"); + assert(FormatTok->isOneOf(tok::kw_try, tok::kw___try) && "'try' expected"); nextToken(); bool NeedsUnwrappedLine = false; if (FormatTok->is(tok::colon)) { @@ -1189,7 +1191,8 @@ void UnwrappedLineParser::parseTryCatch() { parseStructuralElement(); --Line->Level; } - while (FormatTok->is(tok::kw_catch) || + while (FormatTok->isOneOf(tok::kw_catch, Keywords.kw___except, + tok::kw___finally) || ((Style.Language == FormatStyle::LK_Java || Style.Language == FormatStyle::LK_JavaScript) && FormatTok->is(Keywords.kw_finally))) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index f099f20a6e5..b88bdb906f1 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -2244,6 +2244,26 @@ TEST_F(FormatTest, FormatTryCatch) { verifyFormat("try {} catch ("); } +TEST_F(FormatTest, FormatSEHTryCatch) { + verifyFormat("__try {\n" + " int a = b * c;\n" + "} __except (EXCEPTION_EXECUTE_HANDLER) {\n" + " // Do nothing.\n" + "}"); + + verifyFormat("__try {\n" + " int a = b * c;\n" + "} __finally {\n" + " // Do nothing.\n" + "}"); + + verifyFormat("DEBUG({\n" + " __try {\n" + " } __finally {\n" + " }\n" + "});\n"); +} + TEST_F(FormatTest, IncompleteTryCatchBlocks) { verifyFormat("try {\n" " f();\n" @@ -2276,6 +2296,13 @@ TEST_F(FormatTest, FormatTryCatchBraceStyles) { " // something\n" "}", Style); + verifyFormat("__try {\n" + " // something\n" + "}\n" + "__finally {\n" + " // something\n" + "}", + Style); Style.BreakBeforeBraces = FormatStyle::BS_Allman; verifyFormat("try\n" "{\n" |