diff options
Diffstat (limited to 'clangd/ClangdUnit.cpp')
-rw-r--r-- | clangd/ClangdUnit.cpp | 253 |
1 files changed, 0 insertions, 253 deletions
diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 5f45b2f4..f735e09f 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -267,268 +267,15 @@ 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 = Mgr.translateFileLineCol(FE, Pos.line + 1, Pos.character + 1); return Mgr.getMacroArgExpandedLocation(InputLoc); } -/// Finds declarations locations that a given source location refers to. -class DeclarationAndMacrosFinder : public index::IndexDataConsumer { - std::vector<const Decl *> Decls; - std::vector<const MacroInfo *> MacroInfos; - const SourceLocation &SearchedLocation; - const ASTContext &AST; - Preprocessor &PP; - -public: - DeclarationAndMacrosFinder(raw_ostream &OS, - const SourceLocation &SearchedLocation, - ASTContext &AST, Preprocessor &PP) - : SearchedLocation(SearchedLocation), AST(AST), PP(PP) {} - - std::vector<const Decl *> 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<const MacroInfo *> 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<index::SymbolRelation> 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<FileID, unsigned int> 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<const Decl *> &Decls; - std::vector<DocumentHighlight> DocumentHighlights; - const ASTContext &AST; - -public: - DocumentHighlightsFinder(raw_ostream &OS, ASTContext &AST, Preprocessor &PP, - std::vector<const Decl *> &Decls) - : Decls(Decls), AST(AST) {} - std::vector<DocumentHighlight> 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<index::SymbolRelation> 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::SymbolRoleSet>(index::SymbolRole::Write) & Roles) - Kind = DocumentHighlightKind::Write; - else if (static_cast<index::SymbolRoleSet>(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<Location> -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<Location> 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<DeclarationAndMacrosFinder>( - 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<const Decl *> Decls = DeclMacrosFinder->takeDecls(); - std::vector<const MacroInfo *> MacroInfos = - DeclMacrosFinder->takeMacroInfos(); - std::vector<Location> 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<DocumentHighlight> -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<DeclarationAndMacrosFinder>( - 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<const Decl *> SelectedDecls = DeclMacrosFinder->takeDecls(); - - auto DocHighlightsFinder = std::make_shared<DocumentHighlightsFinder>( - llvm::errs(), AST.getASTContext(), AST.getPreprocessor(), SelectedDecls); - - indexTopLevelDecls(AST.getASTContext(), AST.getTopLevelDecls(), - DocHighlightsFinder, IndexOpts); - - return DocHighlightsFinder->takeHighlights(); -} - void ParsedAST::ensurePreambleDeclsDeserialized() { if (PreambleDeclsDeserialized || !Preamble) return; |