[clang] [clang-tools-extra] [clangd] Fixed signature help for static call operator (C++23) (PR #199192)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 22 03:02:30 PDT 2026
https://github.com/Ippo47 updated https://github.com/llvm/llvm-project/pull/199192
>From abf7ea91863482ddbf2b5b76d767d813e197f933 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 | 89 +++++++++++++++++++
clang/lib/Sema/SemaCodeComplete.cpp | 19 ++++
2 files changed, 108 insertions(+)
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 5808b2145965f..1fbb880121597 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -3494,6 +3494,95 @@ 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());
+ EXPECT_THAT(Result.signatures[0],
+ AllOf(sig("operator()([[T a]], [[bool b]]) -> void")));
+ }
+
+ {
+ 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 bef5eea9ed442..d0fbc05cc257c 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6486,6 +6486,25 @@ SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, ArrayRef<Expr *> Args,
LookupResult R(SemaRef, OpName, Loc, Sema::LookupOrdinaryName);
SemaRef.LookupQualifiedName(R, DC);
R.suppressDiagnostics();
+ for (NamedDecl *D : R) {
+ NamedDecl *UD = D->getUnderlyingDecl();
+ if (auto *FD = dyn_cast<FunctionDecl>(UD); FD && 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);
+ FTD && 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());
More information about the cfe-commits
mailing list