https://github.com/HazardyKnusperkeks updated https://github.com/llvm/llvm-project/pull/68743
From be24095877e6ddd25e0884ad8aaf3eca4846f38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= <bjo...@hazardy.de> Date: Fri, 20 Oct 2023 13:00:39 +0200 Subject: [PATCH 1/2] [clang-format] Annotate do while while So we can differentiate on the while keyword between a do-while-loop and a normal while-loop. --- clang/lib/Format/FormatToken.h | 1 + clang/lib/Format/UnwrappedLineParser.cpp | 2 ++ clang/unittests/Format/TokenAnnotatorTest.cpp | 10 ++++++++++ 3 files changed, 13 insertions(+) diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 606e9e790ad833b..acd24f836199da1 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -67,6 +67,7 @@ namespace format { TYPE(DesignatedInitializerLSquare) \ TYPE(DesignatedInitializerPeriod) \ TYPE(DictLiteral) \ + TYPE(DoWhile) \ TYPE(ElseLBrace) \ TYPE(ElseRBrace) \ TYPE(EnumLBrace) \ diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 7bb487d020ea6f7..488d8dc07b1eae3 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -3137,6 +3137,8 @@ void UnwrappedLineParser::parseDoWhile() { return; } + FormatTok->setFinalizedType(TT_DoWhile); + // If in Whitesmiths mode, the line with the while() needs to be indented // to the same level as the block. if (Style.BreakBeforeBraces == FormatStyle::BS_Whitesmiths) diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 4dbe2a532c5fdb2..290d0103bb3cf87 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -2334,6 +2334,16 @@ TEST_F(TokenAnnotatorTest, UnderstandsControlStatements) { EXPECT_TOKEN(Tokens[5], tok::r_brace, TT_ControlStatementRBrace); } +TEST_F(TokenAnnotatorTest, UnderstandsDoWhile) { + auto Tokens = annotate("do { ++i; } while ( i > 5 );"); + ASSERT_EQ(Tokens.size(), 14u) << Tokens; + EXPECT_TOKEN(Tokens[6], tok::kw_while, TT_DoWhile); + + Tokens = annotate("do ++i; while ( i > 5 );"); + ASSERT_EQ(Tokens.size(), 12u) << Tokens; + EXPECT_TOKEN(Tokens[4], tok::kw_while, TT_DoWhile); +} + } // namespace } // namespace format } // namespace clang From 141443c2df008fa6fb7f283a025135712cce92a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Sch=C3=A4pers?= <bjo...@hazardy.de> Date: Tue, 10 Oct 2023 22:50:43 +0200 Subject: [PATCH 2/2] [clang-format] Don't align comments over scopes We now stop aligning trailing comments on all closing braces, for classes etc. we even check for the semicolon between the comment and the brace. Fixes #67906. --- clang/lib/Format/WhitespaceManager.cpp | 44 ++++- clang/unittests/Format/FormatTestComments.cpp | 176 ++++++++++++++++-- 2 files changed, 199 insertions(+), 21 deletions(-) diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index dc81060671c1712..67e5dd4c04445eb 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -1048,6 +1048,9 @@ void WhitespaceManager::alignChainedConditionals() { } void WhitespaceManager::alignTrailingComments() { + if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Never) + return; + const int Size = Changes.size(); int MinColumn = 0; int StartOfSequence = 0; @@ -1118,16 +1121,39 @@ void WhitespaceManager::alignTrailingComments() { } } - // We don't want to align namespace end comments. - const bool DontAlignThisComment = - I > 0 && C.NewlinesBefore == 0 && - Changes[I - 1].Tok->is(TT_NamespaceRBrace); - if (Style.AlignTrailingComments.Kind == FormatStyle::TCAS_Never || - DontAlignThisComment) { + // We don't want to align comments which end a scope, which are here + // identified by most closing braces. + const bool DontAlignThisComment = [&] { + if (I == 0 || C.NewlinesBefore > 0) + return false; + const auto *Tok = Changes[I - 1].Tok; + if (Tok->is(tok::semi)) { + Tok = Tok->getPreviousNonComment(); + if (!Tok) + return false; + } + if (Tok->isNot(tok::r_brace)) { + if (Tok->isNot(tok::r_paren) || !Tok->MatchingParen) + return false; + auto BeforeParent = Tok->MatchingParen->getPreviousNonComment(); + return BeforeParent && BeforeParent->is(TT_DoWhile); + } + + for (auto Prev = Tok->getPreviousNonComment(); + Prev && Prev->is(tok::r_brace); + Prev = Tok->getPreviousNonComment()) { + Tok = Prev; + } + return Tok->NewlinesBefore > 0; + }(); + + if (DontAlignThisComment) { alignTrailingComments(StartOfSequence, I, MinColumn); - MinColumn = ChangeMinColumn; - MaxColumn = ChangeMinColumn; - StartOfSequence = I; + // Reset to initial values, but skip this change for the next alignment + // pass. + MinColumn = 0; + MaxColumn = INT_MAX; + StartOfSequence = I + 1; } else if (BreakBeforeNext || Newlines > NewLineThreshold || (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) || // Break the comment sequence if the previous line did not end diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 1198329b7b5a8f0..a37505926ec63a8 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -182,7 +182,7 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { "int a; // This is unrelated")); EXPECT_EQ("class C {\n" " void f() { // This does something ..\n" - " } // awesome..\n" + " } // awesome..\n" "\n" " int a; // This is unrelated\n" "};", @@ -3102,7 +3102,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { StringRef Input = "namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3114,7 +3116,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { verifyFormat("namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3126,7 +3130,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { verifyFormat("namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3138,7 +3144,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { verifyFormat("namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3151,7 +3159,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { verifyFormat("namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3163,7 +3173,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { verifyFormat("namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3175,7 +3187,9 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { verifyFormat("namespace A {\n" " TESTSUITE(B) {\n" " namespace C {\n" - " namespace D {} // namespace D\n" + " namespace D {\n" + " // ...\n" + " } // namespace D\n" " std::string Foo = Bar; // Comment\n" " std::string BazString = Baz; // C2\n" " } // namespace C\n" @@ -3191,20 +3205,158 @@ TEST_F(FormatTestComments, DontAlignNamespaceComments) { "}\n" "// Comment"; -#if 0 - // FIXME: The following comment is aligned with the namespace comment. verifyFormat("namespace A {\n" " int Foo;\n" " int Bar;\n" "} // namespace A\n" - " // Comment", + "// Comment", Input, Style); -#endif Style.FixNamespaceComments = false; verifyFormat(Input, Style); } +TEST_F(FormatTestComments, DontAlignOverScope) { + verifyFormat("if (foo) {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("if (foo) {\n" + " // something\n" + "} else {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("if (foo) {\n" + " // something\n" + "} else if (foo) {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("while (foo) {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("for (;;) {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("do {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} while (foo); // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("do\n" + " int aLongVariable; // with comment\n" + "while (foo); // not aigned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("switch (foo) {\n" + "case 7: {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // case not aligned\n" + "} // switch also not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("switch (foo) {\n" + "default: {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} // case not aligned\n" + "} // switch also not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("class C {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "}; // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("struct S {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "}; // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("union U {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "}; // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("enum E {\n" + " aLongVariable, // with comment\n" + " f // aligned\n" + "}; // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + verifyFormat("void foo() {\n" + " {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + " } // not aligned\n" + " int bar; // new align\n" + " int foobar; // group\n" + "}"); + + verifyFormat("auto longLambda = [] { // comment\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "}; // not aligned\n" + "int bar; // new align\n" + "int foobar; // group\n" + "auto shortLambda = [] { return 5; }; // aligned"); + + verifyFormat("enum E1 { V1, V2 }; // Aligned\n" + "enum E2 { LongerNames, InThis, Enum }; // Comments"); + + verifyFormat("class C {\n" + " int aLongVariable; // with comment\n" + " int f; // aligned\n" + "} /* middle comment */; // not aligned\n" + "int bar; // new align\n" + "int foobar; // group"); + + auto Style = getLLVMStyle(); + Style.CompactNamespaces = true; + Style.FixNamespaceComments = false; + + verifyFormat("namespace A { namespace B {\n" + "int I; // Comment\n" + "}} // namespace A::B", + Style); + + verifyFormat("namespace A { namespace B {\n" + "int I; // Comment\n" + "} /* Who comments here? */ } // namespace A::B", + Style); +} + TEST_F(FormatTestComments, AlignsBlockCommentDecorations) { EXPECT_EQ("/*\n" " */", _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits