clang: include/clang/AST/Redeclarable.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef LLVM_CLANG_AST_REDECLARABLE_H
14#define LLVM_CLANG_AST_REDECLARABLE_H
15
17#include "llvm/ADT/DenseMapInfo.h"
18#include "llvm/ADT/PointerUnion.h"
19#include "llvm/ADT/iterator_range.h"
20#include "llvm/Support/Casting.h"
21#include
22#include
23#include
24
26
27class ASTContext;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83template<typename decl_type>
85protected:
87
88
92
93
94
95
96 using UninitializedLatest = const void *;
97
99
100
101
102
103 using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
104
105 mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Link;
106
107 public:
110
112 : Link(NotKnownLatest(reinterpret_cast(&Ctx))) {}
114
116 return isa(Link) ||
117
118
119 isa(cast(Link));
120 }
121
123 if (NotKnownLatest NKL = dyn_cast(Link)) {
124 if (auto *Prev = dyn_cast(NKL))
125 return static_cast<decl_type *>(Prev);
126
127
129 cast(NKL)),
130 const_cast<decl_type *>(D));
131 }
132
133 return static_cast<decl_type *>(cast(Link).get(D));
134 }
135
137 assert(() && "decl became non-canonical unexpectedly");
139 }
140
142 assert(isFirst() && "decl became canonical unexpectedly");
143 if (NotKnownLatest NKL = dyn_cast(Link)) {
145 cast(NKL)),
146 D);
147 } else {
148 auto Latest = cast(Link);
149 Latest.set(D);
150 Link = Latest;
151 }
152 }
153
154 void markIncomplete() { cast(Link).markIncomplete(); }
155
157 assert(isFirst() && "expected a canonical decl");
158 if (isa(Link))
159 return nullptr;
160 return cast(Link).getNotUpdated();
161 }
162 };
163
166 }
167
170 }
171
172
173
174
175
176
177
178
179
180
181
182
184
186
189 }
190
191public:
196
199 First(static_cast<decl_type *>(this)) {}
200
201
202
206 return nullptr;
207 }
209 return const_cast<decl_type *>(
210 static_cast<const decl_type*>(this))->getPreviousDecl();
211 }
212
213
214
216
217
218
220
221
223
224
226 return getFirstDecl()->getNextRedeclaration();
227 }
228
229
231 return getFirstDecl()->getNextRedeclaration();
232 }
233
234
235
237
238
240
241 decl_type *Current = nullptr;
242 decl_type *Starter = nullptr;
243 bool PassedFirst = false;
244
245 public:
251
254
257
259 assert(Current && "Advancing while iterator has reached end");
260
261
262 if (Current->isFirstDecl()) {
263 if (PassedFirst) {
264 assert(0 && "Passed first decl twice, invalid redecl chain!");
265 Current = nullptr;
266 return *this;
267 }
268 PassedFirst = true;
269 }
270
271
272 decl_type *Next = Current->getNextRedeclaration();
273 Current = (Next != Starter) ? Next : nullptr;
274 return *this;
275 }
276
279 ++(*this);
280 return tmp;
281 }
282
284 return x.Current == y.Current;
285 }
287 return x.Current != y.Current;
288 }
289 };
290
291 using redecl_range = llvm::iterator_range<redecl_iterator>;
292
293
294
297 static_cast<const decl_type *>(this))),
299 }
300
303};
304
305
306
308
309
310
311
312template<typename decl_type>
314public:
316
317
318
320 auto *D = static_cast<decl_type *>(this);
321 if (->isFromASTFile())
322 return D;
324 }
325
326
327
329 const auto *D = static_cast<const decl_type *>(this);
330 if (->isFromASTFile())
331 return D;
333 }
334
335
337};
338
339
340
341
342
343
344
345
346
347
349public:
355
356 operator decl_type *() { return Ptr; }
357 operator const decl_type *() const { return Ptr; }
358
360 const decl_type *operator->() const { return Ptr; }
361
363 const decl_type &operator*() const { return *Ptr; }
364
366 return LHS.Ptr == RHS.Ptr;
367 }
369 return LHS.Ptr != RHS.Ptr;
370 }
371
372private:
373 friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
375
376 decl_type *Ptr = nullptr;
377};
378
379}
380
381namespace llvm {
382
383template <typename decl_type>
386 using BaseInfo = DenseMapInfo<decl_type *>;
387
389
390
392 P.Ptr = BaseInfo::getEmptyKey();
393 return P;
394 }
395
398 P.Ptr = BaseInfo::getTombstoneKey();
399 return P;
400 }
401
403 return BaseInfo::getHashValue(P);
404 }
405
408 return BaseInfo::isEqual(LHS, RHS);
409 }
410};
411
412template <typename decl_type>
415 return P.Ptr;
416 }
420 return C;
421 }
422 static constexpr int NumLowBitsAvailable =
424};
425
426}
427
428#endif
static const Decl * getCanonicalDecl(const Decl *D)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A wrapper class around a pointer that always points to its canonical declaration.
CanonicalDeclPtr(const CanonicalDeclPtr &)=default
const decl_type * operator->() const
CanonicalDeclPtr & operator=(const CanonicalDeclPtr &)=default
const decl_type & operator*() const
CanonicalDeclPtr(decl_type *Ptr)
friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
CanonicalDeclPtr()=default
friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
Decl - This represents one declaration (or definition), e.g.
virtual void CompleteRedeclChain(const Decl *D)
Gives the external AST source an opportunity to complete the redeclaration chain for a declaration.
Provides support for incremental compilation.
Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...
bool isFirstDecl() const
Returns true if this is the first declaration.
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
DeclLink(LatestTag, const ASTContext &Ctx)
DeclLink(PreviousTag, decl_type *D)
void setPrevious(decl_type *D)
Decl * getLatestNotUpdated() const
void setLatest(decl_type *D)
decl_type * getPrevious(const decl_type *D) const
Iterates through all the redeclarations of the same decl.
friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y)
friend bool operator==(const redecl_iterator &x, const redecl_iterator &y)
redecl_iterator(decl_type *C)
redecl_iterator()=default
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
reference operator*() const
redecl_iterator operator++(int)
redecl_iterator & operator++()
pointer operator->() const
Provides common interface for the Decls that can be redeclared.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
const decl_type * getMostRecentDecl() const
Returns the most recent (re)declaration of this declaration.
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
decl_type * getNextRedeclaration() const
Redeclarable(const ASTContext &Ctx)
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
redecl_iterator redecls_end() const
const decl_type * getPreviousDecl() const
DeclLink RedeclLink
Points to the next redeclaration in the chain.
llvm::iterator_range< redecl_iterator > redecl_range
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
static DeclLink LatestDeclLink(const ASTContext &Ctx)
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
redecl_iterator redecls_begin() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
static DeclLink PreviousDeclLink(decl_type *D)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Diagnostic wrappers for TextAPI types for error reporting.
A lazy value (of type T) that is within an AST node of type Owner, where the value might change in la...
static unsigned getHashValue(const CanonicalDeclPtr &P)
static bool isEqual(const CanonicalDeclPtr &LHS, const CanonicalDeclPtr &RHS)
static CanonicalDeclPtr getEmptyKey()
DenseMapInfo< decl_type * > BaseInfo
static CanonicalDeclPtr getTombstoneKey()
static void * getAsVoidPointer(clang::CanonicalDeclPtr< decl_type > P)
static clang::CanonicalDeclPtr< decl_type > getFromVoidPointer(void *P)