massberg created this revision. massberg added a reviewer: kadircet. Herald added a subscriber: arphaman. Herald added a project: All. massberg requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang-tools-extra.
In C++20 some binary operations can be rewritten, e.g. `a != b` can be rewritten to `!(a == b)` if `!=` is not explicitly defined. The `TargetFinder` hasn't considered the corresponding `CXXRewrittenBinaryOperator` yet. This resulted that the definition of such operators couldn't be found when navigating to such a `!=` operator, see https://github.com/clangd/clangd/issues/1476. In this patch we add support of `CXXRewrittenBinaryOperator` in `FindTarget`. In such a case we redirect to the inner binary operator of the decomposed form. E.g. in case that `a != b` has been rewritten to `!(a == b)` we go to the `==` operator. The `==` operator might be implicitly defined (e.g. by a `<=>` operator), but this case is already handled, see the new test. I'm not sure if I the hover test which is added in this patch is the right one, but at least is passed with this patch and fails without it :) Note, that it might be a bit missleading that hovering over a `!=` refers to "instance method operator==". Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D153331 Files: clang-tools-extra/clangd/FindTarget.cpp clang-tools-extra/clangd/unittests/HoverTests.cpp Index: clang-tools-extra/clangd/unittests/HoverTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/HoverTests.cpp +++ clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -4048,6 +4048,38 @@ EXPECT_TRUE(H->Type); } +TEST(Hover, RewrittenBinaryOperatorSpaceshipMassberg) { + Annotations T(R"cpp( + namespace std { + struct strong_ordering { + int n; + constexpr operator int() const { return n; } + static const strong_ordering equal, greater, less; + }; + constexpr strong_ordering strong_ordering::equal = {0}; + constexpr strong_ordering strong_ordering::greater = {1}; + constexpr strong_ordering strong_ordering::less = {-1}; + } + + struct Foo + { + int x; + // Foo spaceship + auto operator<=>(const Foo&) const = default; + }; + + static_assert(Foo(1) !^= Foo(2)); + )cpp"); + + TestTU TU = TestTU::withCode(T.code()); + TU.ExtraArgs.push_back("-std=c++20"); + auto AST = TU.build(); + auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); + EXPECT_EQ(HI->Type, + HoverInfo::PrintedType("bool (const Foo &) const noexcept")); + EXPECT_EQ(HI->Documentation, "Foo spaceship"); +} + } // namespace } // namespace clangd } // namespace clang Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -347,6 +347,10 @@ void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) { Outer.add(CDE->getOperatorDelete(), Flags); } + void + VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *RBO) { + Outer.add(RBO->getDecomposedForm().InnerBinOp, Flags); + } }; Visitor(*this, Flags).Visit(S); }
Index: clang-tools-extra/clangd/unittests/HoverTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/HoverTests.cpp +++ clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -4048,6 +4048,38 @@ EXPECT_TRUE(H->Type); } +TEST(Hover, RewrittenBinaryOperatorSpaceshipMassberg) { + Annotations T(R"cpp( + namespace std { + struct strong_ordering { + int n; + constexpr operator int() const { return n; } + static const strong_ordering equal, greater, less; + }; + constexpr strong_ordering strong_ordering::equal = {0}; + constexpr strong_ordering strong_ordering::greater = {1}; + constexpr strong_ordering strong_ordering::less = {-1}; + } + + struct Foo + { + int x; + // Foo spaceship + auto operator<=>(const Foo&) const = default; + }; + + static_assert(Foo(1) !^= Foo(2)); + )cpp"); + + TestTU TU = TestTU::withCode(T.code()); + TU.ExtraArgs.push_back("-std=c++20"); + auto AST = TU.build(); + auto HI = getHover(AST, T.point(), format::getLLVMStyle(), nullptr); + EXPECT_EQ(HI->Type, + HoverInfo::PrintedType("bool (const Foo &) const noexcept")); + EXPECT_EQ(HI->Documentation, "Foo spaceship"); +} + } // namespace } // namespace clangd } // namespace clang Index: clang-tools-extra/clangd/FindTarget.cpp =================================================================== --- clang-tools-extra/clangd/FindTarget.cpp +++ clang-tools-extra/clangd/FindTarget.cpp @@ -347,6 +347,10 @@ void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE) { Outer.add(CDE->getOperatorDelete(), Flags); } + void + VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *RBO) { + Outer.add(RBO->getDecomposedForm().InnerBinOp, Flags); + } }; Visitor(*this, Flags).Visit(S); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits