kadircet updated this revision to Diff 202888.
kadircet added a comment.
- Address comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D62814/new/
https://reviews.llvm.org/D62814
Files:
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/ScopedPrinter.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include <string>
namespace clang {
namespace clangd {
@@ -765,6 +766,70 @@
{std::string("bool"), std::string("T"), std::string("false")},
};
}},
+ // Pointers to lambdas
+ {R"cpp(
+ void foo() {
+ auto lamb = [](int T, bool B) -> bool { return T && B; };
+ auto *b = &lamb;
+ auto *[[^c]] = &b;
+ }
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.LocalScope = "foo::";
+ HI.Name = "c";
+ HI.Kind = SymbolKind::Variable;
+ HI.Definition = "auto *c = &b";
+ HI.Type = "<lambda> bool(int, bool)";
+ HI.ReturnType = "bool";
+ HI.Parameters = {
+ {std::string("int"), std::string("T"), llvm::None},
+ {std::string("bool"), std::string("B"), llvm::None},
+ };
+ return HI;
+ }},
+ // Lambda parameter with decltype reference
+ {R"cpp(
+ auto lamb = [](int T, bool B) -> bool { return T && B; };
+ void foo(decltype(lamb)& bar) {
+ [[ba^r]](0, false);
+ }
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.LocalScope = "foo::";
+ HI.Name = "bar";
+ HI.Kind = SymbolKind::Variable;
+ HI.Definition = "decltype(lamb) &bar";
+ HI.Type = "<lambda> bool(int, bool)";
+ HI.ReturnType = "bool";
+ HI.Parameters = {
+ {std::string("int"), std::string("T"), llvm::None},
+ {std::string("bool"), std::string("B"), llvm::None},
+ };
+ return HI;
+ }},
+ // Lambda parameter with decltype
+ {R"cpp(
+ auto lamb = [](int T, bool B) -> bool { return T && B; };
+ void foo(decltype(lamb) bar) {
+ [[ba^r]](0, false);
+ }
+ )cpp",
+ [](HoverInfo &HI) {
+ HI.NamespaceScope = "";
+ HI.LocalScope = "foo::";
+ HI.Name = "bar";
+ HI.Kind = SymbolKind::Variable;
+ HI.Definition = "decltype(lamb) bar";
+ HI.Type = "<lambda> bool(int, bool)";
+ HI.ReturnType = "bool";
+ HI.Parameters = {
+ {std::string("int"), std::string("T"), llvm::None},
+ {std::string("bool"), std::string("B"), llvm::None},
+ };
+ return HI;
+ }},
// Lambda variable
{R"cpp(
void foo() {
@@ -779,7 +844,12 @@
HI.Name = "lamb";
HI.Kind = SymbolKind::Variable;
HI.Definition = "auto lamb = [&bar](int T, bool B) -> bool {}";
- HI.Type = std::string("class (lambda)");
+ HI.Type = "<lambda> bool(int, bool)";
+ HI.ReturnType = "bool";
+ HI.Parameters = {
+ {std::string("int"), std::string("T"), llvm::None},
+ {std::string("bool"), std::string("B"), llvm::None},
+ };
return HI;
}},
// Local variable in lambda
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -18,7 +18,9 @@
#include "index/SymbolLocation.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
@@ -619,6 +621,21 @@
CharSourceRange::getCharRange(Loc, End));
}
+static const FunctionDecl *getUnderlyingFunction(const Decl *D) {
+ // Extract lambda from variables.
+ if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D)) {
+ auto QT = VD->getType();
+ while (!QT->getPointeeType().isNull())
+ QT = QT->getPointeeType();
+
+ if (const auto *CD = QT->getAsCXXRecordDecl())
+ return CD->getLambdaCallOperator();
+ }
+
+ // Non-lambda functions.
+ return D->getAsFunction();
+}
+
/// Generate a \p Hover object given the declaration \p D.
static HoverInfo getHoverContents(const Decl *D) {
HoverInfo HI;
@@ -653,13 +670,15 @@
}
// Fill in types and params.
- if (const FunctionDecl *FD = D->getAsFunction()) {
+ if (const FunctionDecl *FD = getUnderlyingFunction(D)) {
HI.ReturnType.emplace();
llvm::raw_string_ostream OS(*HI.ReturnType);
FD->getReturnType().print(OS, Policy);
HI.Type.emplace();
llvm::raw_string_ostream TypeOS(*HI.Type);
+ if (llvm::isa<VarDecl>(D))
+ TypeOS << "<lambda> ";
FD->getReturnType().print(TypeOS, Policy);
TypeOS << '(';
@@ -692,8 +711,6 @@
TypeOS << ')';
// FIXME: handle variadics.
} else if (const auto *VD = dyn_cast<ValueDecl>(D)) {
- // FIXME: Currently lambdas are also handled as ValueDecls, they should be
- // more similar to functions.
HI.Type.emplace();
llvm::raw_string_ostream OS(*HI.Type);
VD->getType().print(OS, Policy);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits