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();
}
LangOpts.Bool = 1;
LangOpts.ObjC1 = 1;
LangOpts.ObjC2 = 1;
+ LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally.
return LangOpts;
}
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");
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;
(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 &&
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
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 &&
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;
}
}
const FormatStyle &Style;
+ const AdditionalKeywords &Keywords;
};
class NoColumnLimitFormatter {
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(
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);
ContinuationIndenter *Indenter;
WhitespaceManager *Whitespaces;
FormatStyle Style;
+ const AdditionalKeywords &Keywords;
llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
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;
parseCaseLabel();
return;
case tok::kw_try:
+ case tok::kw___try:
parseTryCatch();
return;
case tok::kw_extern:
}
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)) {
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))) {
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"
" // something\n"
"}",
Style);
+ verifyFormat("__try {\n"
+ " // something\n"
+ "}\n"
+ "__finally {\n"
+ " // something\n"
+ "}",
+ Style);
Style.BreakBeforeBraces = FormatStyle::BS_Allman;
verifyFormat("try\n"
"{\n"