[clang-tools-extra] cb133a4 - [clangd] Hover: Add CalleeArgInfo for constructor expressions

Tom Praschan via cfe-commits cfe-commits at lists.llvm.org
Sat Apr 29 03:37:23 PDT 2023


Author: Tom Praschan
Date: 2023-04-29T14:37:16+02:00
New Revision: cb133a4629a56f8c8a67fb7549356839917b52f9

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

LOG: [clangd] Hover: Add CalleeArgInfo for constructor expressions

Differential Revision: https://reviews.llvm.org/D147847

Added: 
    

Modified: 
    clang-tools-extra/clangd/Hover.cpp
    clang-tools-extra/clangd/unittests/HoverTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index f59642dbf721d..558769f209860 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -981,12 +981,23 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
   const auto &OuterNode = N->outerImplicit();
   if (!OuterNode.Parent)
     return;
-  const auto *CE = OuterNode.Parent->ASTNode.get<CallExpr>();
-  if (!CE)
+
+  const FunctionDecl *FD = nullptr;
+  llvm::ArrayRef<const Expr *> Args;
+
+  if (const auto *CE = OuterNode.Parent->ASTNode.get<CallExpr>()) {
+    FD = CE->getDirectCallee();
+    Args = {CE->getArgs(), CE->getNumArgs()};
+  } else if (const auto *CE =
+                 OuterNode.Parent->ASTNode.get<CXXConstructExpr>()) {
+    FD = CE->getConstructor();
+    Args = {CE->getArgs(), CE->getNumArgs()};
+  }
+  if (!FD)
     return;
-  const FunctionDecl *FD = CE->getDirectCallee();
-  // For non-function-call-like operatators (e.g. operator+, operator<<) it's
-  // not immediattely obvious what the "passed as" would refer to and, given
+
+  // For non-function-call-like operators (e.g. operator+, operator<<) it's
+  // not immediately obvious what the "passed as" would refer to and, given
   // fixed function signature, the value would be very low anyway, so we choose
   // to not support that.
   // Both variadic functions and operator() (especially relevant for lambdas)
@@ -999,8 +1010,8 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
   auto Parameters = resolveForwardingParameters(FD);
 
   // Find argument index for N.
-  for (unsigned I = 0; I < CE->getNumArgs() && I < Parameters.size(); ++I) {
-    if (CE->getArg(I) != OuterNode.ASTNode.get<Expr>())
+  for (unsigned I = 0; I < Args.size() && I < Parameters.size(); ++I) {
+    if (Args[I] != OuterNode.ASTNode.get<Expr>())
       continue;
 
     // Extract matching argument from function declaration.

diff  --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 5bf089fbbfeca..ce546f54dd75f 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -956,6 +956,29 @@ class Foo final {})cpp";
             HI.CalleeArgInfo->Type = "const float &";
             HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
           }},
+      {
+          R"cpp(
+          struct Foo {
+            explicit Foo(const float& arg) {}
+          };
+          int main() {
+            int a = 0;
+            Foo foo([[^a]]);
+          }
+          )cpp",
+          [](HoverInfo &HI) {
+            HI.Name = "a";
+            HI.Kind = index::SymbolKind::Variable;
+            HI.NamespaceScope = "";
+            HI.Definition = "int a = 0";
+            HI.LocalScope = "main::";
+            HI.Value = "0";
+            HI.Type = "int";
+            HI.CalleeArgInfo.emplace();
+            HI.CalleeArgInfo->Name = "arg";
+            HI.CalleeArgInfo->Type = "const float &";
+            HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
+          }},
       {// Literal passed to function call
        R"cpp(
           void fun(int arg_a, const int &arg_b) {};
@@ -1342,6 +1365,7 @@ class CustomClass {
   CustomClass(const Base &x) {}
   CustomClass(int &x) {}
   CustomClass(float x) {}
+  CustomClass(int x, int y) {}
 };
 
 void int_by_ref(int &x) {}
@@ -1388,6 +1412,11 @@ void fun() {
       {"base_by_ref([[^derived]]);", PassMode::Ref, false},
       {"base_by_const_ref([[^derived]]);", PassMode::ConstRef, false},
       {"base_by_value([[^derived]]);", PassMode::Value, false},
+      // Custom class constructor tests
+      {"CustomClass c1([[^base]]);", PassMode::ConstRef, false},
+      {"auto c2 = new CustomClass([[^base]]);", PassMode::ConstRef, false},
+      {"CustomClass c3([[^int_x]]);", PassMode::Ref, false},
+      {"CustomClass c3(int_x, [[^int_x]]);", PassMode::Value, false},
       // Converted tests
       {"float_by_value([[^int_x]]);", PassMode::Value, true},
       {"float_by_value([[^int_ref]]);", PassMode::Value, true},


        


More information about the cfe-commits mailing list