}
}
+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,
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)
// 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;
// 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();
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) {};
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 {
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
}},
{
R"cpp(// Function definition via using declaration
- namespace ns {
- void foo();
+ namespace ns {
+ void foo();
}
int main() {
using ns::foo;