[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