[PATCH] D130260: [clangd] Make forwarding parameter detection logic resilient
Kadir Cetinkaya via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 22 02:54:25 PDT 2022
kadircet updated this revision to Diff 446759.
kadircet added a comment.
- Check to ensure function call receives all the arguments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D130260/new/
https://reviews.llvm.org/D130260
Files:
clang-tools-extra/clangd/AST.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
@@ -1429,6 +1429,50 @@
ElementsAre(labelIs(": int"), labelIs(": char")));
}
+TEST(ParameterHints, ArgPacksAndConstructors) {
+ assertParameterHints(
+ R"cpp(
+ struct Foo{ Foo(); Foo(int x); };
+ void foo(Foo a, int b);
+ template <typename... Args>
+ void bar(Args... args) {
+ foo(args...);
+ }
+ template <typename... Args>
+ void baz(Args... args) { foo($param1[[Foo{args...}]], $param2[[1]]); }
+
+ template <typename... Args>
+ void bax(Args... args) { foo($param3[[{args...}]], args...); }
+
+ void foo() {
+ bar($param4[[Foo{}]], $param5[[42]]);
+ bar($param6[[42]], $param7[[42]]);
+ baz($param8[[42]]);
+ bax($param9[[42]]);
+ }
+ )cpp",
+ ExpectedHint{"a: ", "param1"}, ExpectedHint{"b: ", "param2"},
+ ExpectedHint{"a: ", "param3"}, ExpectedHint{"a: ", "param4"},
+ ExpectedHint{"b: ", "param5"}, ExpectedHint{"a: ", "param6"},
+ ExpectedHint{"b: ", "param7"}, ExpectedHint{"x: ", "param8"},
+ ExpectedHint{"b: ", "param9"});
+}
+
+TEST(ParameterHints, DoesntExpandAllArgs) {
+ assertParameterHints(
+ R"cpp(
+ void foo(int x, int y);
+ int id(int a, int b);
+ template <typename... Args>
+ void bar(Args... args) {
+ foo(id($param1[[args]], $param2[[1]])...);
+ }
+ void foo() {
+ bar(1, 2);
+ }
+ )cpp",
+ ExpectedHint{"a: ", "param1"}, ExpectedHint{"b: ", "param2"});
+}
// FIXME: Low-hanging fruit where we could omit a type hint:
// - auto x = TypeName(...);
// - auto x = (TypeName) (...);
Index: clang-tools-extra/clangd/AST.cpp
===================================================================
--- clang-tools-extra/clangd/AST.cpp
+++ clang-tools-extra/clangd/AST.cpp
@@ -786,6 +786,9 @@
// inspects the given callee with the given args to check whether it
// contains Parameters, and sets Info accordingly.
void handleCall(FunctionDecl *Callee, typename CallExpr::arg_range Args) {
+ // Skip functions with less parameters, they can't be the target.
+ if (Callee->parameters().size() < Parameters.size())
+ return;
if (std::any_of(Args.begin(), Args.end(), [](const Expr *E) {
return dyn_cast<PackExpansionExpr>(E) != nullptr;
})) {
@@ -823,10 +826,14 @@
llvm::Optional<size_t> findPack(typename CallExpr::arg_range Args) {
// find the argument directly referring to the first parameter
for (auto It = Args.begin(); It != Args.end(); ++It) {
- const Expr *Arg = *It;
- if (const auto *RefArg = unwrapForward(Arg)) {
+ if (const auto *RefArg = unwrapForward(*It)) {
if (Parameters.front() != RefArg->getDecl())
continue;
+ // Check that this expands all the way until the last parameter.
+ auto ParamEnd = It + Parameters.size() - 1;
+ RefArg = unwrapForward(*ParamEnd);
+ if (!RefArg || Parameters.back() != RefArg->getDecl())
+ continue;
return std::distance(Args.begin(), It);
}
}
@@ -872,6 +879,13 @@
// std::forward.
static const DeclRefExpr *unwrapForward(const Expr *E) {
E = E->IgnoreImplicitAsWritten();
+ // There might be an implicit copy/move constructor call on top of the
+ // forwarded arg.
+ // FIXME: Maybe mark that in the AST as so, this might skip explicit calls
+ // too.
+ if (const auto *Const = dyn_cast<CXXConstructExpr>(E))
+ if (Const->getConstructor()->isCopyOrMoveConstructor())
+ E = Const->getArg(0)->IgnoreImplicitAsWritten();
if (const auto *Call = dyn_cast<CallExpr>(E)) {
const auto Callee = Call->getBuiltinCallee();
if (Callee == Builtin::BIforward) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D130260.446759.patch
Type: text/x-patch
Size: 3920 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220722/0d2e97fb/attachment-0001.bin>
More information about the cfe-commits
mailing list