Author: ksyx Date: 2022-02-08T10:29:18-08:00 New Revision: 39e9a64cf5847935c2ba0099f4bf39945d8ee19b
URL: https://github.com/llvm/llvm-project/commit/39e9a64cf5847935c2ba0099f4bf39945d8ee19b DIFF: https://github.com/llvm/llvm-project/commit/39e9a64cf5847935c2ba0099f4bf39945d8ee19b.diff LOG: [clang-format] Fix DefSeparator empty line issues - Add or remove empty lines surrounding union blocks. - Fixes https://github.com/llvm/llvm-project/issues/53229, in which keywords like class and struct in a line ending with left brace or whose next line is left brace only, will be falsely recognized as definition line, causing extra empty lines inserted surrounding blocks with no need to be formatted. Reviewed By: MyDeveloperDay, curdeius, HazardyKnusperkeks, owenpan Differential Revision: https://reviews.llvm.org/D119067 (cherry picked from commit a70549ae43dfa551f3eacdfa7a7f2c0df073be8e) Added: Modified: clang/lib/Format/DefinitionBlockSeparator.cpp clang/unittests/Format/DefinitionBlockSeparatorTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/DefinitionBlockSeparator.cpp b/clang/lib/Format/DefinitionBlockSeparator.cpp index 827564357f788..cfb019a471dce 100644 --- a/clang/lib/Format/DefinitionBlockSeparator.cpp +++ b/clang/lib/Format/DefinitionBlockSeparator.cpp @@ -35,19 +35,31 @@ void DefinitionBlockSeparator::separateBlocks( const bool IsNeverStyle = Style.SeparateDefinitionBlocks == FormatStyle::SDS_Never; const AdditionalKeywords &ExtraKeywords = Tokens.getKeywords(); - auto LikelyDefinition = [this, ExtraKeywords](const AnnotatedLine *Line, - bool ExcludeEnum = false) { + auto GetBracketLevelChange = [](const FormatToken *Tok) { + if (Tok->isOneOf(tok::l_brace, tok::l_paren, tok::l_square)) + return 1; + if (Tok->isOneOf(tok::r_brace, tok::r_paren, tok::r_square)) + return -1; + return 0; + }; + auto LikelyDefinition = [&](const AnnotatedLine *Line, + bool ExcludeEnum = false) { if ((Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition()) || Line->startsWithNamespace()) return true; - FormatToken *CurrentToken = Line->First; - while (CurrentToken) { - if (CurrentToken->isOneOf(tok::kw_class, tok::kw_struct) || - (Style.isJavaScript() && CurrentToken->is(ExtraKeywords.kw_function))) - return true; - if (!ExcludeEnum && CurrentToken->is(tok::kw_enum)) - return true; - CurrentToken = CurrentToken->Next; + int BracketLevel = 0; + for (const FormatToken *CurrentToken = Line->First; CurrentToken; + CurrentToken = CurrentToken->Next) { + if (BracketLevel == 0) { + if ((CurrentToken->isOneOf(tok::kw_class, tok::kw_struct, + tok::kw_union) || + (Style.isJavaScript() && + CurrentToken->is(ExtraKeywords.kw_function)))) + return true; + if (!ExcludeEnum && CurrentToken->is(tok::kw_enum)) + return true; + } + BracketLevel += GetBracketLevelChange(CurrentToken); } return false; }; @@ -102,14 +114,17 @@ void DefinitionBlockSeparator::separateBlocks( IsPPConditional(OpeningLineIndex - 1); }; const auto HasEnumOnLine = [&]() { - FormatToken *CurrentToken = CurrentLine->First; bool FoundEnumKeyword = false; - while (CurrentToken) { - if (CurrentToken->is(tok::kw_enum)) - FoundEnumKeyword = true; - else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace)) - return true; - CurrentToken = CurrentToken->Next; + int BracketLevel = 0; + for (const FormatToken *CurrentToken = CurrentLine->First; CurrentToken; + CurrentToken = CurrentToken->Next) { + if (BracketLevel == 0) { + if (CurrentToken->is(tok::kw_enum)) + FoundEnumKeyword = true; + else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace)) + return true; + } + BracketLevel += GetBracketLevelChange(CurrentToken); } return FoundEnumKeyword && I + 1 < Lines.size() && Lines[I + 1]->First->is(tok::l_brace); diff --git a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp index 4cbae0f55b036..582b62e445df9 100644 --- a/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp +++ b/clang/unittests/Format/DefinitionBlockSeparatorTest.cpp @@ -109,6 +109,15 @@ TEST_F(DefinitionBlockSeparatorTest, Basic) { "};", Style); + verifyFormat("union foo {\n" + " int i, j;\n" + "};\n" + "\n" + "union bar {\n" + " int j, k;\n" + "};", + Style); + verifyFormat("class foo {\n" " int i, j;\n" "};\n" @@ -311,6 +320,9 @@ TEST_F(DefinitionBlockSeparatorTest, Always) { "int bar3(int j, int k, const enum Bar b) {\n" " // A comment\n" " int r = j % k;\n" + " if (struct S = getS()) {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n"; std::string Postfix = "\n" @@ -364,6 +376,9 @@ TEST_F(DefinitionBlockSeparatorTest, Never) { "int bar3(int j, int k, const enum Bar b) {\n" " // A comment\n" " int r = j % k;\n" + " if (struct S = getS()) {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "} // namespace"; @@ -425,6 +440,10 @@ TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) { "{\n" " // A comment\n" " int r = j % k;\n" + " if (struct S = getS())\n" + " {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "} // namespace NS", @@ -473,6 +492,9 @@ TEST_F(DefinitionBlockSeparatorTest, Leave) { "int bar3(int j, int k, const enum Bar b) {\n" " // A comment\n" " int r = j % k;\n" + " if (struct S = getS()) {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "} // namespace"; _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
