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 
25 namespace clang {
26 
27 class ASTContext;
28 class 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.
83 template<typename decl_type>
84 class Redeclarable {
85 protected:
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 
193 public:
194  friend class ASTDeclMerger;
195  friend class ASTDeclReader;
196  friend class ASTDeclWriter;
197  friend class IncrementalParser;
198 
200  : RedeclLink(LatestDeclLink(Ctx)),
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;
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))),
300  redecl_iterator());
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.
309 Decl *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.
314 template<typename decl_type>
315 class Mergeable {
316 public:
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.
350 template <typename decl_type> class CanonicalDeclPtr {
351 public:
352  CanonicalDeclPtr() = default;
353  CanonicalDeclPtr(decl_type *Ptr)
354  : Ptr(Ptr ? Ptr->getCanonicalDecl() : nullptr) {}
355  CanonicalDeclPtr(const CanonicalDeclPtr &) = default;
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 
374 private:
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 
383 namespace llvm {
384 
385 template <typename decl_type>
386 struct 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 
414 template <typename decl_type>
415 struct 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)
__PTRDIFF_TYPE__ ptrdiff_t
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 & operator=(const CanonicalDeclPtr &)=default
decl_type & operator*()
Definition: Redeclarable.h:364
CanonicalDeclPtr(const CanonicalDeclPtr &)=default
const decl_type & operator*() const
Definition: Redeclarable.h:365
const decl_type * operator->() const
Definition: Redeclarable.h:362
CanonicalDeclPtr(decl_type *Ptr)
Definition: Redeclarable.h:353
friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
Definition: Redeclarable.h:367
friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
Definition: Redeclarable.h:370
decl_type * operator->()
Definition: Redeclarable.h:361
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
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:321
Mergeable()=default
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
const decl_type * getMostRecentDecl() const
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:232
Redeclarable(const ASTContext &Ctx)
Definition: Redeclarable.h:199
redecl_iterator redecls_end() const
Definition: Redeclarable.h:304
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:227
DeclLink RedeclLink
Points to the next redeclaration in the chain.
Definition: Redeclarable.h:185
const decl_type * getPreviousDecl() const
Definition: Redeclarable.h:210
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:217
decl_type * getNextRedeclaration() const
Definition: Redeclarable.h:189
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:293
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
Definition: Decl.h:4979
static DeclLink LatestDeclLink(const ASTContext &Ctx)
Definition: Redeclarable.h:170
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 * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:205
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 clang::CanonicalDeclPtr< decl_type > getFromVoidPointer(void *P)
Definition: Redeclarable.h:419
static void * getAsVoidPointer(clang::CanonicalDeclPtr< decl_type > P)
Definition: Redeclarable.h:416