clang 20.0.0git
Redeclarable.h
Go to the documentation of this file.
1//===- Redeclarable.h - Base for Decls that can be redeclared --*- 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// This file defines the Redeclarable interface.
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 <cassert>
22#include <cstddef>
23#include <iterator>
24
25namespace clang {
26
27class ASTContext;
28class Decl;
29
30// Some notes on redeclarables:
31//
32// - Every redeclarable is on a circular linked list.
33//
34// - Every decl has a pointer to the first element of the chain _and_ a
35// DeclLink that may point to one of 3 possible states:
36// - the "previous" (temporal) element in the chain
37// - the "latest" (temporal) element in the chain
38// - the "uninitialized-latest" value (when newly-constructed)
39//
40// - The first element is also often called the canonical element. Every
41// element has a pointer to it so that "getCanonical" can be fast.
42//
43// - Most links in the chain point to previous, except the link out of
44// the first; it points to latest.
45//
46// - Elements are called "first", "previous", "latest" or
47// "most-recent" when referring to temporal order: order of addition
48// to the chain.
49//
50// - It's easiest to just ignore the implementation of DeclLink when making
51// sense of the redeclaration chain.
52//
53// - There's also a "definition" link for several types of
54// redeclarable, where only one definition should exist at any given
55// time (and the defn pointer is stored in the decl's "data" which
56// is copied to every element on the chain when it's changed).
57//
58// Here is some ASCII art:
59//
60// "first" "latest"
61// "canonical" "most recent"
62// +------------+ first +--------------+
63// | | <--------------------------- | |
64// | | | |
65// | | | |
66// | | +--------------+ | |
67// | | first | | | |
68// | | <---- | | | |
69// | | | | | |
70// | @class A | link | @interface A | link | @class A |
71// | seen first | <---- | seen second | <---- | seen third |
72// | | | | | |
73// +------------+ +--------------+ +--------------+
74// | data | defn | data | defn | data |
75// | | ----> | | <---- | |
76// +------------+ +--------------+ +--------------+
77// | | ^ ^
78// | |defn | |
79// | link +-----+ |
80// +-->-------------------------------------------+
81
82/// Provides common interface for the Decls that can be redeclared.
83template<typename decl_type>
85protected:
86 class DeclLink {
87 /// A pointer to a known latest declaration, either statically known or
88 /// generationally updated as decls are added by an external source.
89 using KnownLatest =
92
93 /// We store a pointer to the ASTContext in the UninitializedLatest
94 /// pointer, but to avoid circular type dependencies when we steal the low
95 /// bits of this pointer, we use a raw void* here.
96 using UninitializedLatest = const void *;
97
98 using Previous = Decl *;
99
100 /// A pointer to either an uninitialized latest declaration (where either
101 /// we've not yet set the previous decl or there isn't one), or to a known
102 /// previous declaration.
103 using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
104
105 mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Link;
106
107 public:
110
112 : Link(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
113 DeclLink(PreviousTag, decl_type *D) : Link(NotKnownLatest(Previous(D))) {}
114
115 bool isFirst() const {
116 return Link.is<KnownLatest>() ||
117 // FIXME: 'template' is required on the next line due to an
118 // apparent clang bug.
119 Link.get<NotKnownLatest>().template is<UninitializedLatest>();
120 }
121
122 decl_type *getPrevious(const decl_type *D) const {
123 if (Link.is<NotKnownLatest>()) {
124 NotKnownLatest NKL = Link.get<NotKnownLatest>();
125 if (NKL.is<Previous>())
126 return static_cast<decl_type*>(NKL.get<Previous>());
127
128 // Allocate the generational 'most recent' cache now, if needed.
129 Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
130 NKL.get<UninitializedLatest>()),
131 const_cast<decl_type *>(D));
132 }
133
134 return static_cast<decl_type*>(Link.get<KnownLatest>().get(D));
135 }
136
137 void setPrevious(decl_type *D) {
138 assert(!isFirst() && "decl became non-canonical unexpectedly");
139 Link = Previous(D);
140 }
141
142 void setLatest(decl_type *D) {
143 assert(isFirst() && "decl became canonical unexpectedly");
144 if (Link.is<NotKnownLatest>()) {
145 NotKnownLatest NKL = Link.get<NotKnownLatest>();
146 Link = KnownLatest(*reinterpret_cast<const ASTContext *>(
147 NKL.get<UninitializedLatest>()),
148 D);
149 } else {
150 auto Latest = Link.get<KnownLatest>();
151 Latest.set(D);
152 Link = Latest;
153 }
154 }
155
156 void markIncomplete() { Link.get<KnownLatest>().markIncomplete(); }
157
159 assert(isFirst() && "expected a canonical decl");
160 if (Link.is<NotKnownLatest>())
161 return nullptr;
162 return Link.get<KnownLatest>().getNotUpdated();
163 }
164 };
165
166 static DeclLink PreviousDeclLink(decl_type *D) {
168 }
169
170 static DeclLink LatestDeclLink(const ASTContext &Ctx) {
171 return DeclLink(DeclLink::LatestLink, Ctx);
172 }
173
174 /// Points to the next redeclaration in the chain.
175 ///
176 /// If isFirst() is false, this is a link to the previous declaration
177 /// of this same Decl. If isFirst() is true, this is the first
178 /// declaration and Link points to the latest declaration. For example:
179 ///
180 /// #1 int f(int x, int y = 1); // <pointer to #3, true>
181 /// #2 int f(int x = 0, int y); // <pointer to #1, false>
182 /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
183 ///
184 /// If there is only one declaration, it is <pointer to self, true>
186
187 decl_type *First;
188
189 decl_type *getNextRedeclaration() const {
190 return RedeclLink.getPrevious(static_cast<const decl_type *>(this));
191 }
192
193public:
194 friend class ASTDeclMerger;
195 friend class ASTDeclReader;
196 friend class ASTDeclWriter;
197 friend class IncrementalParser;
198
201 First(static_cast<decl_type *>(this)) {}
202
203 /// Return the previous declaration of this declaration or NULL if this
204 /// is the first declaration.
205 decl_type *getPreviousDecl() {
206 if (!RedeclLink.isFirst())
207 return getNextRedeclaration();
208 return nullptr;
209 }
210 const decl_type *getPreviousDecl() const {
211 return const_cast<decl_type *>(
212 static_cast<const decl_type*>(this))->getPreviousDecl();
213 }
214
215 /// Return the first declaration of this declaration or itself if this
216 /// is the only declaration.
217 decl_type *getFirstDecl() { return First; }
218
219 /// Return the first declaration of this declaration or itself if this
220 /// is the only declaration.
221 const decl_type *getFirstDecl() const { return First; }
222
223 /// True if this is the first declaration in its redeclaration chain.
224 bool isFirstDecl() const { return RedeclLink.isFirst(); }
225
226 /// Returns the most recent (re)declaration of this declaration.
227 decl_type *getMostRecentDecl() {
228 return getFirstDecl()->getNextRedeclaration();
229 }
230
231 /// Returns the most recent (re)declaration of this declaration.
232 const decl_type *getMostRecentDecl() const {
233 return getFirstDecl()->getNextRedeclaration();
234 }
235
236 /// Set the previous declaration. If PrevDecl is NULL, set this as the
237 /// first and only declaration.
238 void setPreviousDecl(decl_type *PrevDecl);
239
240 /// Iterates through all the redeclarations of the same decl.
242 /// Current - The current declaration.
243 decl_type *Current = nullptr;
244 decl_type *Starter = nullptr;
245 bool PassedFirst = false;
246
247 public:
248 using value_type = decl_type *;
249 using reference = decl_type *;
250 using pointer = decl_type *;
251 using iterator_category = std::forward_iterator_tag;
252 using difference_type = std::ptrdiff_t;
253
254 redecl_iterator() = default;
255 explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) {}
256
257 reference operator*() const { return Current; }
258 pointer operator->() const { return Current; }
259
261 assert(Current && "Advancing while iterator has reached end");
262 // Make sure we don't infinitely loop on an invalid redecl chain. This
263 // should never happen.
264 if (Current->isFirstDecl()) {
265 if (PassedFirst) {
266 assert(0 && "Passed first decl twice, invalid redecl chain!");
267 Current = nullptr;
268 return *this;
269 }
270 PassedFirst = true;
271 }
272
273 // Get either previous decl or latest decl.
274 decl_type *Next = Current->getNextRedeclaration();
275 Current = (Next != Starter) ? Next : nullptr;
276 return *this;
277 }
278
280 redecl_iterator tmp(*this);
281 ++(*this);
282 return tmp;
283 }
284
285 friend bool operator==(const redecl_iterator &x, const redecl_iterator &y) {
286 return x.Current == y.Current;
287 }
288 friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y) {
289 return x.Current != y.Current;
290 }
291 };
292
293 using redecl_range = llvm::iterator_range<redecl_iterator>;
294
295 /// Returns an iterator range for all the redeclarations of the same
296 /// decl. It will iterate at least once (when this decl is the only one).
298 return redecl_range(redecl_iterator(const_cast<decl_type *>(
299 static_cast<const decl_type *>(this))),
301 }
302
303 redecl_iterator redecls_begin() const { return redecls().begin(); }
304 redecl_iterator redecls_end() const { return redecls().end(); }
305};
306
307/// Get the primary declaration for a declaration from an AST file. That
308/// will be the first-loaded declaration.
309Decl *getPrimaryMergedDecl(Decl *D);
310
311/// Provides common interface for the Decls that cannot be redeclared,
312/// but can be merged if the same declaration is brought in from multiple
313/// modules.
314template<typename decl_type>
316public:
317 Mergeable() = default;
318
319 /// Return the first declaration of this declaration or itself if this
320 /// is the only declaration.
321 decl_type *getFirstDecl() {
322 auto *D = static_cast<decl_type *>(this);
323 if (!D->isFromASTFile())
324 return D;
325 return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
326 }
327
328 /// Return the first declaration of this declaration or itself if this
329 /// is the only declaration.
330 const decl_type *getFirstDecl() const {
331 const auto *D = static_cast<const decl_type *>(this);
332 if (!D->isFromASTFile())
333 return D;
334 return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
335 }
336
337 /// Returns true if this is the first declaration.
338 bool isFirstDecl() const { return getFirstDecl() == this; }
339};
340
341/// A wrapper class around a pointer that always points to its canonical
342/// declaration.
343///
344/// CanonicalDeclPtr<decl_type> behaves just like decl_type*, except we call
345/// decl_type::getCanonicalDecl() on construction.
346///
347/// This is useful for hashtables that you want to be keyed on a declaration's
348/// canonical decl -- if you use CanonicalDeclPtr as the key, you don't need to
349/// remember to call getCanonicalDecl() everywhere.
350template <typename decl_type> class CanonicalDeclPtr {
351public:
352 CanonicalDeclPtr() = default;
353 CanonicalDeclPtr(decl_type *Ptr)
354 : Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
357
358 operator decl_type *() { return Ptr; }
359 operator const decl_type *() const { return Ptr; }
360
361 decl_type *operator->() { return Ptr; }
362 const decl_type *operator->() const { return Ptr; }
363
364 decl_type &operator*() { return *Ptr; }
365 const decl_type &operator*() const { return *Ptr; }
366
368 return LHS.Ptr == RHS.Ptr;
369 }
371 return LHS.Ptr != RHS.Ptr;
372 }
373
374private:
375 friend struct llvm::DenseMapInfo<CanonicalDeclPtr<decl_type>>;
376 friend struct llvm::PointerLikeTypeTraits<CanonicalDeclPtr<decl_type>>;
377
378 decl_type *Ptr = nullptr;
379};
380
381} // namespace clang
382
383namespace llvm {
384
385template <typename decl_type>
386struct DenseMapInfo<clang::CanonicalDeclPtr<decl_type>> {
388 using BaseInfo = DenseMapInfo<decl_type *>;
389
391 // Construct our CanonicalDeclPtr this way because the regular constructor
392 // would dereference P.Ptr, which is not allowed.
394 P.Ptr = BaseInfo::getEmptyKey();
395 return P;
396 }
397
400 P.Ptr = BaseInfo::getTombstoneKey();
401 return P;
402 }
403
404 static unsigned getHashValue(const CanonicalDeclPtr &P) {
405 return BaseInfo::getHashValue(P);
406 }
407
408 static bool isEqual(const CanonicalDeclPtr &LHS,
409 const CanonicalDeclPtr &RHS) {
410 return BaseInfo::isEqual(LHS, RHS);
411 }
412};
413
414template <typename decl_type>
415struct PointerLikeTypeTraits<clang::CanonicalDeclPtr<decl_type>> {
417 return P.Ptr;
418 }
422 return C;
423 }
424 static constexpr int NumLowBitsAvailable =
426};
427
428} // namespace llvm
429
430#endif // LLVM_CLANG_AST_REDECLARABLE_H
StringRef P
const Decl * D
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 ...
Definition: ASTContext.h:187
A wrapper class around a pointer that always points to its canonical declaration.
Definition: Redeclarable.h:350
CanonicalDeclPtr(const CanonicalDeclPtr &)=default
const decl_type * operator->() const
Definition: Redeclarable.h:362
CanonicalDeclPtr & operator=(const CanonicalDeclPtr &)=default
const decl_type & operator*() const
Definition: Redeclarable.h:365
decl_type & operator*()
Definition: Redeclarable.h:364
CanonicalDeclPtr(decl_type *Ptr)
Definition: Redeclarable.h:353
decl_type * operator->()
Definition: Redeclarable.h:361
friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
Definition: Redeclarable.h:367
friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
Definition: Redeclarable.h:370
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
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...
Definition: Redeclarable.h:315
bool isFirstDecl() const
Returns true if this is the first declaration.
Definition: Redeclarable.h:338
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:330
Mergeable()=default
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:321
Iterates through all the redeclarations of the same decl.
Definition: Redeclarable.h:241
friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y)
Definition: Redeclarable.h:288
friend bool operator==(const redecl_iterator &x, const redecl_iterator &y)
Definition: Redeclarable.h:285
std::forward_iterator_tag iterator_category
Definition: Redeclarable.h:251
Provides common interface for the Decls that can be redeclared.
Definition: Redeclarable.h:84
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:217
const decl_type * getMostRecentDecl() const
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:232
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:221
decl_type * getNextRedeclaration() const
Definition: Redeclarable.h:189
Redeclarable(const ASTContext &Ctx)
Definition: Redeclarable.h:199
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:205
redecl_iterator redecls_end() const
Definition: Redeclarable.h:304
const decl_type * getPreviousDecl() const
Definition: Redeclarable.h:210
DeclLink RedeclLink
Points to the next redeclaration in the chain.
Definition: Redeclarable.h:185
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:293
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:227
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
Definition: Decl.h:4978
static DeclLink LatestDeclLink(const ASTContext &Ctx)
Definition: Redeclarable.h:170
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Definition: Redeclarable.h:224
redecl_iterator redecls_begin() const
Definition: Redeclarable.h:303
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:297
static DeclLink PreviousDeclLink(decl_type *D)
Definition: Redeclarable.h:166
@ 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.
Definition: Decl.cpp:77
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
A lazy value (of type T) that is within an AST node of type Owner, where the value might change in la...
void set(T NewValue)
Set the value of this pointer, in the current generation.
static unsigned getHashValue(const CanonicalDeclPtr &P)
Definition: Redeclarable.h:404
static bool isEqual(const CanonicalDeclPtr &LHS, const CanonicalDeclPtr &RHS)
Definition: Redeclarable.h:408
static void * getAsVoidPointer(clang::CanonicalDeclPtr< decl_type > P)
Definition: Redeclarable.h:416
static clang::CanonicalDeclPtr< decl_type > getFromVoidPointer(void *P)
Definition: Redeclarable.h:419