[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