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 "support/Path.h" 21 #include "clang/AST/ASTTypeTraits.h" 22 #include "llvm/ADT/StringRef.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include <optional> 25 #include <vector> 26 27 namespace clang { 28 namespace syntax { 29 class Token; 30 class TokenBuffer; 31 } // namespace syntax 32 namespace clangd { 33 class ParsedAST; 34 35 // Describes where a symbol is declared and defined (as far as clangd knows). 36 // There are three cases: 37 // - a declaration only, no definition is known (e.g. only header seen) 38 // - a declaration and a distinct definition (e.g. function declared in header) 39 // - a declaration and an equal definition (e.g. inline function, or class) 40 // For some types of symbol, e.g. macros, definition == declaration always. 41 struct LocatedSymbol { 42 // The (unqualified) name of the symbol. 43 std::string Name; 44 // The canonical or best declaration: where most users find its interface. 45 Location PreferredDeclaration; 46 // Where the symbol is defined, if known. May equal PreferredDeclaration. 47 std::optional<Location> Definition; 48 // SymbolID of the located symbol if available. 49 SymbolID ID; 50 }; 51 llvm::raw_ostream &operator<<(llvm::raw_ostream &, const LocatedSymbol &); 52 /// Get definition of symbol at a specified \p Pos. 53 /// Multiple locations may be returned, corresponding to distinct symbols. 54 std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos, 55 const SymbolIndex *Index = nullptr); 56 57 // Tries to provide a textual fallback for locating a symbol by looking up the 58 // word under the cursor as a symbol name in the index. 59 // The aim is to pick up references to symbols in contexts where 60 // AST-based resolution does not work, such as comments, strings, and PP 61 // disabled regions. 62 // (This is for internal use by locateSymbolAt, and is exposed for testing). 63 std::vector<LocatedSymbol> locateSymbolTextually(const SpelledWord &Word, 64 ParsedAST &AST, 65 const SymbolIndex *Index, 66 llvm::StringRef MainFilePath, 67 ASTNodeKind NodeKind); 68 69 // Try to find a proximate occurrence of `Word` as an identifier, which can be 70 // used to resolve it. 71 // (This is for internal use by locateSymbolAt, and is exposed for testing). 72 const syntax::Token *findNearbyIdentifier(const SpelledWord &Word, 73 const syntax::TokenBuffer &TB); 74 75 /// Get all document links 76 std::vector<DocumentLink> getDocumentLinks(ParsedAST &AST); 77 78 /// Returns highlights for all usages of a symbol at \p Pos. 79 std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST, 80 Position Pos); 81 82 struct ReferencesResult { 83 // Bitmask describing whether the occurrence is a declaration, definition etc. 84 enum ReferenceAttributes : unsigned { 85 Declaration = 1 << 0, 86 Definition = 1 << 1, 87 // The occurrence is an override of the target base method. 88 Override = 1 << 2, 89 }; 90 struct Reference { 91 ReferenceLocation Loc; 92 unsigned Attributes = 0; 93 }; 94 std::vector<Reference> References; 95 bool HasMore = false; 96 }; 97 llvm::raw_ostream &operator<<(llvm::raw_ostream &, 98 const ReferencesResult::Reference &); 99 100 /// Returns implementations at a specified \p Pos: 101 /// - overrides for a virtual method; 102 /// - subclasses for a base class; 103 std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos, 104 const SymbolIndex *Index); 105 106 /// Returns symbols for types referenced at \p Pos. 107 /// 108 /// For example, given `b^ar()` wher bar return Foo, this function returns the 109 /// definition of class Foo. 110 std::vector<LocatedSymbol> findType(ParsedAST &AST, Position Pos, 111 const SymbolIndex *Index); 112 113 /// Returns references of the symbol at a specified \p Pos. 114 /// \p Limit limits the number of results returned (0 means no limit). 115 ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit, 116 const SymbolIndex *Index = nullptr, 117 bool AddContext = false); 118 119 /// Get info about symbols at \p Pos. 120 std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos); 121 122 /// Find the record types referenced at \p Pos. 123 std::vector<const CXXRecordDecl *> findRecordTypeAt(ParsedAST &AST, 124 Position Pos); 125 126 /// Given a record type declaration, find its base (parent) types. 127 std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD); 128 129 /// Get type hierarchy information at \p Pos. 130 std::vector<TypeHierarchyItem> getTypeHierarchy( 131 ParsedAST &AST, Position Pos, int Resolve, TypeHierarchyDirection Direction, 132 const SymbolIndex *Index = nullptr, PathRef TUPath = PathRef{}); 133 134 /// Returns direct parents of a TypeHierarchyItem using SymbolIDs stored inside 135 /// the item. 136 std::optional<std::vector<TypeHierarchyItem>> 137 superTypes(const TypeHierarchyItem &Item, const SymbolIndex *Index); 138 /// Returns direct children of a TypeHierarchyItem. 139 std::vector<TypeHierarchyItem> subTypes(const TypeHierarchyItem &Item, 140 const SymbolIndex *Index); 141 142 void resolveTypeHierarchy(TypeHierarchyItem &Item, int ResolveLevels, 143 TypeHierarchyDirection Direction, 144 const SymbolIndex *Index); 145 146 /// Get call hierarchy information at \p Pos. 147 std::vector<CallHierarchyItem> 148 prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath); 149 150 std::vector<CallHierarchyIncomingCall> 151 incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index); 152 153 std::vector<CallHierarchyOutgoingCall> 154 outgoingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index); 155 156 /// Returns all decls that are referenced in the \p FD except local symbols. 157 llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST, 158 const FunctionDecl *FD); 159 } // namespace clangd 160 } // namespace clang 161 162 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H 163