[clang-tools-extra] a638648 - [clangd] add inlay hints for std::forward-ed parameter packs

2022-07-06 Thread Tobias Ribizel via cfe-commits

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

2022-06-16 Thread Tobias Ribizel via cfe-commits

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)

2025-02-16 Thread Tobias Ribizel via cfe-commits

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)

2025-02-16 Thread Tobias Ribizel via cfe-commits

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