[PATCH] D158926: [clangd] Show parameter hints for operator()

2023-09-10 Thread Younan Zhang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGcbd6ac6165e6: [clangd] Show parameter hints for operator() 
(authored by zyounan).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158926/new/

https://reviews.llvm.org/D158926

Files:
  clang-tools-extra/clangd/InlayHints.cpp
  clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp
===
--- clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -89,7 +89,7 @@
ExpectedHints... Expected) {
   Annotations Source(AnnotatedSource);
   TestTU TU = TestTU::withCode(Source.code());
-  TU.ExtraArgs.push_back("-std=c++20");
+  TU.ExtraArgs.push_back("-std=c++23");
   TU.HeaderCode = HeaderContent;
   auto AST = TU.build();
 
@@ -807,6 +807,42 @@
   )cpp");
 }
 
+TEST(ParameterHints, FunctionCallOperator) {
+  assertParameterHints(R"cpp(
+struct W {
+  void operator()(int x);
+};
+struct S : W {
+  using W::operator();
+  static void operator()(int x, int y);
+};
+void bar() {
+  auto l1 = [](int x) {};
+  auto l2 = [](int x) static {};
+
+  S s;
+  s($1[[1]]);
+  s.operator()($2[[1]]);
+  s.operator()($3[[1]], $4[[2]]);
+  S::operator()($5[[1]], $6[[2]]);
+
+  l1($7[[1]]);
+  l1.operator()($8[[1]]);
+  l2($9[[1]]);
+  l2.operator()($10[[1]]);
+
+  void (*ptr)(int a, int b) = &S::operator();
+  ptr($11[[1]], $12[[2]]);
+}
+  )cpp",
+   ExpectedHint{"x: ", "1"}, ExpectedHint{"x: ", "2"},
+   ExpectedHint{"x: ", "3"}, ExpectedHint{"y: ", "4"},
+   ExpectedHint{"x: ", "5"}, ExpectedHint{"y: ", "6"},
+   ExpectedHint{"x: ", "7"}, ExpectedHint{"x: ", "8"},
+   ExpectedHint{"x: ", "9"}, ExpectedHint{"x: ", "10"},
+   ExpectedHint{"a: ", "11"}, ExpectedHint{"b: ", "12"});
+}
+
 TEST(ParameterHints, Macros) {
   // Handling of macros depends on where the call's argument list comes from.
 
Index: clang-tools-extra/clangd/InlayHints.cpp
===
--- clang-tools-extra/clangd/InlayHints.cpp
+++ clang-tools-extra/clangd/InlayHints.cpp
@@ -586,11 +586,13 @@
 if (!Cfg.InlayHints.Parameters)
   return true;
 
-// Do not show parameter hints for operator calls written using operator
-// syntax or user-defined literals. (Among other reasons, the resulting
+bool IsFunctor = isFunctionObjectCallExpr(E);
+// Do not show parameter hints for user-defined literals or
+// operator calls except for operator(). (Among other reasons, the resulting
 // hints can look awkward, e.g. the expression can itself be a function
 // argument and then we'd get two hints side by side).
-if (isa(E) || isa(E))
+if ((isa(E) && !IsFunctor) ||
+isa(E))
   return true;
 
 auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E);
@@ -607,7 +609,22 @@
 else
   return true;
 
-processCall(Callee, {E->getArgs(), E->getNumArgs()});
+// N4868 [over.call.object]p3 says,
+// The argument list submitted to overload resolution consists of the
+// argument expressions present in the function call syntax preceded by the
+// implied object argument (E).
+//
+// However, we don't have the implied object argument for static
+// operator() per clang::Sema::BuildCallToObjectOfClassType.
+llvm::ArrayRef Args = {E->getArgs(), E->getNumArgs()};
+if (IsFunctor)
+  // We don't have the implied object argument through
+  // a function pointer either.
+  if (const CXXMethodDecl *Method =
+  dyn_cast_or_null(Callee.Decl);
+  Method && Method->isInstance())
+Args = Args.drop_front(1);
+processCall(Callee, Args);
 return true;
   }
 
@@ -1203,6 +1220,12 @@
 return Range{HintStart, HintEnd};
   }
 
+  static bool isFunctionObjectCallExpr(CallExpr *E) noexcept {
+if (auto *CallExpr = dyn_cast(E))
+  return CallExpr->getOperator() == OverloadedOperatorKind::OO_Call;
+return false;
+  }
+
   std::vector &Results;
   ASTContext *
   const syntax::TokenBuffer &Tokens;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158926: [clangd] Show parameter hints for operator()

2023-09-09 Thread Younan Zhang via Phabricator via cfe-commits
zyounan updated this revision to Diff 556358.
zyounan marked an inline comment as done.
zyounan added a comment.

Address a nit comment


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158926/new/

https://reviews.llvm.org/D158926

Files:
  clang-tools-extra/clangd/InlayHints.cpp
  clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp
===
--- clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -89,7 +89,7 @@
ExpectedHints... Expected) {
   Annotations Source(AnnotatedSource);
   TestTU TU = TestTU::withCode(Source.code());
-  TU.ExtraArgs.push_back("-std=c++20");
+  TU.ExtraArgs.push_back("-std=c++23");
   TU.HeaderCode = HeaderContent;
   auto AST = TU.build();
 
@@ -807,6 +807,42 @@
   )cpp");
 }
 
+TEST(ParameterHints, FunctionCallOperator) {
+  assertParameterHints(R"cpp(
+struct W {
+  void operator()(int x);
+};
+struct S : W {
+  using W::operator();
+  static void operator()(int x, int y);
+};
+void bar() {
+  auto l1 = [](int x) {};
+  auto l2 = [](int x) static {};
+
+  S s;
+  s($1[[1]]);
+  s.operator()($2[[1]]);
+  s.operator()($3[[1]], $4[[2]]);
+  S::operator()($5[[1]], $6[[2]]);
+
+  l1($7[[1]]);
+  l1.operator()($8[[1]]);
+  l2($9[[1]]);
+  l2.operator()($10[[1]]);
+
+  void (*ptr)(int a, int b) = &S::operator();
+  ptr($11[[1]], $12[[2]]);
+}
+  )cpp",
+   ExpectedHint{"x: ", "1"}, ExpectedHint{"x: ", "2"},
+   ExpectedHint{"x: ", "3"}, ExpectedHint{"y: ", "4"},
+   ExpectedHint{"x: ", "5"}, ExpectedHint{"y: ", "6"},
+   ExpectedHint{"x: ", "7"}, ExpectedHint{"x: ", "8"},
+   ExpectedHint{"x: ", "9"}, ExpectedHint{"x: ", "10"},
+   ExpectedHint{"a: ", "11"}, ExpectedHint{"b: ", "12"});
+}
+
 TEST(ParameterHints, Macros) {
   // Handling of macros depends on where the call's argument list comes from.
 
Index: clang-tools-extra/clangd/InlayHints.cpp
===
--- clang-tools-extra/clangd/InlayHints.cpp
+++ clang-tools-extra/clangd/InlayHints.cpp
@@ -586,11 +586,13 @@
 if (!Cfg.InlayHints.Parameters)
   return true;
 
-// Do not show parameter hints for operator calls written using operator
-// syntax or user-defined literals. (Among other reasons, the resulting
+bool IsFunctor = isFunctionObjectCallExpr(E);
+// Do not show parameter hints for user-defined literals or
+// operator calls except for operator(). (Among other reasons, the resulting
 // hints can look awkward, e.g. the expression can itself be a function
 // argument and then we'd get two hints side by side).
-if (isa(E) || isa(E))
+if ((isa(E) && !IsFunctor) ||
+isa(E))
   return true;
 
 auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E);
@@ -607,7 +609,22 @@
 else
   return true;
 
-processCall(Callee, {E->getArgs(), E->getNumArgs()});
+// N4868 [over.call.object]p3 says,
+// The argument list submitted to overload resolution consists of the
+// argument expressions present in the function call syntax preceded by the
+// implied object argument (E).
+//
+// However, we don't have the implied object argument for static
+// operator() per clang::Sema::BuildCallToObjectOfClassType.
+llvm::ArrayRef Args = {E->getArgs(), E->getNumArgs()};
+if (IsFunctor)
+  // We don't have the implied object argument through
+  // a function pointer either.
+  if (const CXXMethodDecl *Method =
+  dyn_cast_or_null(Callee.Decl);
+  Method && Method->isInstance())
+Args = Args.drop_front(1);
+processCall(Callee, Args);
 return true;
   }
 
@@ -1203,6 +1220,12 @@
 return Range{HintStart, HintEnd};
   }
 
+  static bool isFunctionObjectCallExpr(CallExpr *E) noexcept {
+if (auto *CallExpr = dyn_cast(E))
+  return CallExpr->getOperator() == OverloadedOperatorKind::OO_Call;
+return false;
+  }
+
   std::vector &Results;
   ASTContext *
   const syntax::TokenBuffer &Tokens;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158926: [clangd] Show parameter hints for operator()

2023-09-09 Thread Younan Zhang via Phabricator via cfe-commits
zyounan marked 2 inline comments as done.
zyounan added inline comments.



Comment at: clang-tools-extra/clangd/InlayHints.cpp:626
+  Method && Method->isInstance())
+Args = Args.drop_front(1);
+processCall(Callee, Args);

nridge wrote:
> Huh, that's an interesting inconsistency between CXXMemberCallExpr and 
> CXXOperatorCallExpr (that one include th implied object argument in getArgs() 
> and the other doesn't)
> 
> As always, thank you for writing thorough tests that give us confidence we're 
> doing the right thing :)
I'm glad to hear that! Thank you.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158926/new/

https://reviews.llvm.org/D158926

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158926: [clangd] Show parameter hints for operator()

2023-09-05 Thread Nathan Ridge via Phabricator via cfe-commits
nridge accepted this revision.
nridge added inline comments.
This revision is now accepted and ready to land.



Comment at: clang-tools-extra/clangd/InlayHints.cpp:626
+  Method && Method->isInstance())
+Args = Args.drop_front(1);
+processCall(Callee, Args);

Huh, that's an interesting inconsistency between CXXMemberCallExpr and 
CXXOperatorCallExpr (that one include th implied object argument in getArgs() 
and the other doesn't)

As always, thank you for writing thorough tests that give us confidence we're 
doing the right thing :)



Comment at: clang-tools-extra/clangd/InlayHints.cpp:1222
 
+  bool isFunctionObjectCallExpr(CallExpr *E) const noexcept {
+if (auto *CallExpr = dyn_cast(E))

nit: this method can be static


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D158926/new/

https://reviews.llvm.org/D158926

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D158926: [clangd] Show parameter hints for operator()

2023-08-26 Thread Younan Zhang via Phabricator via cfe-commits
zyounan created this revision.
zyounan added a reviewer: nridge.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
zyounan requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

Closes https://github.com/clangd/clangd/issues/1742


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D158926

Files:
  clang-tools-extra/clangd/InlayHints.cpp
  clang-tools-extra/clangd/unittests/InlayHintTests.cpp

Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp
===
--- clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -89,7 +89,7 @@
ExpectedHints... Expected) {
   Annotations Source(AnnotatedSource);
   TestTU TU = TestTU::withCode(Source.code());
-  TU.ExtraArgs.push_back("-std=c++20");
+  TU.ExtraArgs.push_back("-std=c++23");
   TU.HeaderCode = HeaderContent;
   auto AST = TU.build();
 
@@ -807,6 +807,42 @@
   )cpp");
 }
 
+TEST(ParameterHints, FunctionCallOperator) {
+  assertParameterHints(R"cpp(
+struct W {
+  void operator()(int x);
+};
+struct S : W {
+  using W::operator();
+  static void operator()(int x, int y);
+};
+void bar() {
+  auto l1 = [](int x) {};
+  auto l2 = [](int x) static {};
+
+  S s;
+  s($1[[1]]);
+  s.operator()($2[[1]]);
+  s.operator()($3[[1]], $4[[2]]);
+  S::operator()($5[[1]], $6[[2]]);
+
+  l1($7[[1]]);
+  l1.operator()($8[[1]]);
+  l2($9[[1]]);
+  l2.operator()($10[[1]]);
+
+  void (*ptr)(int a, int b) = &S::operator();
+  ptr($11[[1]], $12[[2]]);
+}
+  )cpp",
+   ExpectedHint{"x: ", "1"}, ExpectedHint{"x: ", "2"},
+   ExpectedHint{"x: ", "3"}, ExpectedHint{"y: ", "4"},
+   ExpectedHint{"x: ", "5"}, ExpectedHint{"y: ", "6"},
+   ExpectedHint{"x: ", "7"}, ExpectedHint{"x: ", "8"},
+   ExpectedHint{"x: ", "9"}, ExpectedHint{"x: ", "10"},
+   ExpectedHint{"a: ", "11"}, ExpectedHint{"b: ", "12"});
+}
+
 TEST(ParameterHints, Macros) {
   // Handling of macros depends on where the call's argument list comes from.
 
Index: clang-tools-extra/clangd/InlayHints.cpp
===
--- clang-tools-extra/clangd/InlayHints.cpp
+++ clang-tools-extra/clangd/InlayHints.cpp
@@ -586,11 +586,13 @@
 if (!Cfg.InlayHints.Parameters)
   return true;
 
-// Do not show parameter hints for operator calls written using operator
-// syntax or user-defined literals. (Among other reasons, the resulting
+bool IsFunctor = isFunctionObjectCallExpr(E);
+// Do not show parameter hints for user-defined literals or
+// operator calls except for operator(). (Among other reasons, the resulting
 // hints can look awkward, e.g. the expression can itself be a function
 // argument and then we'd get two hints side by side).
-if (isa(E) || isa(E))
+if ((isa(E) && !IsFunctor) ||
+isa(E))
   return true;
 
 auto CalleeDecls = Resolver->resolveCalleeOfCallExpr(E);
@@ -607,7 +609,22 @@
 else
   return true;
 
-processCall(Callee, {E->getArgs(), E->getNumArgs()});
+// N4868 [over.call.object]p3 says,
+// The argument list submitted to overload resolution consists of the
+// argument expressions present in the function call syntax preceded by the
+// implied object argument (E).
+//
+// However, we don't have the implied object argument for static
+// operator() per clang::Sema::BuildCallToObjectOfClassType.
+llvm::ArrayRef Args = {E->getArgs(), E->getNumArgs()};
+if (IsFunctor)
+  // We don't have the implied object argument through
+  // a function pointer either.
+  if (const CXXMethodDecl *Method =
+  dyn_cast_or_null(Callee.Decl);
+  Method && Method->isInstance())
+Args = Args.drop_front(1);
+processCall(Callee, Args);
 return true;
   }
 
@@ -1202,6 +1219,12 @@
 return Range{HintStart, HintEnd};
   }
 
+  bool isFunctionObjectCallExpr(CallExpr *E) const noexcept {
+if (auto *CallExpr = dyn_cast(E))
+  return CallExpr->getOperator() == OverloadedOperatorKind::OO_Call;
+return false;
+  }
+
   std::vector &Results;
   ASTContext *
   const syntax::TokenBuffer &Tokens;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits