| 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 |
| 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 | |