llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-format Author: Owen Pan (owenca) <details> <summary>Changes</summary> Also fix/delete existing invalid/redundant test cases. Fix #<!-- -->130894 --- Full diff: https://github.com/llvm/llvm-project/pull/131434.diff 3 Files Affected: - (modified) clang/lib/Format/TokenAnnotator.cpp (+22-5) - (modified) clang/unittests/Format/FormatTest.cpp (+14-14) - (modified) clang/unittests/Format/TokenAnnotatorTest.cpp (+53) ``````````diff diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 08539de405c67..d618eab1692b3 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -1639,6 +1639,25 @@ class AnnotatingParser { case tok::kw_operator: if (Style.isProto()) break; + // C++ user-defined conversion function. + if (IsCpp && CurrentToken && + (CurrentToken->is(tok::kw_auto) || + CurrentToken->isTypeName(LangOpts))) { + FormatToken *LParen; + if (CurrentToken->startsSequence(tok::kw_decltype, tok::l_paren, + tok::kw_auto, tok::r_paren)) { + LParen = CurrentToken->Next->Next->Next->Next; + } else { + for (LParen = CurrentToken->Next; + LParen && LParen->isNot(tok::l_paren); LParen = LParen->Next) { + } + } + if (LParen && LParen->startsSequence(tok::l_paren, tok::r_paren)) { + Tok->setFinalizedType(TT_FunctionDeclarationName); + LParen->setFinalizedType(TT_FunctionDeclarationLParen); + break; + } + } while (CurrentToken && !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) { if (CurrentToken->isOneOf(tok::star, tok::amp)) @@ -3071,12 +3090,10 @@ class AnnotatingParser { if (InTemplateArgument && NextToken->Tok.isAnyIdentifier()) return TT_BinaryOperator; - // "&&" followed by "(", "*", or "&" is quite unlikely to be two successive - // unary "&". - if (Tok.is(tok::ampamp) && - NextToken->isOneOf(tok::l_paren, tok::star, tok::amp)) { + // "&&" followed by "*" or "&" is quite unlikely to be two successive unary + // "&". + if (Tok.is(tok::ampamp) && NextToken->isOneOf(tok::star, tok::amp)) return TT_BinaryOperator; - } // This catches some cases where evaluation order is used as control flow: // aaa && aaa->f(); diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 9864e7ec1b2ec..5df7865f5a629 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -10443,27 +10443,17 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) { "void\n" "A::operator->() {}\n" "void\n" - "A::operator void *() {}\n" + "A::operator&() {}\n" "void\n" - "A::operator void &() {}\n" - "void\n" - "A::operator void &&() {}\n" - "void\n" - "A::operator char *() {}\n" + "A::operator&&() {}\n" "void\n" "A::operator[]() {}\n" "void\n" "A::operator!() {}\n" "void\n" - "A::operator**() {}\n" - "void\n" "A::operator<Foo> *() {}\n" "void\n" - "A::operator<Foo> **() {}\n" - "void\n" - "A::operator<Foo> &() {}\n" - "void\n" - "A::operator void **() {}", + "A::operator<Foo> &() {}\n", Style); verifyFormat("constexpr auto\n" "operator()() const -> reference {}\n" @@ -10486,7 +10476,7 @@ TEST_F(FormatTest, ReturnTypeBreakingStyle) { "constexpr auto\n" "operator void &() const -> reference {}\n" "constexpr auto\n" - "operator void &&() const -> reference {}\n" + "operator&&() const -> reference {}\n" "constexpr auto\n" "operator char *() const -> reference {}\n" "constexpr auto\n" @@ -28032,6 +28022,16 @@ TEST_F(FormatTest, BreakAfterAttributes) { " --d;", CtrlStmtCode, Style); + verifyFormat("[[nodiscard]]\n" + "operator bool();\n" + "[[nodiscard]]\n" + "operator bool() {\n" + " return true;\n" + "}", + "[[nodiscard]] operator bool();\n" + "[[nodiscard]] operator bool() { return true; }", + Style); + constexpr StringRef CtorDtorCode("struct Foo {\n" " [[deprecated]] Foo();\n" " [[deprecated]] Foo() {}\n" diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 5e2d301c5d1f3..48927813af317 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -3856,6 +3856,59 @@ TEST_F(TokenAnnotatorTest, AfterPPDirective) { EXPECT_TOKEN(Tokens[2], tok::minusminus, TT_AfterPPDirective); } +TEST_F(TokenAnnotatorTest, UserDefinedConversionFunction) { + auto Tokens = annotate("operator int();"); + ASSERT_EQ(Tokens.size(), 6u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); + + Tokens = annotate("explicit operator int *();"); + ASSERT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[3], tok::star, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[4], tok::l_paren, TT_FunctionDeclarationLParen); + + Tokens = annotate("operator int &();"); + ASSERT_EQ(Tokens.size(), 7u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::amp, TT_PointerOrReference); + EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_FunctionDeclarationLParen); + + Tokens = annotate("operator auto() const { return 2; }"); + ASSERT_EQ(Tokens.size(), 11u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); + EXPECT_TOKEN(Tokens[4], tok::kw_const, TT_TrailingAnnotation); + EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_FunctionLBrace); + + Tokens = annotate("operator decltype(auto)() const;"); + ASSERT_EQ(Tokens.size(), 10u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_TypeDeclarationParen); + EXPECT_TOKEN(Tokens[4], tok::r_paren, TT_TypeDeclarationParen); + EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_FunctionDeclarationLParen); + EXPECT_TOKEN(Tokens[7], tok::kw_const, TT_TrailingAnnotation); + + auto Style = getLLVMStyle(); + Style.TypeNames.push_back("Foo"); + + Tokens = annotate("virtual operator Foo() = 0;", Style); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[1], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[3], tok::l_paren, TT_FunctionDeclarationLParen); + + Tokens = annotate("operator Foo() override { return Foo(); }", Style); + ASSERT_EQ(Tokens.size(), 13u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[2], tok::l_paren, TT_FunctionDeclarationLParen); + EXPECT_TOKEN(Tokens[5], tok::l_brace, TT_FunctionLBrace); + + Tokens = annotate("friend Bar::operator Foo();", Style); + ASSERT_EQ(Tokens.size(), 9u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::kw_operator, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[5], tok::l_paren, TT_FunctionDeclarationLParen); +} + } // namespace } // namespace format } // namespace clang `````````` </details> https://github.com/llvm/llvm-project/pull/131434 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits