14 #ifndef LLVM_CLANG_AST_REDECLARABLE_H
15 #define LLVM_CLANG_AST_REDECLARABLE_H
18 #include "llvm/Support/Casting.h"
79 template<
typename decl_type>
92 typedef const void *UninitializedLatest;
99 typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
101 mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
108 : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
110 : Next(NotKnownLatest(
Previous(D))) {}
113 return Next.is<NotKnownLatest>() &&
116 Next.get<NotKnownLatest>().template is<Previous>();
121 decl_type *
getNext(
const decl_type *D)
const {
122 if (Next.is<NotKnownLatest>()) {
123 NotKnownLatest NKL = Next.get<NotKnownLatest>();
125 return static_cast<decl_type*>(NKL.get<
Previous>());
128 Next =
KnownLatest(*reinterpret_cast<const ASTContext *>(
129 NKL.get<UninitializedLatest>()),
130 const_cast<decl_type *>(D));
133 return static_cast<decl_type*
>(Next.get<
KnownLatest>().
get(D));
137 assert(
NextIsPrevious() &&
"decl became non-canonical unexpectedly");
142 assert(
NextIsLatest() &&
"decl became canonical unexpectedly");
143 if (Next.is<NotKnownLatest>()) {
144 NotKnownLatest NKL = Next.get<NotKnownLatest>();
145 Next =
KnownLatest(*reinterpret_cast<const ASTContext *>(
146 NKL.get<UninitializedLatest>()),
159 if (Next.is<NotKnownLatest>())
203 return const_cast<decl_type *
>(
248 : Current(C), Starter(C), PassedFirst(
false) { }
254 assert(Current &&
"Advancing while iterator has reached end");
256 if (Current->isFirstDecl()) {
258 assert(0 &&
"Passed first decl twice, invalid redecl chain!");
266 decl_type *
Next = Current->getNextRedeclaration();
267 Current = (Next != Starter) ? Next :
nullptr;
278 return x.Current == y.Current;
281 return x.Current != y.Current;
290 return redecl_range(redecl_iterator(const_cast<decl_type *>(
291 static_cast<const decl_type *>(
this))),
309 template<
typename decl_type>
317 decl_type *D =
static_cast<decl_type*
>(
this);
318 if (!D->isFromASTFile())
326 const decl_type *D =
static_cast<const decl_type*
>(
this);
327 if (!D->isFromASTFile())
353 operator decl_type *() {
return Ptr; }
354 operator const decl_type *()
const {
return Ptr; }
370 template <
typename decl_type>
379 P.Ptr = BaseInfo::getEmptyKey();
385 P.Ptr = BaseInfo::getTombstoneKey();
390 return BaseInfo::getHashValue(P);
395 return BaseInfo::isEqual(LHS, RHS);
const decl_type * getPreviousDecl() const
static const Decl * getCanonicalDecl(const Decl *D)
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
Decl - This represents one declaration (or definition), e.g.
decl_type * getNext(const decl_type *D) const
static unsigned getHashValue(const CanonicalDeclPtr &P)
void setPrevious(decl_type *D)
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.
static DeclLink LatestDeclLink(const ASTContext &Ctx)
DeclLink(LatestTag, const ASTContext &Ctx)
Provides common interface for the Decls that can be redeclared.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
static bool isEqual(const CanonicalDeclPtr &LHS, const CanonicalDeclPtr &RHS)
bool NextIsPrevious() const
redecl_iterator redecls_begin() const
friend bool operator==(redecl_iterator x, redecl_iterator y)
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
DeclLink(PreviousTag, decl_type *D)
decl_type * getNextRedeclaration() const
DeclLink RedeclLink
Points to the next redeclaration in the chain.
reference operator*() const
const decl_type & operator*() const
pointer operator->() const
bool NextIsLatest() const
static CanonicalDeclPtr getEmptyKey()
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
llvm::iterator_range< redecl_iterator > redecl_range
CanonicalDeclPtr(decl_type *Ptr)
static CanonicalDeclPtr getTombstoneKey()
redecl_iterator operator++(int)
Iterates through all the redeclarations of the same decl.
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
static DeclLink PreviousDeclLink(decl_type *D)
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
Decl * getPrimaryMergedDecl(Decl *D)
Get the primary declaration for a declaration from an AST file.
std::ptrdiff_t difference_type
redecl_iterator & operator++()
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Redeclarable(const ASTContext &Ctx)
std::forward_iterator_tag iterator_category
redecl_iterator redecls_end() const
__PTRDIFF_TYPE__ ptrdiff_t
A signed integer type that is the result of subtracting two pointers.
const decl_type * getMostRecentDecl() const
Returns the most recent (re)declaration of this declaration.
const decl_type * operator->() const
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...
friend bool operator!=(redecl_iterator x, redecl_iterator y)
void setLatest(decl_type *D)
redecl_iterator(decl_type *C)
Decl * getLatestNotUpdated() const
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
A lazy value (of type T) that is within an AST node of type Owner, where the value might change in la...
A wrapper class around a pointer that always points to its canonical declaration. ...
CanonicalDeclPtr & operator=(const CanonicalDeclPtr &)=default