clang-tools 20.0.0git
Ref.h
Go to the documentation of this file.
1//===--- Ref.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_REF_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
11
12#include "index/SymbolID.h"
14#include "llvm/ADT/Hashing.h"
15#include "llvm/Support/Allocator.h"
16#include "llvm/Support/StringSaver.h"
17#include "llvm/Support/raw_ostream.h"
18#include <cstdint>
19#include <set>
20#include <utility>
21
22namespace clang {
23namespace clangd {
24
25/// Describes the kind of a cross-reference.
26///
27/// This is a bitfield which can be combined from different kinds.
28enum class RefKind : uint8_t {
29 Unknown = 0,
30 // Points to symbol declaration. Example:
31 //
32 // class Foo;
33 // ^ Foo declaration
34 // Foo foo;
35 // ^ this does not reference Foo declaration
36 Declaration = 1 << 0,
37 // Points to symbol definition. Example:
38 //
39 // int foo();
40 // ^ references foo declaration, but not foo definition
41 // int foo() { return 42; }
42 // ^ references foo definition, but not declaration
43 // bool bar() { return true; }
44 // ^ references both definition and declaration
45 Definition = 1 << 1,
46 // Points to symbol reference. Example:
47 //
48 // int Foo = 42;
49 // int Bar = Foo + 1;
50 // ^ this is a reference to Foo
51 Reference = 1 << 2,
52 // The reference explicitly spells out declaration's name. Such references can
53 // not come from macro expansions or implicit AST nodes.
54 //
55 // class Foo { public: Foo() {} };
56 // ^ references declaration, definition and explicitly spells out name
57 // #define MACRO Foo
58 // v there is an implicit constructor call here which is not a spelled ref
59 // Foo foo;
60 // ^ this reference explicitly spells out Foo's name
61 // struct Bar {
62 // MACRO Internal;
63 // ^ this references Foo, but does not explicitly spell out its name
64 // };
65 Spelled = 1 << 3,
66 // A reference which is a call. Used as a filter for which references
67 // to store in data structures used for computing outgoing calls.
68 Call = 1 << 4,
70};
71
73 return static_cast<RefKind>(static_cast<uint8_t>(L) |
74 static_cast<uint8_t>(R));
75}
76inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; }
78 return static_cast<RefKind>(static_cast<uint8_t>(A) &
79 static_cast<uint8_t>(B));
80}
81
82llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind);
83
84/// Represents a symbol occurrence in the source file.
85/// Despite the name, it could be a declaration/definition/reference.
86///
87/// WARNING: Location does not own the underlying data - Copies are shallow.
88struct Ref {
89 /// The source location where the symbol is named.
92 /// The ID of the symbol whose definition contains this reference.
93 /// For example, for a reference inside a function body, this would
94 /// be that function. For top-level definitions this isNull().
96};
97
98inline bool operator<(const Ref &L, const Ref &R) {
99 return std::tie(L.Location, L.Kind, L.Container) <
100 std::tie(R.Location, R.Kind, R.Container);
101}
102inline bool operator==(const Ref &L, const Ref &R) {
103 return std::tie(L.Location, L.Kind, L.Container) ==
104 std::tie(R.Location, R.Kind, R.Container);
105}
106
107llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &);
108
109/// An efficient structure of storing large set of symbol references in memory.
110/// Filenames are deduplicated.
111class RefSlab {
112public:
113 // Refs are stored in order.
114 using value_type = std::pair<SymbolID, llvm::ArrayRef<Ref>>;
115 using const_iterator = std::vector<value_type>::const_iterator;
117
118 RefSlab() = default;
119 RefSlab(RefSlab &&Slab) = default;
120 RefSlab &operator=(RefSlab &&RHS) = default;
121
122 const_iterator begin() const { return Refs.begin(); }
123 const_iterator end() const { return Refs.end(); }
124 /// Gets the number of symbols.
125 size_t size() const { return Refs.size(); }
126 size_t numRefs() const { return NumRefs; }
127 bool empty() const { return Refs.empty(); }
128
129 size_t bytes() const {
130 return sizeof(*this) + Arena.getTotalMemory() +
131 sizeof(value_type) * Refs.capacity();
132 }
133
134 /// RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
135 class Builder {
136 public:
137 Builder() : UniqueStrings(Arena) {}
138 /// Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
139 void insert(const SymbolID &ID, const Ref &S);
140 /// Consumes the builder to finalize the slab.
142
143 private:
144 // A ref we're storing with its symbol to consume with build().
145 // All strings are interned, so DenseMapInfo can use pointer comparisons.
146 struct Entry {
148 Ref Reference;
149 };
150 friend struct llvm::DenseMapInfo<Entry>;
151
152 llvm::BumpPtrAllocator Arena;
153 llvm::UniqueStringSaver UniqueStrings; // Contents on the arena.
154 llvm::DenseSet<Entry> Entries;
155 };
156
157private:
158 RefSlab(std::vector<value_type> Refs, llvm::BumpPtrAllocator Arena,
159 size_t NumRefs)
160 : Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {}
161
162 llvm::BumpPtrAllocator Arena;
163 std::vector<value_type> Refs;
164 /// Number of all references.
165 size_t NumRefs = 0;
166};
167
168} // namespace clangd
169} // namespace clang
170
171namespace llvm {
172template <> struct DenseMapInfo<clang::clangd::RefSlab::Builder::Entry> {
173 using Entry = clang::clangd::RefSlab::Builder::Entry;
174 static inline Entry getEmptyKey() {
175 static Entry E{clang::clangd::SymbolID(""), {}};
176 return E;
177 }
178 static inline Entry getTombstoneKey() {
179 static Entry E{clang::clangd::SymbolID("TOMBSTONE"), {}};
180 return E;
181 }
182 static unsigned getHashValue(const Entry &Val) {
183 return llvm::hash_combine(
184 Val.Symbol, reinterpret_cast<uintptr_t>(Val.Reference.Location.FileURI),
185 Val.Reference.Location.Start.rep(), Val.Reference.Location.End.rep());
186 }
187 static bool isEqual(const Entry &LHS, const Entry &RHS) {
188 return std::tie(LHS.Symbol, LHS.Reference.Location.FileURI,
189 LHS.Reference.Kind) ==
190 std::tie(RHS.Symbol, RHS.Reference.Location.FileURI,
191 RHS.Reference.Kind) &&
192 LHS.Reference.Location.Start == RHS.Reference.Location.Start &&
193 LHS.Reference.Location.End == RHS.Reference.Location.End;
194 }
195};
196} // namespace llvm
197
198#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H
const Expr * E
llvm::BumpPtrAllocator Arena
RefSlab::Builder is a mutable container that can 'freeze' to RefSlab.
Definition: Ref.h:135
RefSlab build() &&
Consumes the builder to finalize the slab.
Definition: Ref.cpp:42
void insert(const SymbolID &ID, const Ref &S)
Adds a ref to the slab. Deep copy: Strings will be owned by the slab.
Definition: Ref.cpp:36
An efficient structure of storing large set of symbol references in memory.
Definition: Ref.h:111
std::pair< SymbolID, llvm::ArrayRef< Ref > > value_type
Definition: Ref.h:114
const_iterator iterator
Definition: Ref.h:116
size_t numRefs() const
Definition: Ref.h:126
RefSlab(RefSlab &&Slab)=default
const_iterator end() const
Definition: Ref.h:123
std::vector< value_type >::const_iterator const_iterator
Definition: Ref.h:115
bool empty() const
Definition: Ref.h:127
size_t size() const
Gets the number of symbols.
Definition: Ref.h:125
RefSlab & operator=(RefSlab &&RHS)=default
size_t bytes() const
Definition: Ref.h:129
const_iterator begin() const
Definition: Ref.h:122
DeclRelationSet operator&(DeclRelation L, DeclRelation R)
Definition: FindTarget.h:211
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
Definition: Headers.cpp:331
llvm::raw_ostream & operator<<(llvm::raw_ostream &OS, const CodeCompletion &C)
DeclRelationSet operator|(DeclRelation L, DeclRelation R)
Definition: FindTarget.h:208
bool operator<(const Ref &L, const Ref &R)
Definition: Ref.h:98
RefKind
Describes the kind of a cross-reference.
Definition: Ref.h:28
IncludeGraphNode::SourceFlag & operator|=(IncludeGraphNode::SourceFlag &A, IncludeGraphNode::SourceFlag B)
Definition: Headers.h:115
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Some operations such as code completion produce a set of candidates.
Definition: Generators.h:58
Represents a symbol occurrence in the source file.
Definition: Ref.h:88
RefKind Kind
Definition: Ref.h:91
SymbolID Container
The ID of the symbol whose definition contains this reference.
Definition: Ref.h:95
SymbolLocation Location
The source location where the symbol is named.
Definition: Ref.h:90
The class presents a C++ symbol, e.g.
Definition: Symbol.h:39
clang::clangd::RefSlab::Builder::Entry Entry
Definition: Ref.h:173
static unsigned getHashValue(const Entry &Val)
Definition: Ref.h:182
static bool isEqual(const Entry &LHS, const Entry &RHS)
Definition: Ref.h:187