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