kadircet updated this revision to Diff 202933. kadircet marked an inline comment as done. 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 @@ -19,7 +19,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" @@ -620,6 +622,23 @@ 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(); + if (!QT.isNull()) { + 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; @@ -654,13 +673,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 << '('; @@ -693,8 +714,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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits