Skip to content

Commit 592ba1a

Browse files
committed
[clang][CodeComplete] skip explicit obj param in SignatureHelp
1 parent 2723a6d commit 592ba1a

File tree

3 files changed

+56
-7
lines changed

3 files changed

+56
-7
lines changed

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3266,6 +3266,34 @@ TEST(SignatureHelpTest, VariadicType) {
32663266
}
32673267
}
32683268

3269+
TEST(SignatureHelpTest, SkipExplicitObjectParameter) {
3270+
Annotations Code(R"cpp(
3271+
struct A {
3272+
void foo(this auto&& self, int arg);
3273+
};
3274+
int main() {
3275+
A a {};
3276+
a.foo(^);
3277+
}
3278+
)cpp");
3279+
3280+
auto TU = TestTU::withCode(Code.code());
3281+
TU.ExtraArgs = {"-std=c++23"};
3282+
3283+
MockFS FS;
3284+
auto Inputs = TU.inputs(FS);
3285+
3286+
auto Preamble = TU.preamble();
3287+
ASSERT_TRUE(Preamble);
3288+
3289+
const auto Result = signatureHelp(testPath(TU.Filename), Code.point(),
3290+
*Preamble, Inputs, MarkupKind::PlainText);
3291+
3292+
EXPECT_EQ(1, Result.signatures.size());
3293+
3294+
EXPECT_THAT(Result.signatures[0], AllOf(sig("foo([[int arg]]) -> void")));
3295+
}
3296+
32693297
TEST(CompletionTest, IncludedCompletionKinds) {
32703298
Annotations Test(R"cpp(#include "^)cpp");
32713299
auto TU = TestTU::withCode(Test.code());

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4019,7 +4019,9 @@ static void AddOverloadParameterChunks(
40194019
Function ? Function->getNumParams() : Prototype->getNumParams();
40204020

40214021
for (unsigned P = Start; P != NumParams; ++P) {
4022-
if (Function && Function->getParamDecl(P)->hasDefaultArg() && !InOptional) {
4022+
const ParmVarDecl *Param = Function->getParamDecl(P);
4023+
4024+
if (Function && Param->hasDefaultArg() && !InOptional) {
40234025
// When we see an optional default argument, put that argument and
40244026
// the remaining default arguments into a new, optional string.
40254027
CodeCompletionBuilder Opt(Result.getAllocator(),
@@ -4034,6 +4036,13 @@ static void AddOverloadParameterChunks(
40344036
return;
40354037
}
40364038

4039+
// C++23 introduces an explicit object parameter, a.k.a. "deducing this"
4040+
// Skip it for autocomplete and treat the next parameter as the first
4041+
// parameter
4042+
if (FirstParameter && Param->isExplicitObjectParameter()) {
4043+
continue;
4044+
}
4045+
40374046
if (FirstParameter)
40384047
FirstParameter = false;
40394048
else

clang/test/CodeCompletion/skip-explicit-object-parameter.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,21 @@ int main() {
66
A a {};
77
a.
88
}
9-
// RUN: %clang_cc1 -cc1 -fsyntax-only -code-completion-at=%s:%(line-2):5 -std=c++23 %s | FileCheck %s
10-
// CHECK: COMPLETION: A : A::
11-
// CHECK-NEXT: COMPLETION: foo : [#void#]foo(<#int arg#>)
12-
// CHECK-NEXT: COMPLETION: operator= : [#A &#]operator=(<#const A &#>)
13-
// CHECK-NEXT: COMPLETION: operator= : [#A &#]operator=(<#A &&#>)
14-
// CHECK-NEXT: COMPLETION: ~A : [#void#]~A()
9+
// RUN: %clang_cc1 -cc1 -fsyntax-only -code-completion-at=%s:%(line-2):5 -std=c++23 %s | FileCheck -check-prefix=CHECK-CC1 %s
10+
// CHECK-CC1: COMPLETION: A : A::
11+
// CHECK-NEXT-CC1: COMPLETION: foo : [#void#]foo(<#int arg#>)
12+
// CHECK-NEXT-CC1: COMPLETION: operator= : [#A &#]operator=(<#const A &#>)
13+
// CHECK-NEXT-CC1: COMPLETION: operator= : [#A &#]operator=(<#A &&#>)
14+
// CHECK-NEXT-CC1: COMPLETION: ~A : [#void#]~A()
15+
16+
struct B {
17+
template <typename T>
18+
void foo(this T&& self, int arg);
19+
};
20+
21+
int main2() {
22+
B b {};
23+
b.foo();
24+
}
25+
// RUN: %clang_cc1 -cc1 -fsyntax-only -code-completion-at=%s:%(line-2):9 -std=c++23 %s | FileCheck -check-prefix=CHECK-CC2 %s
26+
// CHECK-CC2: OVERLOAD: [#void#]foo(int arg)

0 commit comments

Comments
 (0)