[clang-tools-extra] b252824 - [clangd] fix wrong CalleeArgInfo in the hover
via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 10 06:17:27 PST 2023
Author: v1nh1shungry
Date: 2023-02-10T22:16:16+08:00
New Revision: b252824e6e6ee0959051841e583860ba7ed1cd67
URL: https://github.com/llvm/llvm-project/commit/b252824e6e6ee0959051841e583860ba7ed1cd67
DIFF: https://github.com/llvm/llvm-project/commit/b252824e6e6ee0959051841e583860ba7ed1cd67.diff
LOG: [clangd] fix wrong CalleeArgInfo in the hover
```
void foobar(int);
int main() {
foobar(1 + 2);
^
}
```
Currently the CalleeArgInfo will be "Passed by reference", which should
be "Passed by value".
Fixes https://github.com/clangd/clangd/issues/1467
Differential Revision: https://reviews.llvm.org/D142014
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 8649ddc9479ed..1a51614bb9d45 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -952,6 +952,15 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
}
}
+HoverInfo::PassType::PassMode getPassMode(QualType ParmType) {
+ if (ParmType->isReferenceType()) {
+ if (ParmType->getPointeeType().isConstQualified())
+ return HoverInfo::PassType::ConstRef;
+ return HoverInfo::PassType::Ref;
+ }
+ return HoverInfo::PassType::Value;
+}
+
// If N is passed as argument to a function, fill HI.CalleeArgInfo with
// information about that argument.
void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
@@ -972,14 +981,19 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
if (!FD || FD->isOverloadedOperator() || FD->isVariadic())
return;
+ HoverInfo::PassType PassType;
+
// Find argument index for N.
for (unsigned I = 0; I < CE->getNumArgs() && I < FD->getNumParams(); ++I) {
if (CE->getArg(I) != OuterNode.ASTNode.get<Expr>())
continue;
// Extract matching argument from function declaration.
- if (const ParmVarDecl *PVD = FD->getParamDecl(I))
+ if (const ParmVarDecl *PVD = FD->getParamDecl(I)) {
HI.CalleeArgInfo.emplace(toHoverInfoParam(PVD, PP));
+ if (N == &OuterNode)
+ PassType.PassBy = getPassMode(PVD->getType());
+ }
break;
}
if (!HI.CalleeArgInfo)
@@ -988,14 +1002,9 @@ void maybeAddCalleeArgInfo(const SelectionTree::Node *N, HoverInfo &HI,
// If we found a matching argument, also figure out if it's a
// [const-]reference. For this we need to walk up the AST from the arg itself
// to CallExpr and check all implicit casts, constructor calls, etc.
- HoverInfo::PassType PassType;
if (const auto *E = N->ASTNode.get<Expr>()) {
if (E->getType().isConstQualified())
PassType.PassBy = HoverInfo::PassType::ConstRef;
-
- // No implicit node, literal passed by value
- if (isLiteral(E) && N->Parent == OuterNode.Parent)
- PassType.PassBy = HoverInfo::PassType::Value;
}
for (auto *CastNode = N->Parent;
@@ -1067,9 +1076,8 @@ const NamedDecl *pickDeclToUse(llvm::ArrayRef<const NamedDecl *> Candidates) {
// template <typename T> void bar() { fo^o(T{}); }
// we actually want to show the using declaration,
// it's not clear which declaration to pick otherwise.
- auto BaseDecls = llvm::make_filter_range(Candidates, [](const NamedDecl *D) {
- return llvm::isa<UsingDecl>(D);
- });
+ auto BaseDecls = llvm::make_filter_range(
+ Candidates, [](const NamedDecl *D) { return llvm::isa<UsingDecl>(D); });
if (std::distance(BaseDecls.begin(), BaseDecls.end()) == 1)
return *BaseDecls.begin();
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 7fbb8858c3f45..211fd1311c98f 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -900,6 +900,27 @@ class Foo final {})cpp";
HI.CalleeArgInfo->Type = "int &";
HI.CallPassType = HoverInfo::PassType{PassMode::Ref, false};
}},
+ {
+ R"cpp(
+ void foobar(const float &arg);
+ int main() {
+ int a = 0;
+ foobar([[^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) {};
@@ -934,6 +955,38 @@ class Foo final {})cpp";
HI.CalleeArgInfo->Type = "const int &";
HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, false};
}},
+ {
+ R"cpp(
+ int add(int lhs, int rhs);
+ int main() {
+ add(1 [[^+]] 2, 3);
+ }
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "expression";
+ HI.Kind = index::SymbolKind::Unknown;
+ HI.Type = "int";
+ HI.Value = "3";
+ HI.CalleeArgInfo.emplace();
+ HI.CalleeArgInfo->Name = "lhs";
+ HI.CalleeArgInfo->Type = "int";
+ HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
+ }},
+ {
+ R"cpp(
+ void foobar(const float &arg);
+ int main() {
+ foobar([[^0]]);
+ }
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "literal";
+ HI.Kind = index::SymbolKind::Unknown;
+ HI.CalleeArgInfo.emplace();
+ HI.CalleeArgInfo->Name = "arg";
+ HI.CalleeArgInfo->Type = "const float &";
+ HI.CallPassType = HoverInfo::PassType{PassMode::Value, true};
+ }},
{// Extra info for method call.
R"cpp(
class C {
@@ -960,6 +1013,29 @@ class Foo final {})cpp";
HI.CalleeArgInfo->Default = "3";
HI.CallPassType = HoverInfo::PassType{PassMode::Value, false};
}},
+ {
+ R"cpp(
+ struct Foo {
+ Foo(const int &);
+ };
+ void foo(Foo);
+ void bar() {
+ const int x = 0;
+ foo([[^x]]);
+ }
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.Name = "x";
+ HI.Kind = index::SymbolKind::Variable;
+ HI.NamespaceScope = "";
+ HI.Definition = "const int x = 0";
+ HI.LocalScope = "bar::";
+ HI.Value = "0";
+ HI.Type = "const int";
+ HI.CalleeArgInfo.emplace();
+ HI.CalleeArgInfo->Type = "Foo";
+ HI.CallPassType = HoverInfo::PassType{PassMode::ConstRef, true};
+ }},
{// Dont crash on invalid decl
R"cpp(
// error-ok
@@ -1673,8 +1749,8 @@ TEST(Hover, All) {
}},
{
R"cpp(// Function definition via using declaration
- namespace ns {
- void foo();
+ namespace ns {
+ void foo();
}
int main() {
using ns::foo;
More information about the cfe-commits
mailing list