diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 08387d2e08ee073..899e68eadf70e9e 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -112,6 +112,7 @@ class ScopedLineState { Parser.Line->PPLevel = PreBlockLine->PPLevel; Parser.Line->InPPDirective = PreBlockLine->InPPDirective; Parser.Line->InMacroBody = PreBlockLine->InMacroBody; + Parser.Line->UnbracedBodyLevel = PreBlockLine->UnbracedBodyLevel; } ~ScopedLineState() { @@ -2708,7 +2709,9 @@ void UnwrappedLineParser::parseUnbracedBody(bool CheckEOF) { addUnwrappedLine(); ++Line->Level; + ++Line->UnbracedBodyLevel; parseStructuralElement(); + --Line->UnbracedBodyLevel; if (Tok) { assert(!Line->InPPDirective); @@ -4836,6 +4839,8 @@ void UnwrappedLineParser::readToken(int LevelDifference) { PPBranchLevel > 0) { Line->Level += PPBranchLevel; } + assert(Line->Level >= Line->UnbracedBodyLevel); + Line->Level -= Line->UnbracedBodyLevel; flushComments(isOnNewLine(*FormatTok)); parsePPDirective(); PreviousWasComment = FormatTok->is(tok::comment); diff --git a/clang/lib/Format/UnwrappedLineParser.h b/clang/lib/Format/UnwrappedLineParser.h index d7963a4211bb906..d5eeb3d57149cb9 100644 --- a/clang/lib/Format/UnwrappedLineParser.h +++ b/clang/lib/Format/UnwrappedLineParser.h @@ -49,6 +49,9 @@ struct UnwrappedLine { /// Whether it is part of a macro body. bool InMacroBody = false; + /// Nesting level of unbraced body of a control statement. + unsigned UnbracedBodyLevel = 0; + bool MustBeDeclaration = false; /// Whether the parser has seen \c decltype(auto) in this line. diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index d2baace6a7d8093..3e75707a9faecc5 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -1087,6 +1087,36 @@ TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) { Style); } +TEST_F(FormatTestComments, CommentsBetweenUnbracedBodyAndPPDirective) { + verifyFormat("{\n" + " if (a)\n" + " f(); // comment\n" + "#define A\n" + "}"); + + verifyFormat("{\n" + " while (a)\n" + " f();\n" + "// comment\n" + "#define A\n" + "}"); + + verifyNoChange("{\n" + " if (a)\n" + " f();\n" + " // comment\n" + "#define A\n" + "}"); + + verifyNoChange("{\n" + " while (a)\n" + " if (b)\n" + " f();\n" + " // comment\n" + "#define A\n" + "}"); +} + TEST_F(FormatTestComments, SplitsLongLinesInComments) { // FIXME: Do we need to fix up the " */" at the end? // It doesn't look like any of our current logic triggers this.