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