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 | /// Returns all decls that are referenced in the \p FD except local symbols. |
154 | llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST, |
155 | const FunctionDecl *FD); |
156 | } // namespace clangd |
157 | } // namespace clang |
158 | |
159 | #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H |
160 | |