[clang-tools-extra] a638648 - [clangd] add inlay hints for std::forward-ed parameter packs
Author: Tobias Ribizel Date: 2022-07-06T22:23:18+02:00 New Revision: a638648fef76146634c2199ce7b90c4bc6bfed01 URL: https://github.com/llvm/llvm-project/commit/a638648fef76146634c2199ce7b90c4bc6bfed01 DIFF: https://github.com/llvm/llvm-project/commit/a638648fef76146634c2199ce7b90c4bc6bfed01.diff LOG: [clangd] add inlay hints for std::forward-ed parameter packs This adds special-case treatment for parameter packs in make_unique-like functions to forward parameter names to inlay hints. The parameter packs are being resolved recursively by traversing the function body of forwarding functions looking for expressions matching the (std::forwarded) parameters expanded from a pack. The implementation checks whether parameters are being passed by (rvalue) reference or value and adds reference inlay hints accordingly. The traversal has a limited recursion stack depth, and recursive calls like std::make_tuple are cut off to avoid hinting duplicate parameter names. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D124690 Added: Modified: clang-tools-extra/clangd/AST.cpp clang-tools-extra/clangd/AST.h clang-tools-extra/clangd/InlayHints.cpp clang-tools-extra/clangd/unittests/InlayHintTests.cpp Removed: diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp index ca838618badd9..1bf876102f991 100644 --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -16,19 +16,23 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Specifiers.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" @@ -667,5 +671,300 @@ bool isDeeplyNested(const Decl *D, unsigned MaxDepth) { } return false; } + +namespace { + +// returns true for `X` in `template void foo()` +bool isTemplateTypeParameterPack(NamedDecl *D) { + if (const auto *TTPD = dyn_cast(D)) { +return TTPD->isParameterPack(); + } + return false; +} + +// Returns the template parameter pack type from an instantiated function +// template, if it exists, nullptr otherwise. +const TemplateTypeParmType *getFunctionPackType(const FunctionDecl *Callee) { + if (const auto *TemplateDecl = Callee->getPrimaryTemplate()) { +auto TemplateParams = TemplateDecl->getTemplateParameters()->asArray(); +// find the template parameter pack from the back +const auto It = std::find_if(TemplateParams.rbegin(), TemplateParams.rend(), + isTemplateTypeParameterPack); +if (It != TemplateParams.rend()) { + const auto *TTPD = dyn_cast(*It); + return TTPD->getTypeForDecl()->castAs(); +} + } + return nullptr; +} + +// Returns the template parameter pack type that this parameter was expanded +// from (if in the Args... or Args&... or Args&&... form), if this is the case, +// nullptr otherwise. +const TemplateTypeParmType *getUnderylingPackType(const ParmVarDecl *Param) { + const auto *PlainType = Param->getType().getTypePtr(); + if (auto *RT = dyn_cast(PlainType)) +PlainType = RT->getPointeeTypeAsWritten().getTypePtr(); + if (const auto *SubstType = dyn_cast(PlainType)) { +const auto *ReplacedParameter = SubstType->getReplacedParameter(); +if (ReplacedParameter->isParameterPack()) { + return dyn_cast( + ReplacedParameter->getCanonicalTypeUnqualified()->getTypePtr()); +} + } + return nullptr; +} + +// This visitor walks over the body of an instantiated function template. +// The template accepts a parameter pack and the visitor records whether +// the pack parameters were forwarded to another call. For example, given: +// +// template +// auto make_unique(Args... args) { +// return unique_ptr(new T(args...)); +// } +// +// When called as `make_unique(2, 'x')` this yields a function +// `make_unique` with two parameters. +// The visitor records that those two parameters are forwarded to the +// `constructor std::string(int, char);`. +// +// This information is recorded in the `ForwardingInfo` split into fully +// resolved parameters (passed as argument to a parameter that is not an +// expanded template type parameter pack) and forwarding parameters (passed to a +// parameter that is an expanded template type par
[clang-tools-extra] e984e1c - [clangd] Don't add inlay hints on std::move/forward
Author: Tobias Ribizel Date: 2022-06-16T12:24:16+02:00 New Revision: e984e1cd6137bb235ca8081b7b35e219c001f86d URL: https://github.com/llvm/llvm-project/commit/e984e1cd6137bb235ca8081b7b35e219c001f86d DIFF: https://github.com/llvm/llvm-project/commit/e984e1cd6137bb235ca8081b7b35e219c001f86d.diff LOG: [clangd] Don't add inlay hints on std::move/forward This removes parameter inlay hints from a few builtin functions like std::move/std::forward Reviewed By: nridge Differential Revision: https://reviews.llvm.org/D127859 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 77dc727bba099..3afadb517cfc2 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/ScopeExit.h" @@ -400,8 +401,9 @@ class InlayHintVisitor : public RecursiveASTVisitor { NameVec ParameterNames = chooseParameterNames(Callee, ArgCount); // Exclude setters (i.e. functions with one argument whose name begins with -// "set"), as their parameter name is also not likely to be interesting. -if (isSetter(Callee, ParameterNames)) +// "set"), and builtins like std::move/forward/... as their parameter name +// is also not likely to be interesting. +if (isSetter(Callee, ParameterNames) || isSimpleBuiltin(Callee)) return; for (size_t I = 0; I < ArgCount; ++I) { @@ -440,6 +442,21 @@ class InlayHintVisitor : public RecursiveASTVisitor { return WhatItIsSetting.equals_insensitive(ParamNames[0]); } + // Checks if the callee is one of the builtins + // addressof, as_const, forward, move(_if_noexcept) + static bool isSimpleBuiltin(const FunctionDecl *Callee) { +switch (Callee->getBuiltinID()) { +case Builtin::BIaddressof: +case Builtin::BIas_const: +case Builtin::BIforward: +case Builtin::BImove: +case Builtin::BImove_if_noexcept: + return true; +default: + return false; +} + } + bool shouldHintName(const Expr *Arg, StringRef ParamName) { if (ParamName.empty()) return false; diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp index 8807cae64ce05..5644ae0d7cc1f 100644 --- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp +++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp @@ -555,6 +555,17 @@ TEST(ParameterHints, SetterFunctions) { ExpectedHint{"timeout_millis: ", "timeout_millis"}); } +TEST(ParameterHints, BuiltinFunctions) { + // This prototype of std::forward is sufficient for clang to recognize it + assertParameterHints(R"cpp( +namespace std { template T&& forward(T&); } +void foo() { + int i; + std::forward(i); +} + )cpp"); +} + TEST(ParameterHints, IncludeAtNonGlobalScope) { Annotations FooInc(R"cpp( void bar() { foo(42); } ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Enable parsing of forwarding functions in the preamble by default (PR #127359)
https://github.com/upsj approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/127359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] Enable parsing of forwarding functions in the preamble by default (PR #127359)
https://github.com/upsj commented: Maybe for consistency we should also change the other defaults that IIRC are used to configure tests: https://github.com/llvm/llvm-project/blob/dbc98cfa46d52ede06e8be7fc5e855d807ba0fac/clang-tools-extra/clangd/ClangdServer.h#L187 https://github.com/llvm/llvm-project/blob/dbc98cfa46d52ede06e8be7fc5e855d807ba0fac/clang-tools-extra/clangd/ClangdServer.h#L504 https://github.com/llvm/llvm-project/pull/127359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits