[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-05 Thread Timothy Akintilo via cfe-commits

tilobyte wrote:

ping

tagging clangd code owner for review: @sam-mccall

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-07 Thread Timothy Akintilo via cfe-commits

https://github.com/tilobyte updated 
https://github.com/llvm/llvm-project/pull/101857

>From c1afe853ccacae1605fecfe552bb9a263c6b8c1d Mon Sep 17 00:00:00 2001
From: Timothy Akintilo 
Date: Sat, 27 Jul 2024 16:17:46 -0500
Subject: [PATCH 1/3] use lambda name instead of operator()

---
 clang-tools-extra/clangd/CodeComplete.cpp |  2 ++
 .../clangd/unittests/CodeCompleteTests.cpp|  9 +++
 .../include/clang/Sema/CodeCompleteConsumer.h | 18 ++
 clang/include/clang/Sema/Overload.h   |  5 
 clang/include/clang/Sema/Sema.h   | 22 -
 clang/lib/Sema/CodeCompleteConsumer.cpp   | 10 +++-
 clang/lib/Sema/SemaCodeComplete.cpp   | 17 ++---
 clang/lib/Sema/SemaLookup.cpp |  3 ++-
 clang/lib/Sema/SemaOverload.cpp   | 24 +--
 9 files changed, 82 insertions(+), 28 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 89eee392837af4..4f8a53aa7aae7e 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1139,6 +1139,8 @@ class SignatureHelpCollector final : public 
CodeCompleteConsumer {
   switch (K) {
   case OC::CK_Aggregate:
 return 0;
+  case OC::CK_Lambda:
+[[fallthrough]];
   case OC::CK_Function:
 return 1;
   case OC::CK_FunctionType:
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 96d1ee1f0add73..4f748168d75aa7 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1437,6 +1437,15 @@ TEST(SignatureHelpTest, Overloads) {
   EXPECT_EQ(0, Results.activeParameter);
 }
 
+TEST(SignatureHelpTest, ShowLambdaNameInsteadOfOperatorParens) {
+  auto const Results = signatures(R"cpp(
+auto foo = [](int x, int y){};
+int main() { foo(^); }
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+  UnorderedElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
+}
+
 TEST(SignatureHelpTest, FunctionPointers) {
   llvm::StringLiteral Tests[] = {
   // Variable of function pointer type
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h 
b/clang/include/clang/Sema/CodeCompleteConsumer.h
index 0924dc27af82b5..a6530c3c93d912 100644
--- a/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -1028,6 +1028,9 @@ class CodeCompleteConsumer {
   /// The candidate is a function declaration.
   CK_Function,
 
+  // The candidate is a lambda operator().
+  CK_Lambda,
+
   /// The candidate is a function template, arguments are being completed.
   CK_FunctionTemplate,
 
@@ -1055,6 +1058,13 @@ class CodeCompleteConsumer {
   /// Kind == CK_Function.
   FunctionDecl *Function;
 
+  /// The lambda operator() candidate paired with the
+  /// lambda variable, available when Kind == CK_Lambda.
+  struct {
+FunctionDecl *OperatorParens;
+VarDecl *Var;
+  } Lambda;
+
   /// The function template overload candidate, available when
   /// Kind == CK_FunctionTemplate.
   FunctionTemplateDecl *FunctionTemplate;
@@ -1082,6 +1092,12 @@ class CodeCompleteConsumer {
   assert(Function != nullptr);
 }
 
+OverloadCandidate(FunctionDecl *LambdaOperatorParens, VarDecl *LambdaVar)
+: Kind(CK_Lambda), Lambda{LambdaOperatorParens, LambdaVar} {
+  assert(Lambda.OperatorParens != nullptr);
+  assert(Lambda.Var != nullptr);
+}
+
 OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
 : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {
   assert(FunctionTemplateDecl != nullptr);
@@ -1112,6 +1128,8 @@ class CodeCompleteConsumer {
 /// function declaration for a function template.
 FunctionDecl *getFunction() const;
 
+VarDecl *getLambdaVarDecl() const;
+
 /// Retrieve the function template overload candidate.
 FunctionTemplateDecl *getFunctionTemplate() const {
   assert(getKind() == CK_FunctionTemplate && "Not a function template");
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index d6a6cee62a7528..7c4e82f07de02e 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};
+
 /// FoundDecl - The original declaration that was looked up /
 /// invented / otherwise found, together with its access.
 /// Might be a UsingShadowDecl or a FunctionTemplateDec

[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits

https://github.com/tilobyte updated 
https://github.com/llvm/llvm-project/pull/101857

>From c1afe853ccacae1605fecfe552bb9a263c6b8c1d Mon Sep 17 00:00:00 2001
From: Timothy Akintilo 
Date: Sat, 27 Jul 2024 16:17:46 -0500
Subject: [PATCH 1/7] use lambda name instead of operator()

---
 clang-tools-extra/clangd/CodeComplete.cpp |  2 ++
 .../clangd/unittests/CodeCompleteTests.cpp|  9 +++
 .../include/clang/Sema/CodeCompleteConsumer.h | 18 ++
 clang/include/clang/Sema/Overload.h   |  5 
 clang/include/clang/Sema/Sema.h   | 22 -
 clang/lib/Sema/CodeCompleteConsumer.cpp   | 10 +++-
 clang/lib/Sema/SemaCodeComplete.cpp   | 17 ++---
 clang/lib/Sema/SemaLookup.cpp |  3 ++-
 clang/lib/Sema/SemaOverload.cpp   | 24 +--
 9 files changed, 82 insertions(+), 28 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 89eee392837af4..4f8a53aa7aae7e 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1139,6 +1139,8 @@ class SignatureHelpCollector final : public 
CodeCompleteConsumer {
   switch (K) {
   case OC::CK_Aggregate:
 return 0;
+  case OC::CK_Lambda:
+[[fallthrough]];
   case OC::CK_Function:
 return 1;
   case OC::CK_FunctionType:
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 96d1ee1f0add73..4f748168d75aa7 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1437,6 +1437,15 @@ TEST(SignatureHelpTest, Overloads) {
   EXPECT_EQ(0, Results.activeParameter);
 }
 
+TEST(SignatureHelpTest, ShowLambdaNameInsteadOfOperatorParens) {
+  auto const Results = signatures(R"cpp(
+auto foo = [](int x, int y){};
+int main() { foo(^); }
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+  UnorderedElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
+}
+
 TEST(SignatureHelpTest, FunctionPointers) {
   llvm::StringLiteral Tests[] = {
   // Variable of function pointer type
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h 
b/clang/include/clang/Sema/CodeCompleteConsumer.h
index 0924dc27af82b5..a6530c3c93d912 100644
--- a/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -1028,6 +1028,9 @@ class CodeCompleteConsumer {
   /// The candidate is a function declaration.
   CK_Function,
 
+  // The candidate is a lambda operator().
+  CK_Lambda,
+
   /// The candidate is a function template, arguments are being completed.
   CK_FunctionTemplate,
 
@@ -1055,6 +1058,13 @@ class CodeCompleteConsumer {
   /// Kind == CK_Function.
   FunctionDecl *Function;
 
+  /// The lambda operator() candidate paired with the
+  /// lambda variable, available when Kind == CK_Lambda.
+  struct {
+FunctionDecl *OperatorParens;
+VarDecl *Var;
+  } Lambda;
+
   /// The function template overload candidate, available when
   /// Kind == CK_FunctionTemplate.
   FunctionTemplateDecl *FunctionTemplate;
@@ -1082,6 +1092,12 @@ class CodeCompleteConsumer {
   assert(Function != nullptr);
 }
 
+OverloadCandidate(FunctionDecl *LambdaOperatorParens, VarDecl *LambdaVar)
+: Kind(CK_Lambda), Lambda{LambdaOperatorParens, LambdaVar} {
+  assert(Lambda.OperatorParens != nullptr);
+  assert(Lambda.Var != nullptr);
+}
+
 OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
 : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {
   assert(FunctionTemplateDecl != nullptr);
@@ -1112,6 +1128,8 @@ class CodeCompleteConsumer {
 /// function declaration for a function template.
 FunctionDecl *getFunction() const;
 
+VarDecl *getLambdaVarDecl() const;
+
 /// Retrieve the function template overload candidate.
 FunctionTemplateDecl *getFunctionTemplate() const {
   assert(getKind() == CK_FunctionTemplate && "Not a function template");
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index d6a6cee62a7528..7c4e82f07de02e 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};
+
 /// FoundDecl - The original declaration that was looked up /
 /// invented / otherwise found, together with its access.
 /// Might be a UsingShadowDecl or a FunctionTemplateDec

[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -6292,11 +6298,16 @@ SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, 
ArrayRef Args,
 SmallVector ArgExprs(1, NakedFn);
 ArgExprs.append(ArgsWithoutDependentTypes.begin(),
 ArgsWithoutDependentTypes.end());
+auto *const LambdaName =
+DC->isLambda() ? 
cast(NakedFn->getReferencedDeclOfCallee())
+   : nullptr;
 SemaRef.AddFunctionCandidates(R.asUnresolvedSet(), ArgExprs,
   CandidateSet,
   /*ExplicitArgs=*/nullptr,
   /*SuppressUserConversions=*/false,
-  /*PartialOverloading=*/true);
+  /*PartialOverloading=*/true,
+  /*FirstArgumentIsBase=*/false,
+  /*LambdaName=*/LambdaName);

tilobyte wrote:

i see, renamed to `LambdaDecl`

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -6292,11 +6298,16 @@ SemaCodeCompletion::ProduceCallSignatureHelp(Expr *Fn, 
ArrayRef Args,
 SmallVector ArgExprs(1, NakedFn);
 ArgExprs.append(ArgsWithoutDependentTypes.begin(),
 ArgsWithoutDependentTypes.end());
+auto *const LambdaName =
+DC->isLambda() ? 
cast(NakedFn->getReferencedDeclOfCallee())

tilobyte wrote:

@erichkeane stepping through the test i added for a lambda returned from a 
function, `NakedFn->getReferencedDeclOfCallee()` returns `nullptr` in the case 
of a lambda returned from a function. i believe this is because `NakedFn` is an 
rvalue, so there is no referenced decl to get.
using `cast_if_present`/`dyn_cast_if_present` seems to cover that case.

@zyn0217 yes, you are correct that `NakedFn` is a `DeclRefExpr` referring to 
the `VarDecl` of the declaration. `dyn_cast_if_present` indeed works, though i 
wonder--if `NakedFn->getReferencedDeclOfCallee()` returns `nullptr` in the case 
of a lambda returned from a function, could we get away with just 
`cast_if_present`?

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -1437,6 +1437,15 @@ TEST(SignatureHelpTest, Overloads) {
   EXPECT_EQ(0, Results.activeParameter);
 }
 
+TEST(SignatureHelpTest, ShowLambdaNameInsteadOfOperatorParens) {
+  auto const Results = signatures(R"cpp(
+auto foo = [](int x, int y){};
+int main() { foo(^); }

tilobyte wrote:

yes, added tests for an immediately-invoked lambda and a lambda returned from a 
function.

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -9147,7 +9147,8 @@ class Sema final : public SemaBase {
   ///
   /// \returns true if lookup succeeded, false if it failed.
   bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
-   bool InUnqualifiedLookup = false);
+   bool InUnqualifiedLookup = false,
+   IdentifierInfo const *IdentifierOverride = nullptr);

tilobyte wrote:

removed, but i'll keep that in mind!

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};

tilobyte wrote:

@erichkeane i added tests for immediately-invoked lambdas. could you give an 
example of a lambda in a template-pack? i was thinking something like 
```
template 
auto foo(Lambda... lambda) {
  lambda(^);
}
```
but then the lambda has a name.

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -2390,7 +2390,8 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, 
LookupResult &R,
 }
 
 bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
-   bool InUnqualifiedLookup) {
+   bool InUnqualifiedLookup,
+   IdentifierInfo const *IdentifierOverride) {

tilobyte wrote:

oops sorry, that's a remnant of another solution i tried earlier. removed

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};

tilobyte wrote:

@zyn0217 unfortunately removing the default initializer breaks a bunch of 
tests--need to check to confirm but i believe it's due to the check that 
`LambdaDecl` is `nullptr` here: 
https://github.com/llvm/llvm-project/blob/d8140f9013f47094a159fd2918128d9252ca3280/clang/lib/Sema/SemaCodeComplete.cpp#L6130

i think the fix would just be setting `LambdaDecl` to `nullptr` everywhere we 
make an `OverloadCandidate` for a non-lambda, but the `nullptr` default 
initializer seemed cleaner... let me know if not using a default initializer is 
preferred.

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-08 Thread Timothy Akintilo via cfe-commits


@@ -10204,15 +10205,14 @@ class Sema final : public SemaBase {
   /// both @c a1 and @c a2. If @p SuppressUserConversions, then don't
   /// allow user-defined conversions via constructors or conversion
   /// operators.
-  void
-  AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
- CXXRecordDecl *ActingContext, QualType ObjectType,
- Expr::Classification ObjectClassification,
- ArrayRef Args, OverloadCandidateSet &CandidateSet,
- bool SuppressUserConversions = false,
- bool PartialOverloading = false,
- ConversionSequenceList EarlyConversions = std::nullopt,
- OverloadCandidateParamOrder PO = {});
+  void AddMethodCandidate(
+  CXXMethodDecl *Method, DeclAccessPair FoundDecl,
+  CXXRecordDecl *ActingContext, QualType ObjectType,
+  Expr::Classification ObjectClassification, ArrayRef Args,
+  OverloadCandidateSet &CandidateSet, bool SuppressUserConversions = false,
+  bool PartialOverloading = false,
+  ConversionSequenceList EarlyConversions = std::nullopt,
+  OverloadCandidateParamOrder PO = {}, VarDecl *LambdaName = nullptr);

tilobyte wrote:

sorry, did not get around to this comment this weekend. to be certain, would we 
also not want `LambdaName` (now `LambdaDecl`) to be a default argument for  
`addFunctionCandidates()` above?

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-09 Thread Timothy Akintilo via cfe-commits


@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};

tilobyte wrote:

thanks for the example!
i don't think this patch affects behavior in this scenario. the current 
behavior (preserved in this patch) is not to produce any signature help. i 
believe this is because within `bar()` it is not known that `Ls` has a call 
operator. unless i'm misunderstanding?
https://github.com/user-attachments/assets/f19431e0-3764-4530-8cf7-22cec4f8f228";>

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-09 Thread Timothy Akintilo via cfe-commits

tilobyte wrote:

> I also wonder if we would better off having `CXXRecordDecl` save its 
> 'variable' for lambdas (and look it up from there) rather than this.

saving the `VarDecl` in the lambda's `CXXRecordDecl` indeed sounds like a 
cleaner solution--i will try implementing that before making any changes to 
`AddMethodCandidate()`'s signature, since it wouldn't need the `LambdaDecl` 
parameter any more with this solution.

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-10 Thread Timothy Akintilo via cfe-commits


@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};

tilobyte wrote:

Wait I think I understand now, you mean the signature help when immediately 
invoking the lambdas within the `bar` function call? E.g., `bar([]{...}(^), 
...)`

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-08-11 Thread Timothy Akintilo via cfe-commits

https://github.com/tilobyte updated 
https://github.com/llvm/llvm-project/pull/101857

>From c1afe853ccacae1605fecfe552bb9a263c6b8c1d Mon Sep 17 00:00:00 2001
From: Timothy Akintilo 
Date: Sat, 27 Jul 2024 16:17:46 -0500
Subject: [PATCH 1/2] use lambda name instead of operator()

---
 clang-tools-extra/clangd/CodeComplete.cpp |  2 ++
 .../clangd/unittests/CodeCompleteTests.cpp|  9 +++
 .../include/clang/Sema/CodeCompleteConsumer.h | 18 ++
 clang/include/clang/Sema/Overload.h   |  5 
 clang/include/clang/Sema/Sema.h   | 22 -
 clang/lib/Sema/CodeCompleteConsumer.cpp   | 10 +++-
 clang/lib/Sema/SemaCodeComplete.cpp   | 17 ++---
 clang/lib/Sema/SemaLookup.cpp |  3 ++-
 clang/lib/Sema/SemaOverload.cpp   | 24 +--
 9 files changed, 82 insertions(+), 28 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 89eee392837af4..4f8a53aa7aae7e 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1139,6 +1139,8 @@ class SignatureHelpCollector final : public 
CodeCompleteConsumer {
   switch (K) {
   case OC::CK_Aggregate:
 return 0;
+  case OC::CK_Lambda:
+[[fallthrough]];
   case OC::CK_Function:
 return 1;
   case OC::CK_FunctionType:
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 96d1ee1f0add73..4f748168d75aa7 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1437,6 +1437,15 @@ TEST(SignatureHelpTest, Overloads) {
   EXPECT_EQ(0, Results.activeParameter);
 }
 
+TEST(SignatureHelpTest, ShowLambdaNameInsteadOfOperatorParens) {
+  auto const Results = signatures(R"cpp(
+auto foo = [](int x, int y){};
+int main() { foo(^); }
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+  UnorderedElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
+}
+
 TEST(SignatureHelpTest, FunctionPointers) {
   llvm::StringLiteral Tests[] = {
   // Variable of function pointer type
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h 
b/clang/include/clang/Sema/CodeCompleteConsumer.h
index 0924dc27af82b5..a6530c3c93d912 100644
--- a/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -1028,6 +1028,9 @@ class CodeCompleteConsumer {
   /// The candidate is a function declaration.
   CK_Function,
 
+  // The candidate is a lambda operator().
+  CK_Lambda,
+
   /// The candidate is a function template, arguments are being completed.
   CK_FunctionTemplate,
 
@@ -1055,6 +1058,13 @@ class CodeCompleteConsumer {
   /// Kind == CK_Function.
   FunctionDecl *Function;
 
+  /// The lambda operator() candidate paired with the
+  /// lambda variable, available when Kind == CK_Lambda.
+  struct {
+FunctionDecl *OperatorParens;
+VarDecl *Var;
+  } Lambda;
+
   /// The function template overload candidate, available when
   /// Kind == CK_FunctionTemplate.
   FunctionTemplateDecl *FunctionTemplate;
@@ -1082,6 +1092,12 @@ class CodeCompleteConsumer {
   assert(Function != nullptr);
 }
 
+OverloadCandidate(FunctionDecl *LambdaOperatorParens, VarDecl *LambdaVar)
+: Kind(CK_Lambda), Lambda{LambdaOperatorParens, LambdaVar} {
+  assert(Lambda.OperatorParens != nullptr);
+  assert(Lambda.Var != nullptr);
+}
+
 OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
 : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {
   assert(FunctionTemplateDecl != nullptr);
@@ -1112,6 +1128,8 @@ class CodeCompleteConsumer {
 /// function declaration for a function template.
 FunctionDecl *getFunction() const;
 
+VarDecl *getLambdaVarDecl() const;
+
 /// Retrieve the function template overload candidate.
 FunctionTemplateDecl *getFunctionTemplate() const {
   assert(getKind() == CK_FunctionTemplate && "Not a function template");
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index d6a6cee62a7528..7c4e82f07de02e 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};
+
 /// FoundDecl - The original declaration that was looked up /
 /// invented / otherwise found, together with its access.
 /// Might be a UsingShadowDecl or a FunctionTemplateDec

[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-08-18 Thread Timothy Akintilo via cfe-commits

tilobyte wrote:

Ping

https://github.com/llvm/llvm-project/pull/101857
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [clangd] show lambda name instead of operator() in signature help (PR #101857)

2024-09-11 Thread Timothy Akintilo via cfe-commits

https://github.com/tilobyte updated 
https://github.com/llvm/llvm-project/pull/101857

>From c1afe853ccacae1605fecfe552bb9a263c6b8c1d Mon Sep 17 00:00:00 2001
From: Timothy Akintilo 
Date: Sat, 27 Jul 2024 16:17:46 -0500
Subject: [PATCH 1/9] use lambda name instead of operator()

---
 clang-tools-extra/clangd/CodeComplete.cpp |  2 ++
 .../clangd/unittests/CodeCompleteTests.cpp|  9 +++
 .../include/clang/Sema/CodeCompleteConsumer.h | 18 ++
 clang/include/clang/Sema/Overload.h   |  5 
 clang/include/clang/Sema/Sema.h   | 22 -
 clang/lib/Sema/CodeCompleteConsumer.cpp   | 10 +++-
 clang/lib/Sema/SemaCodeComplete.cpp   | 17 ++---
 clang/lib/Sema/SemaLookup.cpp |  3 ++-
 clang/lib/Sema/SemaOverload.cpp   | 24 +--
 9 files changed, 82 insertions(+), 28 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index 89eee392837af4..4f8a53aa7aae7e 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1139,6 +1139,8 @@ class SignatureHelpCollector final : public 
CodeCompleteConsumer {
   switch (K) {
   case OC::CK_Aggregate:
 return 0;
+  case OC::CK_Lambda:
+[[fallthrough]];
   case OC::CK_Function:
 return 1;
   case OC::CK_FunctionType:
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 96d1ee1f0add73..4f748168d75aa7 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1437,6 +1437,15 @@ TEST(SignatureHelpTest, Overloads) {
   EXPECT_EQ(0, Results.activeParameter);
 }
 
+TEST(SignatureHelpTest, ShowLambdaNameInsteadOfOperatorParens) {
+  auto const Results = signatures(R"cpp(
+auto foo = [](int x, int y){};
+int main() { foo(^); }
+  )cpp");
+  EXPECT_THAT(Results.signatures,
+  UnorderedElementsAre(sig("foo([[int x]], [[int y]]) -> void")));
+}
+
 TEST(SignatureHelpTest, FunctionPointers) {
   llvm::StringLiteral Tests[] = {
   // Variable of function pointer type
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h 
b/clang/include/clang/Sema/CodeCompleteConsumer.h
index 0924dc27af82b5..a6530c3c93d912 100644
--- a/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -1028,6 +1028,9 @@ class CodeCompleteConsumer {
   /// The candidate is a function declaration.
   CK_Function,
 
+  // The candidate is a lambda operator().
+  CK_Lambda,
+
   /// The candidate is a function template, arguments are being completed.
   CK_FunctionTemplate,
 
@@ -1055,6 +1058,13 @@ class CodeCompleteConsumer {
   /// Kind == CK_Function.
   FunctionDecl *Function;
 
+  /// The lambda operator() candidate paired with the
+  /// lambda variable, available when Kind == CK_Lambda.
+  struct {
+FunctionDecl *OperatorParens;
+VarDecl *Var;
+  } Lambda;
+
   /// The function template overload candidate, available when
   /// Kind == CK_FunctionTemplate.
   FunctionTemplateDecl *FunctionTemplate;
@@ -1082,6 +1092,12 @@ class CodeCompleteConsumer {
   assert(Function != nullptr);
 }
 
+OverloadCandidate(FunctionDecl *LambdaOperatorParens, VarDecl *LambdaVar)
+: Kind(CK_Lambda), Lambda{LambdaOperatorParens, LambdaVar} {
+  assert(Lambda.OperatorParens != nullptr);
+  assert(Lambda.Var != nullptr);
+}
+
 OverloadCandidate(FunctionTemplateDecl *FunctionTemplateDecl)
 : Kind(CK_FunctionTemplate), FunctionTemplate(FunctionTemplateDecl) {
   assert(FunctionTemplateDecl != nullptr);
@@ -1112,6 +1128,8 @@ class CodeCompleteConsumer {
 /// function declaration for a function template.
 FunctionDecl *getFunction() const;
 
+VarDecl *getLambdaVarDecl() const;
+
 /// Retrieve the function template overload candidate.
 FunctionTemplateDecl *getFunctionTemplate() const {
   assert(getKind() == CK_FunctionTemplate && "Not a function template");
diff --git a/clang/include/clang/Sema/Overload.h 
b/clang/include/clang/Sema/Overload.h
index d6a6cee62a7528..7c4e82f07de02e 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -876,6 +876,11 @@ class Sema;
 /// function pointer or reference (C++ [over.call.object]).
 FunctionDecl *Function;
 
+/// LambdaName - When the OverloadCandidate is for a
+/// lambda's operator(), points to the declaration of
+/// the lambda variable.
+VarDecl *LambdaName{nullptr};
+
 /// FoundDecl - The original declaration that was looked up /
 /// invented / otherwise found, together with its access.
 /// Might be a UsingShadowDecl or a FunctionTemplateDec