https://github.com/rymiel updated https://github.com/llvm/llvm-project/pull/65409:
>From e15868400981600b7dc68229660391a7874e67af Mon Sep 17 00:00:00 2001 From: Emilia Kond <emilia@rymiel.space> Date: Tue, 5 Sep 2023 22:44:41 +0300 Subject: [PATCH 1/2] [clang-format] Correctly annotate designated initializer with PP if 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 --- clang/lib/Format/UnwrappedLineParser.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 35 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 5a82b200055a874..eaebc69879b9732 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -626,6 +626,8 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { case tok::kw_switch: case tok::kw_try: case tok::kw___try: + if (PrevTok->is(tok::hash)) + break; if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown)) LBraceStack.back().Tok->setBlockKind(BK_Block); break; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 467ade965d7c86a..ac2b60530f2fb18 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1998,6 +1998,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 >From 88c1e108cc191ddc1c288b57ae202603d4daa962 Mon Sep 17 00:00:00 2001 From: Emilia Kond <emilia@rymiel.space> Date: Thu, 7 Sep 2023 21:34:31 +0300 Subject: [PATCH 2/2] address comments --- clang/lib/Format/UnwrappedLineParser.cpp | 7 ++++--- clang/unittests/Format/TokenAnnotatorTest.cpp | 20 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index eaebc69879b9732..dae2742d27fcbde 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -618,16 +618,17 @@ 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: case tok::kw_try: case tok::kw___try: - if (PrevTok->is(tok::hash)) - break; if (!LBraceStack.empty() && LBraceStack.back().Tok->is(BK_Unknown)) LBraceStack.back().Tok->setBlockKind(BK_Block); break; diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index ac2b60530f2fb18..7ac6bd32620e3d8 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2011,22 +2011,22 @@ TEST_F(TokenAnnotatorTest, UnderstandDesignatedInitializers) { EXPECT_TOKEN(Tokens[7], tok::period, TT_DesignatedInitializerPeriod); Tokens = annotate("SomeStruct {\n" - "#ifdef FOO\n" - " .a = 1,\n" - "#endif\n" - " .b = 2\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" - "};"); + "#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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits