[clang] [clang-tools-extra] [clangd] Fix signature help for static call operator 196153 (C++23) (PR #197139)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 14 03:02:18 PDT 2026
https://github.com/Ippo47 updated https://github.com/llvm/llvm-project/pull/197139
>From 290e652e4bc0930bfe8dc3996f8f1ac2a85a33a5 Mon Sep 17 00:00:00 2001
From: paarth <cs26mtech02005 at iith.ac.in>
Date: Fri, 8 May 2026 15:22:52 +0530
Subject: [PATCH] Fixed signature help for static call operator
Fix signature help for static call operator
fixed code
---
.../clangd/unittests/CodeCompleteTests.cpp | 87 +++++++++++++++++++
clang/lib/Sema/SemaCodeComplete.cpp | 39 +++++++--
2 files changed, 118 insertions(+), 8 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 386ffb54924a7..ce477f34fae2f 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -3455,6 +3455,93 @@ TEST(SignatureHelpTest, SkipExplicitObjectParameter) {
}
}
+TEST(SignatureHelpTest, StaticCallOperator) {
+ Annotations Code(R"cpp(
+ struct Abc {
+ void operator()(bool a) {}
+ };
+ struct AbcStatic {
+ static void operator()(bool a) {}
+ };
+ void test() {
+ Abc abc;
+ AbcStatic abcStatic;
+ abc($c1^);
+ abcStatic($c2^);
+ }
+ )cpp");
+ auto TU = TestTU::withCode(Code.code());
+ TU.ExtraArgs = {"-std=c++23"};
+ MockFS FS;
+ auto Inputs = TU.inputs(FS);
+ auto Preamble = TU.preamble();
+ ASSERT_TRUE(Preamble);
+ {
+ // Case 1: non-static
+ const auto Result = signatureHelp(testPath(TU.Filename), Code.point("c1"),
+ *Preamble, Inputs, MarkupKind::PlainText);
+ EXPECT_EQ(1U, Result.signatures.size());
+ EXPECT_THAT(Result.signatures[0],
+ AllOf(sig("operator()([[bool a]]) -> void")));
+ }
+ {
+ // Case 2: static
+ const auto Result = signatureHelp(testPath(TU.Filename), Code.point("c2"),
+ *Preamble, Inputs, MarkupKind::PlainText);
+ EXPECT_EQ(1U, Result.signatures.size());
+ EXPECT_THAT(Result.signatures[0],
+ AllOf(sig("operator()([[bool a]]) -> void")));
+ }
+ {
+ // Case 3: static template operator()
+ Annotations TemplateCode(R"cpp(
+ struct AbcTemplate {
+ template <typename T>
+ static void operator()(T a, bool b) {}
+ };
+ void test() {
+ AbcTemplate abcTemplate;
+ abcTemplate($c3^);
+ }
+ )cpp");
+ auto TU2 = TestTU::withCode(TemplateCode.code());
+ TU2.ExtraArgs = {"-std=c++23"};
+ MockFS FS2;
+ auto Inputs2 = TU2.inputs(FS2);
+ auto Preamble2 = TU2.preamble();
+ ASSERT_TRUE(Preamble2);
+ const auto Result =
+ signatureHelp(testPath(TU2.Filename), TemplateCode.point("c3"),
+ *Preamble2, Inputs2, MarkupKind::PlainText);
+ EXPECT_EQ(1U, Result.signatures.size());
+ }
+
+ {
+ Annotations TemplateCode2(R"cpp(
+ struct AbcTemplate2 {
+ template <typename T>
+ static void operator()(bool a, bool b) { T c; }
+ };
+ void test() {
+ AbcTemplate2 abcTemplate2;
+ abcTemplate2($c4^);
+ }
+ )cpp");
+ auto TU3 = TestTU::withCode(TemplateCode2.code());
+ TU3.ExtraArgs = {"-std=c++23"};
+ MockFS FS3;
+ auto Inputs3 = TU3.inputs(FS3);
+ auto Preamble3 = TU3.preamble();
+ ASSERT_TRUE(Preamble3);
+ const auto Result =
+ signatureHelp(testPath(TU3.Filename), TemplateCode2.point("c4"),
+ *Preamble3, Inputs3, MarkupKind::PlainText);
+ EXPECT_EQ(1U, Result.signatures.size());
+ EXPECT_THAT(Result.signatures[0],
+ AllOf(sig("operator()([[bool a]], [[bool b]]) -> void")));
+ }
+}
+
TEST(CompletionTest, IncludedCompletionKinds) {
Annotations Test(R"cpp(#include "^)cpp");
auto TU = TestTU::withCode(Test.code());
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 74264ec3906ff..6e97bd0e7a495 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6472,14 +6472,37 @@ SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args,
LookupResult R(SemaRef, OpName, Loc, Sema::LookupOrdinaryName);
SemaRef.LookupQualifiedName(R, DC);
R.suppressDiagnostics();
- SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
- ArgExprs.append(ArgsWithoutDependentTypes.begin(),
- ArgsWithoutDependentTypes.end());
- SemaRef.AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs,
- CandidateSet,
- /*ExplicitArgs=*/nullptr,
- /*SuppressUserConversions=*/false,
- /*PartialOverloading=*/true);
+ for (NamedDecl *D : R) {
+ NamedDecl *UD = D->getUnderlyingDecl();
+ if (auto *FD = dyn_cast<FunctionDecl>(UD)) {
+ if (FD->isStatic()) {
+ SemaRef.AddOverloadCandidate(
+ FD, DeclAccessPair::make(FD, FD->getAccess()),
+ ArgsWithoutDependentTypes, CandidateSet,
+ /*SuppressUserConversions=*/false,
+ /*PartialOverloading=*/true);
+ continue;
+ }
+ } else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(UD)) {
+ if (FTD->getTemplatedDecl()->isStatic()) {
+ SemaRef.AddTemplateOverloadCandidate(
+ FTD, DeclAccessPair::make(FTD, FTD->getAccess()), nullptr,
+ ArgsWithoutDependentTypes, CandidateSet,
+ /*SuppressUserConversions=*/false,
+ /*PartialOverloading=*/true);
+ continue;
+ }
+ }
+ SmallVector<Expr *, 12> ArgExprs(1, NakedFn);
+ ArgExprs.append(ArgsWithoutDependentTypes.begin(),
+ ArgsWithoutDependentTypes.end());
+ UnresolvedSet<1> Candidate;
+ Candidate.addDecl(D, D->getAccess());
+ SemaRef.AddFunctionCandidates(Candidate, ArgExprs, CandidateSet,
+ /*ExplicitArgs=*/nullptr,
+ /*SuppressUserConversions=*/false,
+ /*PartialOverloading=*/true);
+ }
}
} else {
// Lastly we check whether expression's type is function pointer or
More information about the cfe-commits
mailing list