1 //===--- XRefs.h -------------------------------------------------*- C++-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Features that traverse references between symbols. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H 14 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H 15 16 #include "Protocol.h" 17 #include "SourceCode.h" 18 #include "index/Index.h" 19 #include "index/SymbolID.h" 20 #include "index/SymbolLocation.h" 21 #include "support/Path.h" 22 #include "clang/AST/ASTTypeTraits.h" 23 #include "clang/AST/Type.h" 24 #include "clang/Format/Format.h" 25 #include "clang/Index/IndexSymbol.h" 26 #include "llvm/ADT/Optional.h" 27 #include "llvm/Support/raw_ostream.h" 28 #include <vector> 29 30 namespace clang { 31 namespace syntax { 32 class Token; 33 class TokenBuffer; 34 } // namespace syntax 35 namespace clangd { 36 class ParsedAST; 37 38 // Describes where a symbol is declared and defined (as far as clangd knows). 39 // There are three cases: 40 // - a declaration only, no definition is known (e.g. only header seen) 41 // - a declaration and a distinct definition (e.g. function declared in header) 42 // - a declaration and an equal definition (e.g. inline function, or class) 43 // For some types of symbol, e.g. macros, definition == declaration always. 44 struct LocatedSymbol { 45 // The (unqualified) name of the symbol. 46 std::string Name; 47 // The canonical or best declaration: where most users find its interface. 48 Location PreferredDeclaration; 49 // Where the symbol is defined, if known. May equal PreferredDeclaration. 50 llvm::Optional<Location> Definition; 51 // SymbolID of the located symbol if available. 52 SymbolID ID; 53 }; 54 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const LocatedSymbol &); 55 /// Get definition of symbol at a specified \p Pos. 56 /// Multiple locations may be returned, corresponding to distinct symbols. 57 std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos, 58 const SymbolIndex *Index = nullptr); 59 60 // Tries to provide a textual fallback for locating a symbol by looking up the 61 // word under the cursor as a symbol name in the index. 62 // The aim is to pick up references to symbols in contexts where 63 // AST-based resolution does not work, such as comments, strings, and PP 64 // disabled regions. 65 // (This is for internal use by locateSymbolAt, and is exposed for testing). 66 std::vector<LocatedSymbol> 67 locateSymbolTextually(const SpelledWord &Word, ParsedAST &AST, 68 const SymbolIndex *Index, const std::string &MainFilePath, 69 ASTNodeKind NodeKind); 70 71 // Try to find a proximate occurrence of `Word` as an identifier, which can be 72 // used to resolve it. 73 // (This is for internal use by locateSymbolAt, and is exposed for testing). 74 const syntax::Token *findNearbyIdentifier(const SpelledWord &Word, 75 const syntax::TokenBuffer &TB); 76 77 /// Get all document links 78 std::vector<DocumentLink> getDocumentLinks(ParsedAST &AST); 79 80 /// Returns highlights for all usages of a symbol at \p Pos. 81 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST, 82 Position Pos); 83 84 struct ReferencesResult { 85 // Bitmask describing whether the occurrence is a declaration, definition etc. 86 enum ReferenceAttributes : unsigned { 87 Declaration = 1 << 0, 88 Definition = 1 << 1, 89 // The occurrence is an override of the target base method. 90 Override = 1 << 2, 91 }; 92 struct Reference { 93 Location Loc; 94 unsigned Attributes = 0; 95 }; 96 std::vector<Reference> References; 97 bool HasMore = false; 98 }; 99 llvm::raw_ostream &operator<<(llvm::raw_ostream &, 100 const ReferencesResult::Reference &); 101 102 /// Returns implementations at a specified \p Pos: 103 /// - overrides for a virtual method; 104 /// - subclasses for a base class; 105 std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos, 106 const SymbolIndex *Index); 107 108 /// Returns references of the symbol at a specified \p Pos. 109 /// \p Limit limits the number of results returned (0 means no limit). 110 ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit, 111 const SymbolIndex *Index = nullptr); 112 113 /// Get info about symbols at \p Pos. 114 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos); 115 116 /// Find the record type references at \p Pos. 117 const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos); 118 119 /// Given a record type declaration, find its base (parent) types. 120 std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD); 121 122 /// Get type hierarchy information at \p Pos. 123 llvm::Optional<TypeHierarchyItem> getTypeHierarchy( 124 ParsedAST &AST, Position Pos, int Resolve, TypeHierarchyDirection Direction, 125 const SymbolIndex *Index = nullptr, PathRef TUPath = PathRef{}); 126 127 void resolveTypeHierarchy(TypeHierarchyItem &Item, int ResolveLevels, 128 TypeHierarchyDirection Direction, 129 const SymbolIndex *Index); 130 131 /// Get call hierarchy information at \p Pos. 132 std::vector<CallHierarchyItem> 133 prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath); 134 135 std::vector<CallHierarchyIncomingCall> 136 incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index); 137 138 /// Returns all decls that are referenced in the \p FD except local symbols. 139 llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST, 140 const FunctionDecl *FD); 141 } // namespace clangd 142 } // namespace clang 143 144 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H 145