clang-tools 24.0.0git
Symbol.h
Go to the documentation of this file.
1//===--- Symbol.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#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H
11
12#include "Protocol.h"
13#include "index/SymbolID.h"
15#include "index/SymbolOrigin.h"
16#include "clang/Index/IndexSymbol.h"
17#include "llvm/ADT/BitmaskEnum.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/StringSaver.h"
20
21namespace clang {
22namespace clangd {
23
25
26/// A bitmask type representing symbol tags supported by LSP.
27/// \see
28/// https://microsoft.github.io/language-server-protocol/specifications/specification-current/#symbolTag
29using SymbolTags = uint32_t;
30/// Ensure we have enough bits to represent all SymbolTag values.
31static_assert(static_cast<unsigned>(SymbolTag::LastTag) < 32,
32 "Too many SymbolTags to fit in uint32_t. Change to uint64_t if "
33 "we ever have more than 32 tags.");
34
35/// The class presents a C++ symbol, e.g. class, function.
36///
37/// WARNING: Symbols do not own much of their underlying data - typically
38/// strings are owned by a SymbolSlab. They should be treated as non-owning
39/// references. Copies are shallow.
40///
41/// When adding new unowned data fields to Symbol, remember to update:
42/// - SymbolSlab::Builder in Index.cpp, to copy them to the slab's storage.
43/// - mergeSymbol in Merge.cpp, to properly combine two Symbols.
44///
45/// A fully documented symbol can be split as:
46/// size_type std::map<k, t>::count(const K& key) const
47/// | Return | Scope |Name| Signature |
48/// We split up these components to allow display flexibility later.
49struct Symbol {
50 /// The ID of the symbol.
52 /// The symbol information, like symbol kind.
53 index::SymbolInfo SymInfo = index::SymbolInfo();
54 /// Where this symbol came from. Usually an index provides a constant value.
56 /// The unqualified name of the symbol, e.g. "bar" (for ns::bar).
57 llvm::StringRef Name;
58 /// The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
59 llvm::StringRef Scope;
60 /// The location of the symbol's definition, if one was found.
61 /// This just covers the symbol name (e.g. without class/function body).
63 /// The location of the preferred declaration of the symbol.
64 /// This just covers the symbol name.
65 /// This may be the same as Definition.
66 ///
67 /// A C++ symbol may have multiple declarations, and we pick one to prefer.
68 /// * For classes, the canonical declaration should be the definition.
69 /// * For non-inline functions, the canonical declaration typically appears
70 /// in the ".h" file corresponding to the definition.
72 /// The number of translation units that reference this symbol from their main
73 /// file. This number is only meaningful if aggregated in an index.
74 unsigned References = 0;
75 /// Symbol tags for LSP protocol (Deprecated, Static, Virtual, Abstract,
76 /// Final, ReadOnly, Public, Protected, Private, Declaration, Definition).
77 /// This is a bitmask where each bit represents a SymbolTag.
79 /// A brief description of the symbol that can be appended in the completion
80 /// candidate list. For example, "(X x, Y y) const" is a function signature.
81 /// Only set when the symbol is indexed for completion.
82 llvm::StringRef Signature;
83 /// Argument list in human-readable format, will be displayed to help
84 /// disambiguate between different specializations of a template. Empty for
85 /// non-specializations. Example: "<int, bool, 3>"
87 /// What to insert when completing this symbol, after the symbol name.
88 /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function).
89 /// (When snippets are disabled, the symbol name alone is used).
90 /// Only set when the symbol is indexed for completion.
91 llvm::StringRef CompletionSnippetSuffix;
92 /// Documentation including comment for the symbol declaration.
93 llvm::StringRef Documentation;
94 /// Type when this symbol is used in an expression. (Short display form).
95 /// e.g. return type of a function, or type of a variable.
96 /// Only set when the symbol is indexed for completion.
97 llvm::StringRef ReturnType;
98
99 /// Raw representation of the OpaqueType of the symbol, used for scoring
100 /// purposes.
101 /// Only set when the symbol is indexed for completion.
102 llvm::StringRef Type;
103
104 enum IncludeDirective : uint8_t {
106 /// `#include "header.h"`
108 /// `#import "header.h"`
110
111 LLVM_MARK_AS_BITMASK_ENUM(Import)
112 };
113
116
122
123 /// This can be either a URI of the header to be #include'd
124 /// for this symbol, or a literal header quoted with <> or "" that is
125 /// suitable to be included directly. When it is a URI, the exact #include
126 /// path needs to be calculated according to the URI scheme.
127 ///
128 /// Note that the include header is a canonical include for the symbol and
129 /// can be different from FileURI in the CanonicalDeclaration.
130 llvm::StringRef IncludeHeader = "";
131 /// The number of translation units that reference this symbol and include
132 /// this header. This number is only meaningful if aggregated in an index.
133 uint32_t References : 30;
134 /// Bitfield of supported directives (IncludeDirective) that can be used
135 /// when including this header.
137
141 };
142 /// One Symbol can potentially be included via different headers.
143 /// - If we haven't seen a definition, this covers all declarations.
144 /// - If we have seen a definition, this covers declarations visible from
145 /// any definition.
146 /// Only set when the symbol is indexed for completion.
147 llvm::SmallVector<IncludeHeaderWithReferences, 1> IncludeHeaders;
148
149 enum SymbolFlag : uint8_t {
150 None = 0,
151 /// Whether or not this symbol is meant to be used for the code completion.
152 /// See also isIndexedForCodeCompletion().
153 /// Note that we don't store completion information (signature, snippet,
154 /// type, includes) if the symbol is not indexed for code completion.
156 /// Indicates if the symbol is deprecated.
157 Deprecated = 1 << 1,
158 /// Symbol is an implementation detail.
160 /// Symbol is visible to other files (not e.g. a static helper function).
162 /// Symbol has an attached documentation comment.
164 };
166
167 /// FIXME: also add deprecation message and fixit?
168};
169
172 return static_cast<Symbol::SymbolFlag>(static_cast<uint8_t>(A) |
173 static_cast<uint8_t>(B));
174}
177 return A = A | B;
178}
179
180llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S);
181llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag);
182
183/// Invokes Callback with each StringRef& contained in the Symbol.
184/// Useful for deduplicating backing strings.
185template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
186 CB(S.Name);
187 CB(S.Scope);
189 CB(S.Signature);
191 CB(S.Documentation);
192 CB(S.ReturnType);
193 CB(S.Type);
194 auto RawCharPointerCB = [&CB](const char *&P) {
195 llvm::StringRef S(P);
196 CB(S);
197 assert(!S.data()[S.size()] && "Visited StringRef must be null-terminated");
198 P = S.data();
199 };
200 RawCharPointerCB(S.CanonicalDeclaration.FileURI);
201 RawCharPointerCB(S.Definition.FileURI);
202
203 for (auto &Include : S.IncludeHeaders)
204 CB(Include.IncludeHeader);
205}
206
207/// Computes query-independent quality score for a Symbol.
208/// This currently falls in the range [1, ln(#indexed documents)].
209/// FIXME: this should probably be split into symbol -> signals
210/// and signals -> score, so it can be reused for Sema completions.
211float quality(const Symbol &S);
212
213/// An immutable symbol container that stores a set of symbols.
214/// The container will maintain the lifetime of the symbols.
216public:
217 using const_iterator = std::vector<Symbol>::const_iterator;
220
221 SymbolSlab() = default;
222
223 const_iterator begin() const { return Symbols.begin(); }
224 const_iterator end() const { return Symbols.end(); }
225 const_iterator find(const SymbolID &SymID) const;
226
227 using size_type = size_t;
228 size_type size() const { return Symbols.size(); }
229 bool empty() const { return Symbols.empty(); }
230 // Estimates the total memory usage.
231 size_t bytes() const {
232 return sizeof(*this) + Arena.getTotalMemory() +
233 Symbols.capacity() * sizeof(Symbol);
234 }
235
236 /// SymbolSlab::Builder is a mutable container that can 'freeze' to
237 /// SymbolSlab. The frozen SymbolSlab will use less memory.
238 class Builder {
239 public:
240 Builder() : UniqueStrings(Arena) {}
241
242 /// Adds a symbol, overwriting any existing one with the same ID.
243 /// This is a deep copy: underlying strings will be owned by the slab.
244 void insert(const Symbol &S);
245
246 /// Removes the symbol with an ID, if it exists.
247 void erase(const SymbolID &ID) { Symbols.erase(ID); }
248
249 /// Returns the symbol with an ID, if it exists. Valid until insert/remove.
250 const Symbol *find(const SymbolID &ID) {
251 auto I = Symbols.find(ID);
252 return I == Symbols.end() ? nullptr : &I->second;
253 }
254
255 /// Consumes the builder to finalize the slab.
256 SymbolSlab build() &&;
257
258 private:
259 llvm::BumpPtrAllocator Arena;
260 /// Intern table for strings. Contents are on the arena.
261 llvm::UniqueStringSaver UniqueStrings;
262 /// Values are indices into Symbols vector.
263 llvm::DenseMap<SymbolID, Symbol> Symbols;
264 };
265
266private:
267 SymbolSlab(llvm::BumpPtrAllocator Arena, std::vector<Symbol> Symbols)
268 : Arena(std::move(Arena)), Symbols(std::move(Symbols)) {}
269
270 llvm::BumpPtrAllocator Arena; // Owns Symbol data that the Symbols do not.
271 std::vector<Symbol> Symbols; // Sorted by SymbolID to allow lookup.
272};
273
274llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolSlab &Slab);
275
276} // namespace clangd
277} // namespace clang
278
279#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H
const Symbol * find(const SymbolID &ID)
Returns the symbol with an ID, if it exists. Valid until insert/remove.
Definition Symbol.h:250
void erase(const SymbolID &ID)
Removes the symbol with an ID, if it exists.
Definition Symbol.h:247
void insert(const Symbol &S)
Adds a symbol, overwriting any existing one with the same ID.
Definition Symbol.cpp:52
SymbolSlab build() &&
Consumes the builder to finalize the slab.
Definition Symbol.cpp:56
size_type size() const
Definition Symbol.h:228
const_iterator iterator
Definition Symbol.h:218
size_t bytes() const
Definition Symbol.h:231
const_iterator begin() const
Definition Symbol.h:223
const_iterator end() const
Definition Symbol.h:224
const_iterator find(const SymbolID &SymID) const
Definition Symbol.cpp:39
std::vector< Symbol >::const_iterator const_iterator
Definition Symbol.h:217
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Definition AST.cpp:44
void visitStrings(Symbol &S, const Callback &CB)
Invokes Callback with each StringRef& contained in the Symbol.
Definition Symbol.h:185
uint32_t SymbolTags
A bitmask type representing symbol tags supported by LSP.
Definition Symbol.h:29
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition Function.h:28
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
DeclRelationSet operator|(DeclRelation L, DeclRelation R)
Definition FindTarget.h:210
float quality(const Symbol &S)
Computes query-independent quality score for a Symbol.
Definition Symbol.cpp:31
IncludeGraphNode::SourceFlag & operator|=(IncludeGraphNode::SourceFlag &A, IncludeGraphNode::SourceFlag B)
Definition Headers.h:117
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
uint32_t SupportedDirectives
Bitfield of supported directives (IncludeDirective) that can be used when including this header.
Definition Symbol.h:136
uint32_t References
The number of translation units that reference this symbol and include this header.
Definition Symbol.h:133
IncludeHeaderWithReferences(llvm::StringRef IncludeHeader, uint32_t References, IncludeDirective SupportedDirectives)
Definition Symbol.h:117
llvm::StringRef IncludeHeader
This can be either a URI of the header to be include'd for this symbol, or a literal header quoted wi...
Definition Symbol.h:130
Ensure we have enough bits to represent all SymbolTag values.
Definition Symbol.h:49
SymbolFlag Flags
Definition Symbol.h:165
@ IndexedForCodeCompletion
Whether or not this symbol is meant to be used for the code completion.
Definition Symbol.h:155
@ Deprecated
Indicates if the symbol is deprecated.
Definition Symbol.h:157
@ ImplementationDetail
Symbol is an implementation detail.
Definition Symbol.h:159
@ HasDocComment
Symbol has an attached documentation comment.
Definition Symbol.h:163
@ VisibleOutsideFile
Symbol is visible to other files (not e.g. a static helper function).
Definition Symbol.h:161
@ Include
#include "header.h"
Definition Symbol.h:107
@ Import
#import "header.h"
Definition Symbol.h:109
SymbolLocation Definition
The location of the symbol's definition, if one was found.
Definition Symbol.h:62
llvm::StringRef Type
Raw representation of the OpaqueType of the symbol, used for scoring purposes.
Definition Symbol.h:102
llvm::StringRef Documentation
Documentation including comment for the symbol declaration.
Definition Symbol.h:93
SymbolTags Tags
Symbol tags for LSP protocol (Deprecated, Static, Virtual, Abstract, Final, ReadOnly,...
Definition Symbol.h:78
index::SymbolInfo SymInfo
The symbol information, like symbol kind.
Definition Symbol.h:53
llvm::SmallVector< IncludeHeaderWithReferences, 1 > IncludeHeaders
One Symbol can potentially be included via different headers.
Definition Symbol.h:147
llvm::StringRef Name
The unqualified name of the symbol, e.g. "bar" (for ns::bar).
Definition Symbol.h:57
llvm::StringRef Scope
The containing namespace. e.g. "" (global), "ns::" (top-level namespace).
Definition Symbol.h:59
llvm::StringRef Signature
A brief description of the symbol that can be appended in the completion candidate list.
Definition Symbol.h:82
unsigned References
The number of translation units that reference this symbol from their main file.
Definition Symbol.h:74
llvm::StringRef ReturnType
Type when this symbol is used in an expression.
Definition Symbol.h:97
llvm::StringRef TemplateSpecializationArgs
Argument list in human-readable format, will be displayed to help disambiguate between different spec...
Definition Symbol.h:86
SymbolLocation CanonicalDeclaration
The location of the preferred declaration of the symbol.
Definition Symbol.h:71
llvm::StringRef CompletionSnippetSuffix
What to insert when completing this symbol, after the symbol name.
Definition Symbol.h:91
SymbolID ID
The ID of the symbol.
Definition Symbol.h:51
SymbolOrigin Origin
Where this symbol came from. Usually an index provides a constant value.
Definition Symbol.h:55