From 553feab6bee651d07d4f707d7b9485f2476c521b Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Tue, 19 Dec 2017 17:06:07 +0000 Subject: [clangd] Split findDefs/highlights into XRefs, from ClangdUnit. NFC Going to add unit tests in the next patch. (Haha!) But seriously there's some work to do first - need to extract the markers-in-source-code parser from CodeComplete test and make it more flexible, to allow annotated ranges etc. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@321087 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 1 + clangd/ClangdServer.cpp | 2 + clangd/ClangdUnit.cpp | 253 --------------------------------------------- clangd/ClangdUnit.h | 7 -- clangd/XRefs.cpp | 270 ++++++++++++++++++++++++++++++++++++++++++++++++ clangd/XRefs.h | 34 ++++++ 6 files changed, 307 insertions(+), 260 deletions(-) create mode 100644 clangd/XRefs.cpp create mode 100644 clangd/XRefs.h diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index 69a0c684..df242da5 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangDaemon ProtocolHandlers.cpp SourceCode.cpp Trace.cpp + XRefs.cpp index/FileIndex.cpp index/Index.cpp index/MemIndex.cpp diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 4a9ee699..129fc074 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -8,7 +8,9 @@ //===-------------------------------------------------------------------===// #include "ClangdServer.h" +#include "CodeComplete.h" #include "SourceCode.h" +#include "XRefs.h" #include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 5f45b2f4..f735e09f 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -266,13 +266,6 @@ ParsedAST::Build(const Context &Ctx, namespace { -SourceLocation getMacroArgExpandedLocation(const SourceManager &Mgr, - const FileEntry *FE, - unsigned Offset) { - SourceLocation FileLoc = Mgr.translateFileLineCol(FE, 1, 1); - return Mgr.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset)); -} - SourceLocation getMacroArgExpandedLocation(const SourceManager &Mgr, const FileEntry *FE, Position Pos) { SourceLocation InputLoc = @@ -280,255 +273,9 @@ SourceLocation getMacroArgExpandedLocation(const SourceManager &Mgr, return Mgr.getMacroArgExpandedLocation(InputLoc); } -/// Finds declarations locations that a given source location refers to. -class DeclarationAndMacrosFinder : public index::IndexDataConsumer { - std::vector Decls; - std::vector MacroInfos; - const SourceLocation &SearchedLocation; - const ASTContext * - Preprocessor &PP; - -public: - DeclarationAndMacrosFinder(raw_ostream &OS, - const SourceLocation &SearchedLocation, - ASTContext &AST, Preprocessor &PP) - : SearchedLocation(SearchedLocation), AST(AST), PP(PP) {} - - std::vector takeDecls() { - // Don't keep the same declaration multiple times. - // This can happen when nodes in the AST are visited twice. - std::sort(Decls.begin(), Decls.end()); - auto Last = std::unique(Decls.begin(), Decls.end()); - Decls.erase(Last, Decls.end()); - return std::move(Decls); - } - - std::vector takeMacroInfos() { - // Don't keep the same Macro info multiple times. - std::sort(MacroInfos.begin(), MacroInfos.end()); - auto Last = std::unique(MacroInfos.begin(), MacroInfos.end()); - MacroInfos.erase(Last, MacroInfos.end()); - return std::move(MacroInfos); - } - - bool - handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, - ArrayRef Relations, FileID FID, - unsigned Offset, - index::IndexDataConsumer::ASTNodeInfo ASTNode) override { - if (isSearchedLocation(FID, Offset)) - Decls.push_back(D); - return true; - } - -private: - bool isSearchedLocation(FileID FID, unsigned Offset) const { - const SourceManager &SourceMgr = AST.getSourceManager(); - return SourceMgr.getFileOffset(SearchedLocation) == Offset && - SourceMgr.getFileID(SearchedLocation) == FID; - } - - void finish() override { - // Also handle possible macro at the searched location. - Token Result; - if (!Lexer::getRawToken(SearchedLocation, Result, AST.getSourceManager(), - AST.getLangOpts(), false)) { - if (Result.is(tok::raw_identifier)) { - PP.LookUpIdentifierInfo(Result); - } - IdentifierInfo *IdentifierInfo = Result.getIdentifierInfo(); - if (IdentifierInfo && IdentifierInfo->hadMacroDefinition()) { - std::pair DecLoc = - AST.getSourceManager().getDecomposedExpansionLoc(SearchedLocation); - // Get the definition just before the searched location so that a macro - // referenced in a '#undef MACRO' can still be found. - SourceLocation BeforeSearchedLocation = getMacroArgExpandedLocation( - AST.getSourceManager(), - AST.getSourceManager().getFileEntryForID(DecLoc.first), - DecLoc.second - 1); - MacroDefinition MacroDef = - PP.getMacroDefinitionAtLoc(IdentifierInfo, BeforeSearchedLocation); - MacroInfo *MacroInf = MacroDef.getMacroInfo(); - if (MacroInf) { - MacroInfos.push_back(MacroInf); - } - } - } - } -}; - -/// Finds document highlights that a given list of declarations refers to. -class DocumentHighlightsFinder : public index::IndexDataConsumer { - std::vector &Decls; - std::vector DocumentHighlights; - const ASTContext * - -public: - DocumentHighlightsFinder(raw_ostream &OS, ASTContext &AST, Preprocessor &PP, - std::vector &Decls) - : Decls(Decls), AST(AST) {} - std::vector takeHighlights() { - // Don't keep the same highlight multiple times. - // This can happen when nodes in the AST are visited twice. - std::sort(DocumentHighlights.begin(), DocumentHighlights.end()); - auto Last = - std::unique(DocumentHighlights.begin(), DocumentHighlights.end()); - DocumentHighlights.erase(Last, DocumentHighlights.end()); - return std::move(DocumentHighlights); - } - - bool - handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, - ArrayRef Relations, FileID FID, - unsigned Offset, - index::IndexDataConsumer::ASTNodeInfo ASTNode) override { - const SourceManager &SourceMgr = AST.getSourceManager(); - if (SourceMgr.getMainFileID() != FID || - std::find(Decls.begin(), Decls.end(), D) == Decls.end()) { - return true; - } - SourceLocation End; - const LangOptions &LangOpts = AST.getLangOpts(); - SourceLocation StartOfFileLoc = SourceMgr.getLocForStartOfFile(FID); - SourceLocation HightlightStartLoc = StartOfFileLoc.getLocWithOffset(Offset); - End = - Lexer::getLocForEndOfToken(HightlightStartLoc, 0, SourceMgr, LangOpts); - SourceRange SR(HightlightStartLoc, End); - - DocumentHighlightKind Kind = DocumentHighlightKind::Text; - if (static_cast(index::SymbolRole::Write) & Roles) - Kind = DocumentHighlightKind::Write; - else if (static_cast(index::SymbolRole::Read) & Roles) - Kind = DocumentHighlightKind::Read; - - DocumentHighlights.push_back(getDocumentHighlight(SR, Kind)); - return true; - } - -private: - DocumentHighlight getDocumentHighlight(SourceRange SR, - DocumentHighlightKind Kind) { - const SourceManager &SourceMgr = AST.getSourceManager(); - SourceLocation LocStart = SR.getBegin(); - Position Begin; - Begin.line = SourceMgr.getSpellingLineNumber(LocStart) - 1; - Begin.character = SourceMgr.getSpellingColumnNumber(LocStart) - 1; - Position End; - End.line = SourceMgr.getSpellingLineNumber(SR.getEnd()) - 1; - End.character = SourceMgr.getSpellingColumnNumber(SR.getEnd()) - 1; - Range R = {Begin, End}; - DocumentHighlight DH; - DH.range = R; - DH.kind = Kind; - return DH; - } -}; } // namespace -llvm::Optional -getDeclarationLocation(ParsedAST &AST, const SourceRange &ValSourceRange) { - const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); - const LangOptions &LangOpts = AST.getASTContext().getLangOpts(); - SourceLocation LocStart = ValSourceRange.getBegin(); - - const FileEntry *F = - SourceMgr.getFileEntryForID(SourceMgr.getFileID(LocStart)); - if (!F) - return llvm::None; - SourceLocation LocEnd = Lexer::getLocForEndOfToken(ValSourceRange.getEnd(), 0, - SourceMgr, LangOpts); - Position Begin; - Begin.line = SourceMgr.getSpellingLineNumber(LocStart) - 1; - Begin.character = SourceMgr.getSpellingColumnNumber(LocStart) - 1; - Position End; - End.line = SourceMgr.getSpellingLineNumber(LocEnd) - 1; - End.character = SourceMgr.getSpellingColumnNumber(LocEnd) - 1; - Range R = {Begin, End}; - Location L; - - StringRef FilePath = F->tryGetRealPathName(); - if (FilePath.empty()) - FilePath = F->getName(); - L.uri = URI::fromFile(FilePath); - L.range = R; - return L; -} - -std::vector clangd::findDefinitions(const Context &Ctx, - ParsedAST &AST, Position Pos) { - const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); - const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - if (!FE) - return {}; - - SourceLocation SourceLocationBeg = getBeginningOfIdentifier(AST, Pos, FE); - - auto DeclMacrosFinder = std::make_shared( - llvm::errs(), SourceLocationBeg, AST.getASTContext(), - AST.getPreprocessor()); - index::IndexingOptions IndexOpts; - IndexOpts.SystemSymbolFilter = - index::IndexingOptions::SystemSymbolFilterKind::All; - IndexOpts.IndexFunctionLocals = true; - - indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), - DeclMacrosFinder, IndexOpts); - - std::vector Decls = DeclMacrosFinder->takeDecls(); - std::vector MacroInfos = - DeclMacrosFinder->takeMacroInfos(); - std::vector Result; - - for (auto Item : Decls) { - auto L = getDeclarationLocation(AST, Item->getSourceRange()); - if (L) - Result.push_back(*L); - } - - for (auto Item : MacroInfos) { - SourceRange SR(Item->getDefinitionLoc(), Item->getDefinitionEndLoc()); - auto L = getDeclarationLocation(AST, SR); - if (L) - Result.push_back(*L); - } - - return Result; -} - -std::vector -clangd::findDocumentHighlights(const Context &Ctx, ParsedAST &AST, - Position Pos) { - const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); - const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); - if (!FE) - return {}; - - SourceLocation SourceLocationBeg = getBeginningOfIdentifier(AST, Pos, FE); - - auto DeclMacrosFinder = std::make_shared( - llvm::errs(), SourceLocationBeg, AST.getASTContext(), - AST.getPreprocessor()); - index::IndexingOptions IndexOpts; - IndexOpts.SystemSymbolFilter = - index::IndexingOptions::SystemSymbolFilterKind::All; - IndexOpts.IndexFunctionLocals = true; - - // Macro occurences are not currently handled. - indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), - DeclMacrosFinder, IndexOpts); - - std::vector SelectedDecls = DeclMacrosFinder->takeDecls(); - - auto DocHighlightsFinder = std::make_shared( - llvm::errs(), AST.getASTContext(), AST.getPreprocessor(), SelectedDecls); - - indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), - DocHighlightsFinder, IndexOpts); - - return DocHighlightsFinder->takeHighlights(); -} - void ParsedAST::ensurePreambleDeclsDeserialized() { if (PreambleDeclsDeserialized || !Preamble) return; diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index a8110de4..47902c54 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -258,13 +258,6 @@ private: SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, const FileEntry *FE); -/// Get definition of symbol at a specified \p Pos. -std::vector findDefinitions(const Context &Ctx, ParsedAST &AST, - Position Pos); - -std::vector -findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos); - /// For testing/debugging purposes. Note that this method deserializes all /// unserialized Decls, so use with care. void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS); diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp new file mode 100644 index 00000000..9bd4131b --- /dev/null +++ b/clangd/XRefs.cpp @@ -0,0 +1,270 @@ +//===--- XRefs.cpp ----------------------------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +#include "XRefs.h" +#include "clang/Index/IndexDataConsumer.h" +#include "clang/Index/IndexingAction.h" +namespace clang { +namespace clangd { +using namespace llvm; +namespace { + +/// Finds declarations locations that a given source location refers to. +class DeclarationAndMacrosFinder : public index::IndexDataConsumer { + std::vector Decls; + std::vector MacroInfos; + const SourceLocation &SearchedLocation; + const ASTContext * + Preprocessor &PP; + +public: + DeclarationAndMacrosFinder(raw_ostream &OS, + const SourceLocation &SearchedLocation, + ASTContext &AST, Preprocessor &PP) + : SearchedLocation(SearchedLocation), AST(AST), PP(PP) {} + + std::vector takeDecls() { + // Don't keep the same declaration multiple times. + // This can happen when nodes in the AST are visited twice. + std::sort(Decls.begin(), Decls.end()); + auto Last = std::unique(Decls.begin(), Decls.end()); + Decls.erase(Last, Decls.end()); + return std::move(Decls); + } + + std::vector takeMacroInfos() { + // Don't keep the same Macro info multiple times. + std::sort(MacroInfos.begin(), MacroInfos.end()); + auto Last = std::unique(MacroInfos.begin(), MacroInfos.end()); + MacroInfos.erase(Last, MacroInfos.end()); + return std::move(MacroInfos); + } + + bool + handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, + ArrayRef Relations, FileID FID, + unsigned Offset, + index::IndexDataConsumer::ASTNodeInfo ASTNode) override { + if (isSearchedLocation(FID, Offset)) + Decls.push_back(D); + return true; + } + +private: + bool isSearchedLocation(FileID FID, unsigned Offset) const { + const SourceManager &SourceMgr = AST.getSourceManager(); + return SourceMgr.getFileOffset(SearchedLocation) == Offset && + SourceMgr.getFileID(SearchedLocation) == FID; + } + + void finish() override { + // Also handle possible macro at the searched location. + Token Result; + auto &Mgr = AST.getSourceManager(); + if (!Lexer::getRawToken(SearchedLocation, Result, Mgr, AST.getLangOpts(), + false)) { + if (Result.is(tok::raw_identifier)) { + PP.LookUpIdentifierInfo(Result); + } + IdentifierInfo *IdentifierInfo = Result.getIdentifierInfo(); + if (IdentifierInfo && IdentifierInfo->hadMacroDefinition()) { + std::pair DecLoc = + Mgr.getDecomposedExpansionLoc(SearchedLocation); + // Get the definition just before the searched location so that a macro + // referenced in a '#undef MACRO' can still be found. + SourceLocation BeforeSearchedLocation = Mgr.getMacroArgExpandedLocation( + Mgr.getLocForStartOfFile(DecLoc.first) + .getLocWithOffset(DecLoc.second - 1)); + MacroDefinition MacroDef = + PP.getMacroDefinitionAtLoc(IdentifierInfo, BeforeSearchedLocation); + MacroInfo *MacroInf = MacroDef.getMacroInfo(); + if (MacroInf) { + MacroInfos.push_back(MacroInf); + } + } + } + } +}; + +llvm::Optional +getDeclarationLocation(ParsedAST &AST, const SourceRange &ValSourceRange) { + const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); + const LangOptions &LangOpts = AST.getASTContext().getLangOpts(); + SourceLocation LocStart = ValSourceRange.getBegin(); + + const FileEntry *F = + SourceMgr.getFileEntryForID(SourceMgr.getFileID(LocStart)); + if (!F) + return llvm::None; + SourceLocation LocEnd = Lexer::getLocForEndOfToken(ValSourceRange.getEnd(), 0, + SourceMgr, LangOpts); + Position Begin; + Begin.line = SourceMgr.getSpellingLineNumber(LocStart) - 1; + Begin.character = SourceMgr.getSpellingColumnNumber(LocStart) - 1; + Position End; + End.line = SourceMgr.getSpellingLineNumber(LocEnd) - 1; + End.character = SourceMgr.getSpellingColumnNumber(LocEnd) - 1; + Range R = {Begin, End}; + Location L; + + StringRef FilePath = F->tryGetRealPathName(); + if (FilePath.empty()) + FilePath = F->getName(); + L.uri = URI::fromFile(FilePath); + L.range = R; + return L; +} + +} // namespace + +std::vector findDefinitions(const Context &Ctx, ParsedAST &AST, + Position Pos) { + const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); + const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); + if (!FE) + return {}; + + SourceLocation SourceLocationBeg = getBeginningOfIdentifier(AST, Pos, FE); + + auto DeclMacrosFinder = std::make_shared( + llvm::errs(), SourceLocationBeg, AST.getASTContext(), + AST.getPreprocessor()); + index::IndexingOptions IndexOpts; + IndexOpts.SystemSymbolFilter = + index::IndexingOptions::SystemSymbolFilterKind::All; + IndexOpts.IndexFunctionLocals = true; + + indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), + DeclMacrosFinder, IndexOpts); + + std::vector Decls = DeclMacrosFinder->takeDecls(); + std::vector MacroInfos = + DeclMacrosFinder->takeMacroInfos(); + std::vector Result; + + for (auto Item : Decls) { + auto L = getDeclarationLocation(AST, Item->getSourceRange()); + if (L) + Result.push_back(*L); + } + + for (auto Item : MacroInfos) { + SourceRange SR(Item->getDefinitionLoc(), Item->getDefinitionEndLoc()); + auto L = getDeclarationLocation(AST, SR); + if (L) + Result.push_back(*L); + } + + return Result; +} + +namespace { + +/// Finds document highlights that a given list of declarations refers to. +class DocumentHighlightsFinder : public index::IndexDataConsumer { + std::vector &Decls; + std::vector DocumentHighlights; + const ASTContext * + +public: + DocumentHighlightsFinder(raw_ostream &OS, ASTContext &AST, Preprocessor &PP, + std::vector &Decls) + : Decls(Decls), AST(AST) {} + std::vector takeHighlights() { + // Don't keep the same highlight multiple times. + // This can happen when nodes in the AST are visited twice. + std::sort(DocumentHighlights.begin(), DocumentHighlights.end()); + auto Last = + std::unique(DocumentHighlights.begin(), DocumentHighlights.end()); + DocumentHighlights.erase(Last, DocumentHighlights.end()); + return std::move(DocumentHighlights); + } + + bool + handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, + ArrayRef Relations, FileID FID, + unsigned Offset, + index::IndexDataConsumer::ASTNodeInfo ASTNode) override { + const SourceManager &SourceMgr = AST.getSourceManager(); + if (SourceMgr.getMainFileID() != FID || + std::find(Decls.begin(), Decls.end(), D) == Decls.end()) { + return true; + } + SourceLocation End; + const LangOptions &LangOpts = AST.getLangOpts(); + SourceLocation StartOfFileLoc = SourceMgr.getLocForStartOfFile(FID); + SourceLocation HightlightStartLoc = StartOfFileLoc.getLocWithOffset(Offset); + End = + Lexer::getLocForEndOfToken(HightlightStartLoc, 0, SourceMgr, LangOpts); + SourceRange SR(HightlightStartLoc, End); + + DocumentHighlightKind Kind = DocumentHighlightKind::Text; + if (static_cast(index::SymbolRole::Write) & Roles) + Kind = DocumentHighlightKind::Write; + else if (static_cast(index::SymbolRole::Read) & Roles) + Kind = DocumentHighlightKind::Read; + + DocumentHighlights.push_back(getDocumentHighlight(SR, Kind)); + return true; + } + +private: + DocumentHighlight getDocumentHighlight(SourceRange SR, + DocumentHighlightKind Kind) { + const SourceManager &SourceMgr = AST.getSourceManager(); + SourceLocation LocStart = SR.getBegin(); + Position Begin; + Begin.line = SourceMgr.getSpellingLineNumber(LocStart) - 1; + Begin.character = SourceMgr.getSpellingColumnNumber(LocStart) - 1; + Position End; + End.line = SourceMgr.getSpellingLineNumber(SR.getEnd()) - 1; + End.character = SourceMgr.getSpellingColumnNumber(SR.getEnd()) - 1; + Range R = {Begin, End}; + DocumentHighlight DH; + DH.range = R; + DH.kind = Kind; + return DH; + } +}; + +} // namespace + +std::vector +findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos) { + const SourceManager &SourceMgr = AST.getASTContext().getSourceManager(); + const FileEntry *FE = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()); + if (!FE) + return {}; + + SourceLocation SourceLocationBeg = getBeginningOfIdentifier(AST, Pos, FE); + + auto DeclMacrosFinder = std::make_shared( + llvm::errs(), SourceLocationBeg, AST.getASTContext(), + AST.getPreprocessor()); + index::IndexingOptions IndexOpts; + IndexOpts.SystemSymbolFilter = + index::IndexingOptions::SystemSymbolFilterKind::All; + IndexOpts.IndexFunctionLocals = true; + + // Macro occurences are not currently handled. + indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), + DeclMacrosFinder, IndexOpts); + + std::vector SelectedDecls = DeclMacrosFinder->takeDecls(); + + auto DocHighlightsFinder = std::make_shared( + llvm::errs(), AST.getASTContext(), AST.getPreprocessor(), SelectedDecls); + + indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), + DocHighlightsFinder, IndexOpts); + + return DocHighlightsFinder->takeHighlights(); +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/XRefs.h b/clangd/XRefs.h new file mode 100644 index 00000000..04518a19 --- /dev/null +++ b/clangd/XRefs.h @@ -0,0 +1,34 @@ +//===--- XRefs.h ------------------------------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// Features that traverse references between symbols. +// +//===---------------------------------------------------------------------===// +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H + +#include "ClangdUnit.h" +#include "Context.h" +#include "Protocol.h" +#include + +namespace clang { +namespace clangd { + +/// Get definition of symbol at a specified \p Pos. +std::vector findDefinitions(const Context &Ctx, ParsedAST &AST, + Position Pos); + +/// Returns highlights for all usages of a symbol at \p Pos. +std::vector +findDocumentHighlights(const Context &Ctx, ParsedAST &AST, Position Pos); + +} // namespace clangd +} // namespace clang +#endif -- cgit v1.2.3