diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp --- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp +++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "index/Index.h" +#include "index/Relation.h" #include "index/Serialization.h" #include "index/dex/Dex.h" #include "index/remote/Client.h" @@ -267,6 +269,43 @@ } }; +class Relations : public Command { + llvm::cl::opt ID{ + "id", + llvm::cl::Positional, + llvm::cl::desc("Symbol ID of the symbol being queried (hex)."), + }; + llvm::cl::opt Relation{ + "relation", + llvm::cl::desc("Relation kind for the predicate."), + values(clEnumValN(RelationKind::BaseOf, "base_of", + "Find subclasses of a class."), + clEnumValN(RelationKind::OverriddenBy, "overridden_by", + "Find methods that overrides a virtual method.")), + }; + + void run() override { + if (ID.getNumOccurrences() == 0 || Relation.getNumOccurrences() == 0) { + llvm::errs() + << "Missing required argument: please provide id and -relation.\n"; + return; + } + RelationsRequest Req; + if (ID.getNumOccurrences()) { + auto SID = SymbolID::fromStr(ID); + if (!SID) { + llvm::errs() << llvm::toString(SID.takeError()) << "\n"; + return; + } + Req.Subjects.insert(*SID); + } + Req.Predicate = Relation.getValue(); + Index->relations(Req, [](const SymbolID &SID, const Symbol &S) { + llvm::outs() << S << " defined at: " << S.Definition << "\n"; + }); + } +}; + class Export : public Command { llvm::cl::opt Format{ "format", @@ -326,6 +365,8 @@ {"lookup", "Dump symbol details by ID or qualified name", std::make_unique}, {"refs", "Find references by ID or qualified name", std::make_unique}, + {"relations", "Find relations by ID and relation kind", + std::make_unique}, {"export", "Export index", std::make_unique}, };