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