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