[clangd] Make go-to-type work on member function calls
authorSam McCall <sam.mccall@gmail.com>
Mon, 26 Sep 2022 02:17:27 +0000 (04:17 +0200)
committerSam McCall <sam.mccall@gmail.com>
Mon, 26 Sep 2022 02:18:43 +0000 (04:18 +0200)
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp

index 020f83b..17be646 100644 (file)
@@ -454,6 +454,10 @@ public:
             Outer.add(TD->getTemplatedDecl(), Flags | Rel::TemplatePattern);
         }
       }
+      void
+      VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT) {
+        Outer.add(STTPT->getReplacementType(), Flags);
+      }
       void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT) {
         Outer.add(TTPT->getDecl(), Flags);
       }
index 25ddcbd..10fb14b 100644 (file)
@@ -1834,6 +1834,12 @@ static QualType typeForNode(const SelectionTree::Node *N) {
       QualType VisitExpr(const Expr *S) {
         return S->IgnoreImplicitAsWritten()->getType();
       }
+      QualType VisitMemberExpr(const MemberExpr *S) {
+        // The `foo` in `s.foo()` pretends not to have a real type!
+        if (S->getType()->isSpecificBuiltinType(BuiltinType::BoundMember))
+          return Expr::findBoundMemberType(S);
+        return VisitExpr(S);
+      }
       // Exceptions for void expressions that operate on a type in some way.
       QualType VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
         return S->getDestroyedType();
index e9e6b6f..dba7f4f 100644 (file)
@@ -1829,8 +1829,9 @@ TEST(FindType, All) {
     struct $Target[[Target]] { operator int() const; };
     struct Aggregate { Target a, b; };
     Target t;
+    Target make();
 
-    template <typename T> class $smart_ptr[[smart_ptr]] {
+    template <typename T> struct $smart_ptr[[smart_ptr]] {
       T& operator*();
       T* operator->();
       T* get();
@@ -1858,6 +1859,8 @@ TEST(FindType, All) {
            "void x() { ^if (t) {} }",
            "void x() { ^while (t) {} }",
            "void x() { ^do { } while (t); }",
+           "void x() { ^make(); }",
+           "void x(smart_ptr<Target> &t) { t.^get(); }",
            "^auto x = []() { return t; };",
            "Target* ^tptr = &t;",
            "Target ^tarray[3];",