ksyx created this revision. ksyx added reviewers: MyDeveloperDay, curdeius, HazardyKnusperkeks. ksyx added a project: clang-format. ksyx requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This commit 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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D119067 Files: clang/lib/Format/DefinitionBlockSeparator.cpp clang/unittests/Format/DefinitionBlockSeparatorTest.cpp
Index: clang/unittests/Format/DefinitionBlockSeparatorTest.cpp =================================================================== --- clang/unittests/Format/DefinitionBlockSeparatorTest.cpp +++ clang/unittests/Format/DefinitionBlockSeparatorTest.cpp @@ -302,6 +302,9 @@ "\n" "int bar2(int j, int k) {\n" " int r = j / k;\n" + " if (struct S = getS()) {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "\n" @@ -355,6 +358,9 @@ "\n" "int bar2(int j, int k) {\n" " int r = j / k;\n" + " if (struct S = getS()) {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "\n" @@ -412,6 +418,10 @@ "int bar2(int j, int k)\n" "{\n" " int r = j / k;\n" + " if (struct S = getS())\n" + " {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "\n" @@ -465,6 +475,9 @@ "\n" "int bar2(int j, int k) {\n" " int r = j / k;\n" + " if (struct S = getS()) {\n" + " // if condition\n" + " }\n" " return r;\n" "}\n" "\n" Index: clang/lib/Format/DefinitionBlockSeparator.cpp =================================================================== --- clang/lib/Format/DefinitionBlockSeparator.cpp +++ clang/lib/Format/DefinitionBlockSeparator.cpp @@ -35,18 +35,31 @@ 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; + else if (Tok->isOneOf(tok::r_brace, tok::r_paren, tok::r_square)) + return -1; + else + return 0; + }; + auto LikelyDefinition = [&](const AnnotatedLine *Line, + bool ExcludeEnum = false) { if ((Line->MightBeFunctionDecl && Line->mightBeFunctionDefinition()) || Line->startsWithNamespace()) return true; FormatToken *CurrentToken = Line->First; + int BracketLevel = 0; 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; + if (BracketLevel == 0) { + 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; + } + BracketLevel += GetBracketLevelChange(CurrentToken); CurrentToken = CurrentToken->Next; } return false; @@ -104,11 +117,15 @@ const auto HasEnumOnLine = [&]() { FormatToken *CurrentToken = CurrentLine->First; bool FoundEnumKeyword = false; + int BracketLevel = 0; while (CurrentToken) { - if (CurrentToken->is(tok::kw_enum)) - FoundEnumKeyword = true; - else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace)) - return true; + if (BracketLevel == 0) { + if (CurrentToken->is(tok::kw_enum)) + FoundEnumKeyword = true; + else if (FoundEnumKeyword && CurrentToken->is(tok::l_brace)) + return true; + } + BracketLevel += GetBracketLevelChange(CurrentToken); CurrentToken = CurrentToken->Next; } return FoundEnumKeyword && I + 1 < Lines.size() &&
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits