r228148 - clang-format: Add support for SEH __try / __except / __finally blocks.
Nico Weber
nicolasweber at gmx.de
Wed Feb 4 07:26:27 PST 2015
Author: nico
Date: Wed Feb 4 09:26:27 2015
New Revision: 228148
URL: http://llvm.org/viewvc/llvm-project?rev=228148&view=rev
Log:
clang-format: Add support for SEH __try / __except / __finally blocks.
This lets clang-format format
__try {
} __except(0) {
}
and
__try {
} __finally {
}
correctly. __try and __finally are keywords if `LangOpts.MicrosoftExt` is set,
so this turns this on. This also enables a few other keywords, but it
shouldn't overly perturb regular clang-format operation. __except is a
context-sensitive keyword, so `AdditionalKeywords` needs to be passed around to
a few more places.
Fixes PR22321.
Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/FormatToken.h
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
cfe/trunk/lib/Format/UnwrappedLineFormatter.h
cfe/trunk/lib/Format/UnwrappedLineParser.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Wed Feb 4 09:26:27 2015
@@ -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
LangOpts.Bool = 1;
LangOpts.ObjC1 = 1;
LangOpts.ObjC2 = 1;
+ LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
return LangOpts;
}
Modified: cfe/trunk/lib/Format/FormatToken.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatToken.h?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/lib/Format/FormatToken.h (original)
+++ cfe/trunk/lib/Format/FormatToken.h Wed Feb 4 09:26:27 2015
@@ -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;
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Wed Feb 4 09:26:27 2015
@@ -1701,8 +1701,8 @@ bool TokenAnnotator::spaceRequiredBetwee
(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 &&
Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.cpp Wed Feb 4 09:26:27 2015
@@ -27,7 +27,8 @@ bool startsExternCBlock(const AnnotatedL
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(
Modified: cfe/trunk/lib/Format/UnwrappedLineFormatter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineFormatter.h?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineFormatter.h (original)
+++ cfe/trunk/lib/Format/UnwrappedLineFormatter.h Wed Feb 4 09:26:27 2015
@@ -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;
Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original)
+++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Wed Feb 4 09:26:27 2015
@@ -374,6 +374,7 @@ void UnwrappedLineParser::calculateBrace
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::parseStructura
parseCaseLabel();
return;
case tok::kw_try:
+ case tok::kw___try:
parseTryCatch();
return;
case tok::kw_extern:
@@ -1149,7 +1151,7 @@ void UnwrappedLineParser::parseIfThenEls
}
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))) {
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=228148&r1=228147&r2=228148&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Wed Feb 4 09:26:27 2015
@@ -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, FormatTryCatchBraceSt
" // something\n"
"}",
Style);
+ verifyFormat("__try {\n"
+ " // something\n"
+ "}\n"
+ "__finally {\n"
+ " // something\n"
+ "}",
+ Style);
Style.BreakBeforeBraces = FormatStyle::BS_Allman;
verifyFormat("try\n"
"{\n"
More information about the cfe-commits
mailing list