Skip to content

Commit 063e3fe

Browse files
authored
[clang-format] Skip PP directives when determining brace kind (#69473)
Pull request #65409 changed the brace kind heuristic to not treat a preprocessor if directive as a in statement, however, this caused some regressions. If the contents of a brace don't immediately determine the brace kind, the heuristic will look at the characters immediately before and after the closing brace to determine the brace type. Unfortunately, if the closing brace was preceded by a preprocessor directive, for example `#endif`, the preceding token was `endif`, seen as just an identifier, so the braces were understood as a braced list. This patch fixes this behaviour by skipping all preprocessor directives when calculating brace types. Comments were already being skipped, so now preprocessor lines are skipped alongside comments. Fixes #68404
1 parent b5b251a commit 063e3fe

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -491,11 +491,18 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
491491
SmallVector<StackEntry, 8> LBraceStack;
492492
assert(Tok->is(tok::l_brace));
493493
do {
494-
// Get next non-comment token.
494+
// Get next non-comment, non-preprocessor token.
495495
FormatToken *NextTok;
496496
do {
497497
NextTok = Tokens->getNextToken();
498498
} while (NextTok->is(tok::comment));
499+
while (NextTok->is(tok::hash)) {
500+
NextTok = Tokens->getNextToken();
501+
do {
502+
NextTok = Tokens->getNextToken();
503+
} while (NextTok->is(tok::comment) ||
504+
(NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof)));
505+
}
499506

500507
switch (Tok->Tok.getKind()) {
501508
case tok::l_brace:
@@ -611,12 +618,9 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
611618
if (Tok->isNot(TT_StatementMacro))
612619
break;
613620
[[fallthrough]];
614-
case tok::kw_if:
615-
if (PrevTok->is(tok::hash))
616-
break;
617-
[[fallthrough]];
618621
case tok::at:
619622
case tok::semi:
623+
case tok::kw_if:
620624
case tok::kw_while:
621625
case tok::kw_for:
622626
case tok::kw_switch:

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,6 +2152,7 @@ TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
21522152
EXPECT_TOKEN(Tokens[11], tok::l_paren, TT_Unknown);
21532153
EXPECT_TOKEN(Tokens[12], tok::r_paren, TT_Unknown);
21542154
EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace);
2155+
EXPECT_BRACE_KIND(Tokens[13], BK_Block);
21552156

21562157
Tokens = annotate("Class::Class() : BaseClass{}, Member{} {}");
21572158
ASSERT_EQ(Tokens.size(), 16u) << Tokens;
@@ -2164,6 +2165,20 @@ TEST_F(TokenAnnotatorTest, UnderstandConstructors) {
21642165
EXPECT_TOKEN(Tokens[11], tok::l_brace, TT_Unknown);
21652166
EXPECT_TOKEN(Tokens[12], tok::r_brace, TT_Unknown);
21662167
EXPECT_TOKEN(Tokens[13], tok::l_brace, TT_FunctionLBrace);
2168+
EXPECT_BRACE_KIND(Tokens[13], BK_Block);
2169+
2170+
Tokens = annotate("class Class {\n"
2171+
" Class() : BaseClass() {\n"
2172+
"#if 0\n"
2173+
" // comment\n"
2174+
"#endif\n"
2175+
" }\n"
2176+
" Class f();\n"
2177+
"}");
2178+
ASSERT_EQ(Tokens.size(), 25u) << Tokens;
2179+
EXPECT_TOKEN(Tokens[6], tok::colon, TT_CtorInitializerColon);
2180+
EXPECT_TOKEN(Tokens[10], tok::l_brace, TT_FunctionLBrace);
2181+
EXPECT_BRACE_KIND(Tokens[10], BK_Block);
21672182
}
21682183

21692184
TEST_F(TokenAnnotatorTest, UnderstandsConditionParens) {

0 commit comments

Comments
 (0)