Skip to content

Commit e9ed1aa

Browse files
authored
[clang-format] Correctly annotate designated initializer with PP if (#65409)
When encountering braces, such as those of a designated initializer, clang-format scans ahead to see what is contained within the braces. If it found a statement, like an if-statement of for-loop, it would deem the braces as not an initializer, but as a block instead. However, this heuristic incorrectly included a preprocessor `#if` line as an if-statement. This manifested in strange results and discrepancies between `#ifdef` and `#if defined`. With this patch, `if` is now ignored if it is preceeded by `#`. Fixes most of #56685
1 parent 80f0dc3 commit e9ed1aa

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,9 +618,12 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
618618
if (Tok->isNot(TT_StatementMacro))
619619
break;
620620
[[fallthrough]];
621+
case tok::kw_if:
622+
if (PrevTok->is(tok::hash))
623+
break;
624+
[[fallthrough]];
621625
case tok::at:
622626
case tok::semi:
623-
case tok::kw_if:
624627
case tok::kw_while:
625628
case tok::kw_for:
626629
case tok::kw_switch:

clang/unittests/Format/TokenAnnotatorTest.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,6 +2005,41 @@ TEST_F(TokenAnnotatorTest, UnderstandsNestedBlocks) {
20052005
EXPECT_BRACE_KIND(Tokens[10], BK_Block);
20062006
}
20072007

2008+
TEST_F(TokenAnnotatorTest, UnderstandDesignatedInitializers) {
2009+
auto Tokens = annotate("SomeStruct { .a = 1 };");
2010+
ASSERT_EQ(Tokens.size(), 9u) << Tokens;
2011+
EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
2012+
EXPECT_TOKEN(Tokens[2], tok::period, TT_DesignatedInitializerPeriod);
2013+
2014+
Tokens = annotate("SomeStruct { .a = 1, .b = 2 };");
2015+
ASSERT_EQ(Tokens.size(), 14u) << Tokens;
2016+
EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
2017+
EXPECT_TOKEN(Tokens[2], tok::period, TT_DesignatedInitializerPeriod);
2018+
EXPECT_TOKEN(Tokens[7], tok::period, TT_DesignatedInitializerPeriod);
2019+
2020+
Tokens = annotate("SomeStruct {\n"
2021+
"#ifdef FOO\n"
2022+
" .a = 1,\n"
2023+
"#endif\n"
2024+
" .b = 2\n"
2025+
"};");
2026+
ASSERT_EQ(Tokens.size(), 19u) << Tokens;
2027+
EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
2028+
EXPECT_TOKEN(Tokens[5], tok::period, TT_DesignatedInitializerPeriod);
2029+
EXPECT_TOKEN(Tokens[12], tok::period, TT_DesignatedInitializerPeriod);
2030+
2031+
Tokens = annotate("SomeStruct {\n"
2032+
"#if defined FOO\n"
2033+
" .a = 1,\n"
2034+
"#endif\n"
2035+
" .b = 2\n"
2036+
"};");
2037+
ASSERT_EQ(Tokens.size(), 20u) << Tokens;
2038+
EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
2039+
EXPECT_TOKEN(Tokens[6], tok::period, TT_DesignatedInitializerPeriod);
2040+
EXPECT_TOKEN(Tokens[13], tok::period, TT_DesignatedInitializerPeriod);
2041+
}
2042+
20082043
} // namespace
20092044
} // namespace format
20102045
} // namespace clang

0 commit comments

Comments
 (0)