zyounan created this revision.
zyounan added reviewers: sammccall, nridge, hokein.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
zyounan published this revision for review.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

This resolves https://reviews.llvm.org/D155370#4531274.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156605

Files:
  clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/unittests/Sema/CodeCompleteTest.cpp

Index: clang/unittests/Sema/CodeCompleteTest.cpp
===================================================================
--- clang/unittests/Sema/CodeCompleteTest.cpp
+++ clang/unittests/Sema/CodeCompleteTest.cpp
@@ -214,15 +214,25 @@
     struct OtherClass {
       OtherClass() {
         Foo f;
+        Derived d;
         f.$canBeCall^
+        ; // Prevent parsing as 'f.f'
+        f.Foo::$canBeCall^
         &Foo::$cannotBeCall^
+        ;
+        d.Foo::$canBeCall^
       }
     };
 
     int main() {
       Foo f;
+      Derived d;
       f.$canBeCall^
+      ; // Prevent parsing as 'f.f'
+      f.Foo::$canBeCall^
       &Foo::$cannotBeCall^
+      ;
+      d.Foo::$canBeCall^
     }
     )cpp");
 
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -338,8 +338,11 @@
   ///
   /// \param InBaseClass whether the result was found in a base
   /// class of the searched context.
+  ///
+  /// \param BaseType the type of expression that precedes the "." or "->"
+  /// in a member access expression.
   void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
-                 bool InBaseClass);
+                 bool InBaseClass, QualType BaseType);
 
   /// Add a new non-declaration result to this result set.
   void AddResult(Result R);
@@ -1262,7 +1265,8 @@
 }
 
 void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
-                              NamedDecl *Hiding, bool InBaseClass = false) {
+                              NamedDecl *Hiding, bool InBaseClass = false,
+                              QualType BaseType = QualType()) {
   if (R.Kind != Result::RK_Declaration) {
     // For non-declaration results, just add the result.
     Results.push_back(R);
@@ -1380,9 +1384,7 @@
         OverloadSet.Add(Method, Results.size());
       }
 
-  // When completing a non-static member function (and not via
-  // dot/arrow member access) and we're not inside that class' scope,
-  // it can't be a call.
+  // Decide whether or not a non-static member function can be a call.
   if (CompletionContext.getKind() == clang::CodeCompletionContext::CCC_Symbol) {
     const NamedDecl *ND = R.getDeclaration();
     if (const auto *FuncTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
@@ -1404,10 +1406,24 @@
         return nullptr;
       }();
 
+      // When completing a non-static member function (and not via
+      // dot/arrow member access) and we're not inside that class' scope,
+      // it can't be a call.
       R.FunctionCanBeCall =
           CurrentClassScope &&
           (CurrentClassScope == Method->getParent() ||
            CurrentClassScope->isDerivedFrom(Method->getParent()));
+
+      // If the member access "." or "->" is followed by a qualified Id and the
+      // object type is derived from or the same as that of the Id, then
+      // the candidate functions should be perceived as calls.
+      if (const CXXRecordDecl *MaybeDerived = nullptr;
+          !BaseType.isNull() &&
+          (MaybeDerived = BaseType->getAsCXXRecordDecl())) {
+        auto *MaybeBase = Method->getParent();
+        R.FunctionCanBeCall =
+            MaybeDerived == MaybeBase || MaybeDerived->isDerivedFrom(MaybeBase);
+      }
     }
   }
 
@@ -1683,7 +1699,7 @@
                  bool InBaseClass) override {
     ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr,
                                  false, IsAccessible(ND, Ctx), FixIts);
-    Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass);
+    Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass, BaseType);
   }
 
   void EnteredContext(DeclContext *Ctx) override {
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -552,15 +552,25 @@
       struct OtherClass {
         OtherClass() {
           Foo f;
+          Derived d;
           f.$canBeCall^
+          ; // Prevent parsing as 'f.f'
+          f.Foo::$canBeCall^
           &Foo::$canNotBeCall^
+          ;
+          d.Foo::$canBeCall^
         }
       };
 
       int main() {
         Foo f;
+        Derived d;
         f.$canBeCall^
+        ; // Prevent parsing as 'f.f'
+        f.Foo::$canBeCall^
         &Foo::$canNotBeCall^
+        ;
+        d.Foo::$canBeCall^
       }
       )cpp");
   auto TU = TestTU::withCode(Code.code());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D156605: [CodeComplet... Younan Zhang via Phabricator via cfe-commits

Reply via email to