diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -438,8 +438,6 @@ if (C.SemaResult) { getSignature(*SemaCCS, &S.Signature, &S.SnippetSuffix, C.SemaResult->Kind, C.SemaResult->CursorKind, &Completion.RequiredQualifier); - if (!C.SemaResult->FunctionCanBeCall) - S.SnippetSuffix.clear(); S.ReturnType = getReturnType(*SemaCCS); } else if (C.IndexResult) { S.Signature = std::string(C.IndexResult->Signature); diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1211,6 +1211,13 @@ R.InBaseClass = true; } +static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy, + const NamedDecl *ND, + CodeCompletionBuilder &Result); + +static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, + const Preprocessor &PP); + enum class OverloadCompare { BothViable, Dominates, Dominated }; // Will Candidate ever be called on the object, when overloaded with Incumbent? // Returns Dominates if Candidate is always called, Dominated if Incumbent is @@ -1400,10 +1407,29 @@ return nullptr; }(); - R.FunctionCanBeCall = + bool FunctionCanBeCall = CurrentClassScope && (CurrentClassScope == Method->getParent() || CurrentClassScope->isDerivedFrom(Method->getParent())); + + // Instead of doing calculation for parameters later whose results would be + // dropped eventually, we only emit the function name. + if (!FunctionCanBeCall) { + CodeCompletionBuilder Builder(getAllocator(), + getCodeCompletionTUInfo()); + auto &ASTContext = SemaRef.getASTContext(); + AddTypedNameChunk( + ASTContext, + getCompletionPrintingPolicy(ASTContext, SemaRef.getPreprocessor()), + Method, Builder); + Result R(Builder.TakeString(), /*Priority=*/CCP_Declaration, + /*CursorKind=*/CXCursor_CXXMethod, + /*Availability=*/CXAvailability_Available, + /*D=*/Method); + R.FunctionCanBeCall = false; + AddResult(std::move(R)); + return; + } } } diff --git a/clang/test/CodeCompletion/member-access.cpp b/clang/test/CodeCompletion/member-access.cpp --- a/clang/test/CodeCompletion/member-access.cpp +++ b/clang/test/CodeCompletion/member-access.cpp @@ -171,7 +171,7 @@ template void dependentColonColonCompletion() { Template::staticFn(); -// CHECK-CC7: function : [#void#]function() +// CHECK-CC7: Pattern : function // CHECK-CC7: Nested : Nested // CHECK-CC7: o1 : [#BaseTemplate#]o1 // CHECK-CC7: o2 : [#BaseTemplate#]o2 diff --git a/clang/test/Index/complete-qualified.cpp b/clang/test/Index/complete-qualified.cpp --- a/clang/test/Index/complete-qualified.cpp +++ b/clang/test/Index/complete-qualified.cpp @@ -16,5 +16,6 @@ // RUN: c-index-test -code-completion-at=%s:14:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: FieldDecl:{ResultType C}{TypedText c} (35) // CHECK-CC1: ClassDecl:{TypedText Foo} (35) -// CHECK-CC1: CXXMethod:{ResultType Foo &}{TypedText operator=}{LeftParen (}{Placeholder const Foo &}{RightParen )} -// CHECK-CC1: CXXDestructor:{ResultType void}{TypedText ~Foo}{LeftParen (}{RightParen )} (80) +// CHECK-CC1: CXXMethod:{TypedText operator=} (50) +// CHECK-CC1: CXXMethod:{TypedText operator=} (50) +// CHECK-CC1: CXXMethod:{TypedText ~Foo} (50) diff --git a/clang/unittests/Sema/CodeCompleteTest.cpp b/clang/unittests/Sema/CodeCompleteTest.cpp --- a/clang/unittests/Sema/CodeCompleteTest.cpp +++ b/clang/unittests/Sema/CodeCompleteTest.cpp @@ -59,14 +59,12 @@ unsigned NumResults) override { for (unsigned I = 0; I < NumResults; ++I) { auto R = Results[I]; - if (R.Kind == CodeCompletionResult::RK_Declaration) { - if (const auto *FD = llvm::dyn_cast(R.getDeclaration())) { - CompletedFunctionDecl D; - D.Name = FD->getNameAsString(); - D.CanBeCall = R.FunctionCanBeCall; - D.IsStatic = FD->isStatic(); - CompletedFuncDecls.emplace_back(std::move(D)); - } + if (const auto *FD = llvm::dyn_cast(R.getDeclaration())) { + CompletedFunctionDecl D; + D.Name = FD->getNameAsString(); + D.CanBeCall = R.FunctionCanBeCall; + D.IsStatic = FD->isStatic(); + CompletedFuncDecls.emplace_back(std::move(D)); } } }