Author: nico Date: Tue Jul 23 10:49:45 2019 New Revision: 366831 URL: http://llvm.org/viewvc/llvm-project?rev=366831&view=rev Log: clang-format: Fix namespace end comments for namespaces with attributes and macros.
Fixes PR39247. While here, also make C++20 `namespace A::inline B::inline C` nested inline namespaced definitions work. Before: #define DEPRECATE_WOOF [[deprecated("meow")]] namespace DEPRECATE_WOOF woof { void f() {} } // namespace DEPRECATE_WOOFwoof namespace [[deprecated("meow")]] woof { void f() {} } // namespace [[deprecated("meow")]]woof namespace woof::inline bark { void f() {} } // namespace woof::inlinebark Now: #define DEPRECATE_WOOF [[deprecated("meow")]] namespace DEPRECATE_WOOF woof { void f() {} } // namespace woof namespace [[deprecated("meow")]] woof { void f() {} } // namespace woof namespace woof::inline bark { void f() {} } // namespace woof::inline bark (In addition to the fixed namespace end comments, also note the correct indent of the namespace contents.) Differential Revision: https://reviews.llvm.org/D65125 Modified: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp cfe/trunk/lib/Format/UnwrappedLineParser.cpp cfe/trunk/unittests/Format/FormatTest.cpp cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Modified: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp?rev=366831&r1=366830&r2=366831&view=diff ============================================================================== --- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp (original) +++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp Tue Jul 23 10:49:45 2019 @@ -36,7 +36,7 @@ std::string computeName(const FormatToke const FormatToken *Tok = NamespaceTok->getNextNonComment(); if (NamespaceTok->is(TT_NamespaceMacro)) { // Collects all the non-comment tokens between opening parenthesis - // and closing parenthesis or comma + // and closing parenthesis or comma. assert(Tok && Tok->is(tok::l_paren) && "expected an opening parenthesis"); Tok = Tok->getNextNonComment(); while (Tok && !Tok->isOneOf(tok::r_paren, tok::comma)) { @@ -44,9 +44,21 @@ std::string computeName(const FormatToke Tok = Tok->getNextNonComment(); } } else { - // Collects all the non-comment tokens between 'namespace' and '{'. + // For `namespace [[foo]] A::B::inline C {` or + // `namespace MACRO1 MACRO2 A::B::inline C {`, returns "A::B::inline C". + // Peek for the first '::' (or '{') and then return all tokens from one + // token before that up until the '{'. + const FormatToken *FirstNSTok = Tok; + while (Tok && !Tok->is(tok::l_brace) && !Tok->is(tok::coloncolon)) { + FirstNSTok = Tok; + Tok = Tok->getNextNonComment(); + } + + Tok = FirstNSTok; while (Tok && !Tok->is(tok::l_brace)) { name += Tok->TokenText; + if (Tok->is(tok::kw_inline)) + name += " "; Tok = Tok->getNextNonComment(); } } Modified: cfe/trunk/lib/Format/UnwrappedLineParser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/UnwrappedLineParser.cpp?rev=366831&r1=366830&r2=366831&view=diff ============================================================================== --- cfe/trunk/lib/Format/UnwrappedLineParser.cpp (original) +++ cfe/trunk/lib/Format/UnwrappedLineParser.cpp Tue Jul 23 10:49:45 2019 @@ -1873,8 +1873,13 @@ void UnwrappedLineParser::parseNamespace if (InitialToken.is(TT_NamespaceMacro)) { parseParens(); } else { - while (FormatTok->isOneOf(tok::identifier, tok::coloncolon)) - nextToken(); + while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::kw_inline, + tok::l_square)) { + if (FormatTok->is(tok::l_square)) + parseSquare(); + else + nextToken(); + } } if (FormatTok->Tok.is(tok::l_brace)) { if (ShouldBreakBeforeBrace(Style, InitialToken)) Modified: cfe/trunk/unittests/Format/FormatTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=366831&r1=366830&r2=366831&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTest.cpp (original) +++ cfe/trunk/unittests/Format/FormatTest.cpp Tue Jul 23 10:49:45 2019 @@ -1782,6 +1782,21 @@ TEST_F(FormatTest, FormatsNamespaces) { "void f() { f(); }\n" "}", LLVMWithNoNamespaceFix); + verifyFormat("namespace N::inline D {\n" + "class A {};\n" + "void f() { f(); }\n" + "}", + LLVMWithNoNamespaceFix); + verifyFormat("namespace N::inline D::E {\n" + "class A {};\n" + "void f() { f(); }\n" + "}", + LLVMWithNoNamespaceFix); + verifyFormat("namespace [[deprecated(\"foo[bar\")]] some_namespace {\n" + "class A {};\n" + "void f() { f(); }\n" + "}", + LLVMWithNoNamespaceFix); verifyFormat("/* something */ namespace some_namespace {\n" "class A {};\n" "void f() { f(); }\n" Modified: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp?rev=366831&r1=366830&r2=366831&view=diff ============================================================================== --- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp (original) +++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Tue Jul 23 10:49:45 2019 @@ -77,6 +77,44 @@ TEST_F(NamespaceEndCommentsFixerTest, Ad "int i;\n" "int j;\n" "}")); + + EXPECT_EQ("namespace [[deprecated(\"foo\")]] A::B {\n" + "int i;\n" + "int j;\n" + "}// namespace A::B", + fixNamespaceEndComments("namespace [[deprecated(\"foo\")]] A::B {\n" + "int i;\n" + "int j;\n" + "}")); + + EXPECT_EQ("namespace [[deprecated(\"foo\")]] A::inline B::inline C {\n" + "int i;\n" + "int j;\n" + "}// namespace A::inline B::inline C", + fixNamespaceEndComments( + "namespace [[deprecated(\"foo\")]] A::inline B::inline C {\n" + "int i;\n" + "int j;\n" + "}")); + + EXPECT_EQ("namespace DEPRECATED A::B {\n" + "int i;\n" + "int j;\n" + "}// namespace A::B", + fixNamespaceEndComments("namespace DEPRECATED A::B {\n" + "int i;\n" + "int j;\n" + "}")); + + EXPECT_EQ("inline namespace [[deprecated]] A {\n" + "int i;\n" + "int j;\n" + "}// namespace A", + fixNamespaceEndComments("inline namespace [[deprecated]] A {\n" + "int i;\n" + "int j;\n" + "}")); + EXPECT_EQ("namespace ::A {\n" "int i;\n" "int j;\n" @@ -410,7 +448,8 @@ TEST_F(NamespaceEndCommentsFixerTest, Do /*Ranges=*/{1, tooling::Range(16, 3)})); } -TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) { +TEST_F(NamespaceEndCommentsFixerTest, + DoesNotAddCommentAfterRBraceInPPDirective) { EXPECT_EQ("#define SAD \\\n" "namespace A { \\\n" "int i; \\\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits