https://github.com/MythreyaK updated https://github.com/llvm/llvm-project/pull/152445
>From 1b2cb7c27b72d1a774aa7ac0652f3765defa1140 Mon Sep 17 00:00:00 2001 From: Mythreya Kuricheti <g...@mythreya.dev> Date: Wed, 6 Aug 2025 22:49:28 -0700 Subject: [PATCH] [clang] CodeComplete fix for addr of deduced-this methods --- .../clangd/unittests/CodeCompleteTests.cpp | 11 ++++---- clang/lib/Sema/SemaCodeComplete.cpp | 25 +++++++++++++------ .../skip-explicit-object-parameter.cpp | 4 +-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp index 61bd6318b46cf..8a7188ee7260c 100644 --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -4462,15 +4462,16 @@ TEST(CompletionTest, SkipExplicitObjectParameter) { Preamble.get(), Inputs, Opts); EXPECT_THAT( Result.Completions, - ElementsAre(AllOf(named("foo"), signature("<class self:auto>(int arg)"), - snippetSuffix("<${1:class self:auto}>")))); + ElementsAre(AllOf(named("foo"), signature("(auto &&self, int arg)"), + snippetSuffix("(${1:auto &&self}, ${2:int arg})")))); } { auto Result = codeComplete(testPath(TU.Filename), Code.point("c3"), Preamble.get(), Inputs, Opts); - EXPECT_THAT(Result.Completions, - ElementsAre(AllOf(named("bar"), signature("(int arg)"), - snippetSuffix("")))); + EXPECT_THAT( + Result.Completions, + ElementsAre(AllOf(named("bar"), signature("(A self, int arg)"), + snippetSuffix("(${1:A self}, ${2:int arg})")))); } } } // namespace diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 0de55800ccdd1..357798e20aca3 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1312,6 +1312,11 @@ bool ResultBuilder::canCxxMethodBeCalled(const CXXMethodDecl *Method, (CurrentClassScope == Method->getParent() || CurrentClassScope->isDerivedFrom(Method->getParent())); + // if method is using C++23 "deducing this", then it is a call + if (Method->isExplicitObjectMemberFunction()) { + FunctionCanBeCall = true; + } + // We skip the following calculation for exceptions if it's already true. if (FunctionCanBeCall) return true; @@ -3240,6 +3245,7 @@ static std::string GetDefaultValueString(const ParmVarDecl *Param, static void AddFunctionParameterChunks(Preprocessor &PP, const PrintingPolicy &Policy, const FunctionDecl *Function, + const CodeCompletionContext &CCContext, CodeCompletionBuilder &Result, unsigned Start = 0, bool InOptional = false) { @@ -3255,15 +3261,17 @@ static void AddFunctionParameterChunks(Preprocessor &PP, Result.getCodeCompletionTUInfo()); if (!FirstParameter) Opt.AddChunk(CodeCompletionString::CK_Comma); - AddFunctionParameterChunks(PP, Policy, Function, Opt, P, true); + AddFunctionParameterChunks(PP, Policy, Function, CCContext, Opt, P, true); Result.AddOptionalChunk(Opt.TakeString()); break; } // C++23 introduces an explicit object parameter, a.k.a. "deducing this" // Skip it for autocomplete and treat the next parameter as the first - // parameter - if (FirstParameter && Param->isExplicitObjectParameter()) { + // parameter. But if the context is a symbol, i.e., "A::method" call, + // do not skip + auto IsSymbol = CCContext.getKind() == CodeCompletionContext::CCC_Symbol; + if (FirstParameter && Param->isExplicitObjectParameter() && !IsSymbol) { continue; } @@ -3726,7 +3734,7 @@ CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl( Ctx, Policy); AddTypedNameChunk(Ctx, Policy, ND, Result); Result.AddChunk(CodeCompletionString::CK_LeftParen); - AddFunctionParameterChunks(PP, Policy, Function, Result); + AddFunctionParameterChunks(PP, Policy, Function, CCContext, Result); Result.AddChunk(CodeCompletionString::CK_RightParen); AddFunctionTypeQualsToCompletionString(Result, Function); }; @@ -3808,7 +3816,7 @@ CodeCompletionString *CodeCompletionResult::createCodeCompletionStringForDecl( // Add the function parameters Result.AddChunk(CodeCompletionString::CK_LeftParen); - AddFunctionParameterChunks(PP, Policy, Function, Result); + AddFunctionParameterChunks(PP, Policy, Function, CCContext, Result); Result.AddChunk(CodeCompletionString::CK_RightParen); AddFunctionTypeQualsToCompletionString(Result, Function); return Result.TakeString(); @@ -7132,13 +7140,16 @@ void SemaCodeCompletion::CodeCompleteConstructorInitializer( auto GenerateCCS = [&](const NamedDecl *ND, const char *Name) { CodeCompletionBuilder Builder(Results.getAllocator(), Results.getCodeCompletionTUInfo()); + auto CCContext = Results.getCompletionContext(); Builder.AddTypedTextChunk(Name); Builder.AddChunk(CodeCompletionString::CK_LeftParen); if (const auto *Function = dyn_cast<FunctionDecl>(ND)) - AddFunctionParameterChunks(SemaRef.PP, Policy, Function, Builder); + AddFunctionParameterChunks(SemaRef.PP, Policy, Function, CCContext, + Builder); else if (const auto *FunTemplDecl = dyn_cast<FunctionTemplateDecl>(ND)) AddFunctionParameterChunks(SemaRef.PP, Policy, - FunTemplDecl->getTemplatedDecl(), Builder); + FunTemplDecl->getTemplatedDecl(), CCContext, + Builder); Builder.AddChunk(CodeCompletionString::CK_RightParen); return Builder.TakeString(); }; diff --git a/clang/test/CodeCompletion/skip-explicit-object-parameter.cpp b/clang/test/CodeCompletion/skip-explicit-object-parameter.cpp index 587d6cb044d19..f88f1543e0081 100644 --- a/clang/test/CodeCompletion/skip-explicit-object-parameter.cpp +++ b/clang/test/CodeCompletion/skip-explicit-object-parameter.cpp @@ -36,9 +36,9 @@ int func3() { (&A::bar) } // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-3):10 -std=c++23 %s | FileCheck -check-prefix=CHECK-CC3 %s -// CHECK-CC3: COMPLETION: foo : [#void#]foo<<#class self:auto#>>(<#int arg#>) +// CHECK-CC3: COMPLETION: foo : [#void#]foo(<#auto &&self#>, <#int arg#>) // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-4):10 -std=c++23 %s | FileCheck -check-prefix=CHECK-CC4 %s -// CHECK-CC4: COMPLETION: bar : [#void#]bar(<#int arg#>) +// CHECK-CC4: COMPLETION: bar : [#void#]bar(<#A self#>, <#int arg#>) int func4() { // TODO (&A::foo)( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits