clang  3.9.0
Redeclarable.h
Go to the documentation of this file.
1 //===-- Redeclarable.h - Base for Decls that can be redeclared -*- C++ -*-====//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the Redeclarable interface.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_REDECLARABLE_H
15 #define LLVM_CLANG_AST_REDECLARABLE_H
16 
18 #include "llvm/ADT/PointerIntPair.h"
19 #include "llvm/Support/Casting.h"
20 #include <iterator>
21 
22 namespace clang {
23 class ASTContext;
24 
25 /// \brief Provides common interface for the Decls that can be redeclared.
26 template<typename decl_type>
27 class Redeclarable {
28 protected:
29  class DeclLink {
30  /// A pointer to a known latest declaration, either statically known or
31  /// generationally updated as decls are added by an external source.
32  typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
35 
36  /// We store a pointer to the ASTContext in the UninitializedLatest
37  /// pointer, but to avoid circular type dependencies when we steal the low
38  /// bits of this pointer, we use a raw void* here.
39  typedef const void *UninitializedLatest;
40 
41  typedef Decl *Previous;
42 
43  /// A pointer to either an uninitialized latest declaration (where either
44  /// we've not yet set the previous decl or there isn't one), or to a known
45  /// previous declaration.
46  typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
47 
48  mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
49 
50  public:
53 
55  : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
56  DeclLink(PreviousTag, decl_type *D)
57  : Next(NotKnownLatest(Previous(D))) {}
58 
59  bool NextIsPrevious() const {
60  return Next.is<NotKnownLatest>() &&
61  // FIXME: 'template' is required on the next line due to an
62  // apparent clang bug.
63  Next.get<NotKnownLatest>().template is<Previous>();
64  }
65 
66  bool NextIsLatest() const { return !NextIsPrevious(); }
67 
68  decl_type *getNext(const decl_type *D) const {
69  if (Next.is<NotKnownLatest>()) {
70  NotKnownLatest NKL = Next.get<NotKnownLatest>();
71  if (NKL.is<Previous>())
72  return static_cast<decl_type*>(NKL.get<Previous>());
73 
74  // Allocate the generational 'most recent' cache now, if needed.
75  Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
76  NKL.get<UninitializedLatest>()),
77  const_cast<decl_type *>(D));
78  }
79 
80  return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
81  }
82 
83  void setPrevious(decl_type *D) {
84  assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
85  Next = Previous(D);
86  }
87 
88  void setLatest(decl_type *D) {
89  assert(NextIsLatest() && "decl became canonical unexpectedly");
90  if (Next.is<NotKnownLatest>()) {
91  NotKnownLatest NKL = Next.get<NotKnownLatest>();
92  Next = KnownLatest(*reinterpret_cast<const ASTContext *>(
93  NKL.get<UninitializedLatest>()),
94  D);
95  } else {
96  auto Latest = Next.get<KnownLatest>();
97  Latest.set(D);
98  Next = Latest;
99  }
100  }
101 
102  void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
103 
105  assert(NextIsLatest() && "expected a canonical decl");
106  if (Next.is<NotKnownLatest>())
107  return nullptr;
108  return Next.get<KnownLatest>().getNotUpdated();
109  }
110  };
111 
112  static DeclLink PreviousDeclLink(decl_type *D) {
113  return DeclLink(DeclLink::PreviousLink, D);
114  }
115 
116  static DeclLink LatestDeclLink(const ASTContext &Ctx) {
117  return DeclLink(DeclLink::LatestLink, Ctx);
118  }
119 
120  /// \brief Points to the next redeclaration in the chain.
121  ///
122  /// If NextIsPrevious() is true, this is a link to the previous declaration
123  /// of this same Decl. If NextIsLatest() is true, this is the first
124  /// declaration and Link points to the latest declaration. For example:
125  ///
126  /// #1 int f(int x, int y = 1); // <pointer to #3, true>
127  /// #2 int f(int x = 0, int y); // <pointer to #1, false>
128  /// #3 int f(int x, int y) { return x + y; } // <pointer to #2, false>
129  ///
130  /// If there is only one declaration, it is <pointer to self, true>
131  DeclLink RedeclLink;
132  decl_type *First;
133 
134  decl_type *getNextRedeclaration() const {
135  return RedeclLink.getNext(static_cast<const decl_type *>(this));
136  }
137 
138 public:
140  : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {}
141 
142  /// \brief Return the previous declaration of this declaration or NULL if this
143  /// is the first declaration.
144  decl_type *getPreviousDecl() {
146  return getNextRedeclaration();
147  return nullptr;
148  }
149  const decl_type *getPreviousDecl() const {
150  return const_cast<decl_type *>(
151  static_cast<const decl_type*>(this))->getPreviousDecl();
152  }
153 
154  /// \brief Return the first declaration of this declaration or itself if this
155  /// is the only declaration.
156  decl_type *getFirstDecl() { return First; }
157 
158  /// \brief Return the first declaration of this declaration or itself if this
159  /// is the only declaration.
160  const decl_type *getFirstDecl() const { return First; }
161 
162  /// \brief True if this is the first declaration in its redeclaration chain.
163  bool isFirstDecl() const { return RedeclLink.NextIsLatest(); }
164 
165  /// \brief Returns the most recent (re)declaration of this declaration.
166  decl_type *getMostRecentDecl() {
167  return getFirstDecl()->getNextRedeclaration();
168  }
169 
170  /// \brief Returns the most recent (re)declaration of this declaration.
171  const decl_type *getMostRecentDecl() const {
172  return getFirstDecl()->getNextRedeclaration();
173  }
174 
175  /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
176  /// first and only declaration.
177  void setPreviousDecl(decl_type *PrevDecl);
178 
179  /// \brief Iterates through all the redeclarations of the same decl.
181  /// Current - The current declaration.
182  decl_type *Current;
183  decl_type *Starter;
184  bool PassedFirst;
185 
186  public:
187  typedef decl_type* value_type;
188  typedef decl_type* reference;
189  typedef decl_type* pointer;
190  typedef std::forward_iterator_tag iterator_category;
192 
193  redecl_iterator() : Current(nullptr) { }
194  explicit redecl_iterator(decl_type *C)
195  : Current(C), Starter(C), PassedFirst(false) { }
196 
197  reference operator*() const { return Current; }
198  pointer operator->() const { return Current; }
199 
201  assert(Current && "Advancing while iterator has reached end");
202  // Sanity check to avoid infinite loop on invalid redecl chain.
203  if (Current->isFirstDecl()) {
204  if (PassedFirst) {
205  assert(0 && "Passed first decl twice, invalid redecl chain!");
206  Current = nullptr;
207  return *this;
208  }
209  PassedFirst = true;
210  }
211 
212  // Get either previous decl or latest decl.
213  decl_type *Next = Current->getNextRedeclaration();
214  Current = (Next != Starter) ? Next : nullptr;
215  return *this;
216  }
217 
219  redecl_iterator tmp(*this);
220  ++(*this);
221  return tmp;
222  }
223 
225  return x.Current == y.Current;
226  }
228  return x.Current != y.Current;
229  }
230  };
231 
232  typedef llvm::iterator_range<redecl_iterator> redecl_range;
233 
234  /// \brief Returns an iterator range for all the redeclarations of the same
235  /// decl. It will iterate at least once (when this decl is the only one).
237  return redecl_range(redecl_iterator(const_cast<decl_type *>(
238  static_cast<const decl_type *>(this))),
239  redecl_iterator());
240  }
241 
242  redecl_iterator redecls_begin() const { return redecls().begin(); }
243  redecl_iterator redecls_end() const { return redecls().end(); }
244 
245  friend class ASTDeclReader;
246  friend class ASTDeclWriter;
247 };
248 
249 /// \brief Get the primary declaration for a declaration from an AST file. That
250 /// will be the first-loaded declaration.
252 
253 /// \brief Provides common interface for the Decls that cannot be redeclared,
254 /// but can be merged if the same declaration is brought in from multiple
255 /// modules.
256 template<typename decl_type>
257 class Mergeable {
258 public:
260 
261  /// \brief Return the first declaration of this declaration or itself if this
262  /// is the only declaration.
263  decl_type *getFirstDecl() {
264  decl_type *D = static_cast<decl_type*>(this);
265  if (!D->isFromASTFile())
266  return D;
267  return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
268  }
269 
270  /// \brief Return the first declaration of this declaration or itself if this
271  /// is the only declaration.
272  const decl_type *getFirstDecl() const {
273  const decl_type *D = static_cast<const decl_type*>(this);
274  if (!D->isFromASTFile())
275  return D;
276  return cast<decl_type>(getPrimaryMergedDecl(const_cast<decl_type*>(D)));
277  }
278 
279  /// \brief Returns true if this is the first declaration.
280  bool isFirstDecl() const { return getFirstDecl() == this; }
281 };
282 
283 }
284 
285 #endif
const decl_type * getPreviousDecl() const
Definition: Redeclarable.h:149
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
Definition: Decl.h:3818
virtual void CompleteRedeclChain(const Decl *D)
Gives the external AST source an opportunity to complete the redeclaration chain for a declaration...
bool isFirstDecl() const
Returns true if this is the first declaration.
Definition: Redeclarable.h:280
static DeclLink LatestDeclLink(const ASTContext &Ctx)
Definition: Redeclarable.h:116
Provides common interface for the Decls that can be redeclared.
Definition: Redeclarable.h:27
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
redecl_iterator redecls_begin() const
Definition: Redeclarable.h:242
friend bool operator==(redecl_iterator x, redecl_iterator y)
Definition: Redeclarable.h:224
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:272
decl_type * getNextRedeclaration() const
Definition: Redeclarable.h:134
DeclLink RedeclLink
Points to the next redeclaration in the chain.
Definition: Redeclarable.h:131
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:263
llvm::iterator_range< redecl_iterator > redecl_range
Definition: Redeclarable.h:232
Iterates through all the redeclarations of the same decl.
Definition: Redeclarable.h:180
friend class ASTContext
Definition: Type.h:4178
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:160
static DeclLink PreviousDeclLink(decl_type *D)
Definition: Redeclarable.h:112
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Definition: Redeclarable.h:163
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
Definition: Decl.cpp:39
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Definition: Redeclarable.h:156
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:236
#define false
Definition: stdbool.h:33
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Definition: Redeclarable.h:144
SmallVectorImpl< AnnotatedLine * >::const_iterator Next
Redeclarable(const ASTContext &Ctx)
Definition: Redeclarable.h:139
std::forward_iterator_tag iterator_category
Definition: Redeclarable.h:190
redecl_iterator redecls_end() const
Definition: Redeclarable.h:243
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
Definition: opencl-c.h:61
const decl_type * getMostRecentDecl() const
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:171
void set(T NewValue)
Set the value of this pointer, in the current generation.
Provides common interface for the Decls that cannot be redeclared, but can be merged if the same decl...
Definition: Redeclarable.h:257
friend bool operator!=(redecl_iterator x, redecl_iterator y)
Definition: Redeclarable.h:227
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:166
A lazy value (of type T) that is within an AST node of type Owner, where the value might change in la...