[clang] e9ed1aa - [clang-format] Correctly annotate designated initializer with PP if (#65409)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 7 12:23:09 PDT 2023
Author: Emilia Kond
Date: 2023-09-07T22:23:05+03:00
New Revision: e9ed1aa9cd867938cd05fe76df57eb505591e81a
URL: https://github.com/llvm/llvm-project/commit/e9ed1aa9cd867938cd05fe76df57eb505591e81a
DIFF: https://github.com/llvm/llvm-project/commit/e9ed1aa9cd867938cd05fe76df57eb505591e81a.diff
LOG: [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 https://github.com/llvm/llvm-project/issues/56685
Added:
Modified:
clang/lib/Format/UnwrappedLineParser.cpp
clang/unittests/Format/TokenAnnotatorTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp
index da55948a367b78f..0ff0656a92d7222 100644
--- a/clang/lib/Format/UnwrappedLineParser.cpp
+++ b/clang/lib/Format/UnwrappedLineParser.cpp
@@ -618,9 +618,12 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
if (Tok->isNot(TT_StatementMacro))
break;
[[fallthrough]];
+ case tok::kw_if:
+ if (PrevTok->is(tok::hash))
+ break;
+ [[fallthrough]];
case tok::at:
case tok::semi:
- case tok::kw_if:
case tok::kw_while:
case tok::kw_for:
case tok::kw_switch:
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 66bfd7f0ef0d282..434852983712940 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2005,6 +2005,41 @@ TEST_F(TokenAnnotatorTest, UnderstandsNestedBlocks) {
EXPECT_BRACE_KIND(Tokens[10], BK_Block);
}
+TEST_F(TokenAnnotatorTest, UnderstandDesignatedInitializers) {
+ auto Tokens = annotate("SomeStruct { .a = 1 };");
+ ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+ EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
+ EXPECT_TOKEN(Tokens[2], tok::period, TT_DesignatedInitializerPeriod);
+
+ Tokens = annotate("SomeStruct { .a = 1, .b = 2 };");
+ ASSERT_EQ(Tokens.size(), 14u) << Tokens;
+ EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
+ EXPECT_TOKEN(Tokens[2], tok::period, TT_DesignatedInitializerPeriod);
+ EXPECT_TOKEN(Tokens[7], tok::period, TT_DesignatedInitializerPeriod);
+
+ Tokens = annotate("SomeStruct {\n"
+ "#ifdef FOO\n"
+ " .a = 1,\n"
+ "#endif\n"
+ " .b = 2\n"
+ "};");
+ ASSERT_EQ(Tokens.size(), 19u) << Tokens;
+ EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
+ EXPECT_TOKEN(Tokens[5], tok::period, TT_DesignatedInitializerPeriod);
+ EXPECT_TOKEN(Tokens[12], tok::period, TT_DesignatedInitializerPeriod);
+
+ Tokens = annotate("SomeStruct {\n"
+ "#if defined FOO\n"
+ " .a = 1,\n"
+ "#endif\n"
+ " .b = 2\n"
+ "};");
+ ASSERT_EQ(Tokens.size(), 20u) << Tokens;
+ EXPECT_BRACE_KIND(Tokens[1], BK_BracedInit);
+ EXPECT_TOKEN(Tokens[6], tok::period, TT_DesignatedInitializerPeriod);
+ EXPECT_TOKEN(Tokens[13], tok::period, TT_DesignatedInitializerPeriod);
+}
+
} // namespace
} // namespace format
} // namespace clang
More information about the cfe-commits
mailing list