[clang-tools-extra] 4a540ce - [clangd] Adapt Inlay Hint support for Deducing This (#68177)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 23 18:51:47 PDT 2023


Author: Younan Zhang
Date: 2023-10-24T09:51:43+08:00
New Revision: 4a540ceed454f9ef364838469ebc94252dba152e

URL: https://github.com/llvm/llvm-project/commit/4a540ceed454f9ef364838469ebc94252dba152e
DIFF: https://github.com/llvm/llvm-project/commit/4a540ceed454f9ef364838469ebc94252dba152e.diff

LOG: [clangd] Adapt Inlay Hint support for Deducing This (#68177)

This is a follow-up for D140828, making Clangd omit the explicit object
parameter in a call to member function with Deducing This.

Given that the parent patch is still in its infancy and might undergo
several reverting-relanding processes, one can feel free to revert this
if encountering any CI failure. And please let me know if I should alter
anything.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index e6e5e11b889bff8..3da047f95421385 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -528,6 +528,13 @@ static FunctionProtoTypeLoc getPrototypeLoc(Expr *Fn) {
   return {};
 }
 
+ArrayRef<const ParmVarDecl *>
+maybeDropCxxExplicitObjectParameters(ArrayRef<const ParmVarDecl *> Params) {
+  if (!Params.empty() && Params.front()->isExplicitObjectParameter())
+    Params = Params.drop_front(1);
+  return Params;
+}
+
 struct Callee {
   // Only one of Decl or Loc is set.
   // Loc is for calls through function pointers.
@@ -614,15 +621,21 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
     // 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.
+    // As well as the provision from P0847R7 Deducing This [expr.call]p7:
+    // ...If the function is an explicit object member function and there is an
+    // implied object argument ([over.call.func]), the list of provided
+    // arguments is preceded by the implied object argument for the purposes of
+    // this correspondence...
+    //
+    // However, we don't have the implied object argument
+    // for static operator() per clang::Sema::BuildCallToObjectOfClassType.
     llvm::ArrayRef<const Expr *> 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<CXXMethodDecl>(Callee.Decl);
-          Method && Method->isInstance())
+    // We don't have the implied object argument through a function pointer
+    // either.
+    if (const CXXMethodDecl *Method =
+            dyn_cast_or_null<CXXMethodDecl>(Callee.Decl))
+      if (Method->isInstance() &&
+          (IsFunctor || Method->hasCXXExplicitFunctionObjectParameter()))
         Args = Args.drop_front(1);
     processCall(Callee, Args);
     return true;
@@ -849,15 +862,18 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
         if (Ctor->isCopyOrMoveConstructor())
           return;
 
-    auto Params =
-        Callee.Decl ? Callee.Decl->parameters() : Callee.Loc.getParams();
-
+    ArrayRef<const ParmVarDecl *> Params, ForwardedParams;
     // Resolve parameter packs to their forwarded parameter
-    SmallVector<const ParmVarDecl *> ForwardedParams;
-    if (Callee.Decl)
-      ForwardedParams = resolveForwardingParameters(Callee.Decl);
-    else
+    SmallVector<const ParmVarDecl *> ForwardedParamsStorage;
+    if (Callee.Decl) {
+      Params = maybeDropCxxExplicitObjectParameters(Callee.Decl->parameters());
+      ForwardedParamsStorage = resolveForwardingParameters(Callee.Decl);
+      ForwardedParams =
+          maybeDropCxxExplicitObjectParameters(ForwardedParamsStorage);
+    } else {
+      Params = maybeDropCxxExplicitObjectParameters(Callee.Loc.getParams());
       ForwardedParams = {Params.begin(), Params.end()};
+    }
 
     NameVec ParameterNames = chooseParameterNames(ForwardedParams);
 
@@ -1018,7 +1034,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
     return {};
   }
 
-  NameVec chooseParameterNames(SmallVector<const ParmVarDecl *> Parameters) {
+  NameVec chooseParameterNames(ArrayRef<const ParmVarDecl *> Parameters) {
     NameVec ParameterNames;
     for (const auto *P : Parameters) {
       if (isExpandedFromParameterPack(P)) {

diff  --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index a8c3546eb80cc85..20c1cdd985dbc01 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -843,6 +843,34 @@ TEST(ParameterHints, FunctionCallOperator) {
                        ExpectedHint{"a: ", "11"}, ExpectedHint{"b: ", "12"});
 }
 
+TEST(ParameterHints, DeducingThis) {
+  assertParameterHints(R"cpp(
+    struct S {
+      template <typename This>
+      auto operator()(this This &&Self, int Param) {
+        return 42;
+      }
+
+      auto function(this auto &Self, int Param) {
+        return Param;
+      }
+    };
+    void work() {
+      S s;
+      s($1[[42]]);
+      s.function($2[[42]]);
+      S()($3[[42]]);
+      auto lambda = [](this auto &Self, char C) -> void {
+        return Self(C);
+      };
+      lambda($4[['A']]);
+    }
+  )cpp",
+                       ExpectedHint{"Param: ", "1"},
+                       ExpectedHint{"Param: ", "2"},
+                       ExpectedHint{"Param: ", "3"}, ExpectedHint{"C: ", "4"});
+}
+
 TEST(ParameterHints, Macros) {
   // Handling of macros depends on where the call's argument list comes from.
 


        


More information about the cfe-commits mailing list