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() && 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"