[clang] [clang-tools-extra] [clang] CodeComplete fix for addr of deduced-this methods (PR #152445)
Mythreya Kuricheti via cfe-commits
cfe-commits at lists.llvm.org
Thu Aug 7 01:47:32 PDT 2025
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 <git at 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)(
More information about the cfe-commits
mailing list