13#ifndef LLVM_CLANG_AST_REDECLARABLE_H
14#define LLVM_CLANG_AST_REDECLARABLE_H
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"
83template<
typename decl_type>
96 using UninitializedLatest =
const void *;
103 using NotKnownLatest = llvm::PointerUnion<Previous, UninitializedLatest>;
105 mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Link;
112 : Link(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {}
116 return isa<KnownLatest>(Link) ||
119 isa<UninitializedLatest>(cast<NotKnownLatest>(Link));
123 if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
124 if (
auto *Prev = dyn_cast<Previous>(NKL))
125 return static_cast<decl_type *
>(Prev);
129 cast<UninitializedLatest>(NKL)),
130 const_cast<decl_type *
>(
D));
133 return static_cast<decl_type *
>(cast<KnownLatest>(Link).get(
D));
137 assert(!
isFirst() &&
"decl became non-canonical unexpectedly");
142 assert(
isFirst() &&
"decl became canonical unexpectedly");
143 if (NotKnownLatest NKL = dyn_cast<NotKnownLatest>(Link)) {
145 cast<UninitializedLatest>(NKL)),
148 auto Latest = cast<KnownLatest>(Link);
157 assert(
isFirst() &&
"expected a canonical decl");
158 if (isa<NotKnownLatest>(Link))
160 return cast<KnownLatest>(Link).getNotUpdated();
199 First(static_cast<decl_type *>(this)) {}
209 return const_cast<decl_type *
>(
210 static_cast<const decl_type*
>(
this))->getPreviousDecl();
241 decl_type *Current =
nullptr;
242 decl_type *Starter =
nullptr;
243 bool PassedFirst =
false;
259 assert(Current &&
"Advancing while iterator has reached end");
262 if (Current->isFirstDecl()) {
264 assert(0 &&
"Passed first decl twice, invalid redecl chain!");
272 decl_type *Next = Current->getNextRedeclaration();
273 Current = (Next != Starter) ? Next :
nullptr;
284 return x.Current == y.Current;
287 return x.Current != y.Current;
297 static_cast<const decl_type *
>(
this))),
312template<
typename decl_type>
320 auto *
D =
static_cast<decl_type *
>(
this);
321 if (!
D->isFromASTFile())
329 const auto *
D =
static_cast<const decl_type *
>(
this);
330 if (!
D->isFromASTFile())
356 operator decl_type *() {
return Ptr; }
357 operator const decl_type *()
const {
return Ptr; }
366 return LHS.Ptr == RHS.Ptr;
369 return LHS.Ptr != RHS.Ptr;
376 decl_type *Ptr =
nullptr;
383template <
typename decl_type>
392 P.Ptr = BaseInfo::getEmptyKey();
398 P.Ptr = BaseInfo::getTombstoneKey();
403 return BaseInfo::getHashValue(
P);
408 return BaseInfo::isEqual(LHS, RHS);
412template <
typename decl_type>
422 static constexpr int NumLowBitsAvailable =
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 ...
A wrapper class around a pointer that always points to its canonical declaration.
CanonicalDeclPtr(const CanonicalDeclPtr &)=default
const decl_type * operator->() const
CanonicalDeclPtr & operator=(const CanonicalDeclPtr &)=default
const decl_type & operator*() const
CanonicalDeclPtr(decl_type *Ptr)
friend bool operator==(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
CanonicalDeclPtr()=default
friend bool operator!=(CanonicalDeclPtr LHS, CanonicalDeclPtr RHS)
Decl - This represents one declaration (or definition), e.g.
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...
bool isFirstDecl() const
Returns true if this is the first declaration.
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
DeclLink(LatestTag, const ASTContext &Ctx)
DeclLink(PreviousTag, decl_type *D)
void setPrevious(decl_type *D)
Decl * getLatestNotUpdated() const
void setLatest(decl_type *D)
decl_type * getPrevious(const decl_type *D) const
Iterates through all the redeclarations of the same decl.
friend bool operator!=(const redecl_iterator &x, const redecl_iterator &y)
friend bool operator==(const redecl_iterator &x, const redecl_iterator &y)
redecl_iterator(decl_type *C)
redecl_iterator()=default
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
reference operator*() const
redecl_iterator operator++(int)
redecl_iterator & operator++()
pointer operator->() const
Provides common interface for the Decls that can be redeclared.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
const decl_type * getMostRecentDecl() const
Returns the most recent (re)declaration of this declaration.
const decl_type * getFirstDecl() const
Return the first declaration of this declaration or itself if this is the only declaration.
decl_type * getNextRedeclaration() const
Redeclarable(const ASTContext &Ctx)
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
redecl_iterator redecls_end() const
const decl_type * getPreviousDecl() const
DeclLink RedeclLink
Points to the next redeclaration in the chain.
llvm::iterator_range< redecl_iterator > redecl_range
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
static DeclLink LatestDeclLink(const ASTContext &Ctx)
bool isFirstDecl() const
True if this is the first declaration in its redeclaration chain.
redecl_iterator redecls_begin() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
static DeclLink PreviousDeclLink(decl_type *D)
@ 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.
Diagnostic wrappers for TextAPI types for error reporting.
A lazy value (of type T) that is within an AST node of type Owner, where the value might change in la...
static unsigned getHashValue(const CanonicalDeclPtr &P)
static bool isEqual(const CanonicalDeclPtr &LHS, const CanonicalDeclPtr &RHS)
static CanonicalDeclPtr getEmptyKey()
DenseMapInfo< decl_type * > BaseInfo
static CanonicalDeclPtr getTombstoneKey()
static void * getAsVoidPointer(clang::CanonicalDeclPtr< decl_type > P)
static clang::CanonicalDeclPtr< decl_type > getFromVoidPointer(void *P)