mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 07:26:07 +00:00
Introduce a redecl_iterator in Decl class, so that we can do a "iterate over all declarations of the same decl" without knowing the exact type.
llvm-svn: 76298
This commit is contained in:
parent
fad334ce5b
commit
05898da9cb
@ -259,7 +259,19 @@ protected:
|
|||||||
DeclaredInCondition(false), TypeSpecStartLoc(TSSL) {
|
DeclaredInCondition(false), TypeSpecStartLoc(TSSL) {
|
||||||
SClass = SC;
|
SClass = SC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef Redeclarable<VarDecl> redeclarable_base;
|
||||||
|
virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef redeclarable_base::redecl_iterator redecl_iterator;
|
||||||
|
redecl_iterator redecls_begin() const {
|
||||||
|
return redeclarable_base::redecls_begin();
|
||||||
|
}
|
||||||
|
redecl_iterator redecls_end() const {
|
||||||
|
return redeclarable_base::redecls_end();
|
||||||
|
}
|
||||||
|
|
||||||
static VarDecl *Create(ASTContext &C, DeclContext *DC,
|
static VarDecl *Create(ASTContext &C, DeclContext *DC,
|
||||||
SourceLocation L, IdentifierInfo *Id,
|
SourceLocation L, IdentifierInfo *Id,
|
||||||
QualType T, StorageClass S,
|
QualType T, StorageClass S,
|
||||||
@ -683,7 +695,18 @@ protected:
|
|||||||
virtual ~FunctionDecl() {}
|
virtual ~FunctionDecl() {}
|
||||||
virtual void Destroy(ASTContext& C);
|
virtual void Destroy(ASTContext& C);
|
||||||
|
|
||||||
|
typedef Redeclarable<FunctionDecl> redeclarable_base;
|
||||||
|
virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef redeclarable_base::redecl_iterator redecl_iterator;
|
||||||
|
redecl_iterator redecls_begin() const {
|
||||||
|
return redeclarable_base::redecls_begin();
|
||||||
|
}
|
||||||
|
redecl_iterator redecls_end() const {
|
||||||
|
return redeclarable_base::redecls_end();
|
||||||
|
}
|
||||||
|
|
||||||
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
|
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
|
||||||
DeclarationName N, QualType T,
|
DeclarationName N, QualType T,
|
||||||
StorageClass S = None, bool isInline = false,
|
StorageClass S = None, bool isInline = false,
|
||||||
|
@ -320,6 +320,62 @@ public:
|
|||||||
|
|
||||||
/// \brief Whether this particular Decl is a primary one.
|
/// \brief Whether this particular Decl is a primary one.
|
||||||
bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
|
bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// \brief Returns the next redeclaration or itself if this is the only decl.
|
||||||
|
///
|
||||||
|
/// Decl subclasses that can be redeclared should override this method so that
|
||||||
|
/// Decl::redecl_iterator can iterate over them.
|
||||||
|
virtual Decl *getNextRedeclaration() { return this; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// \brief Iterates through all the redeclarations of the same decl.
|
||||||
|
class redecl_iterator {
|
||||||
|
/// Current - The current declaration.
|
||||||
|
Decl *Current;
|
||||||
|
Decl *Starter;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef Decl* value_type;
|
||||||
|
typedef Decl* reference;
|
||||||
|
typedef Decl* pointer;
|
||||||
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
|
||||||
|
redecl_iterator() : Current(0) { }
|
||||||
|
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
|
||||||
|
|
||||||
|
reference operator*() const { return Current; }
|
||||||
|
pointer operator->() const { return Current; }
|
||||||
|
|
||||||
|
redecl_iterator& operator++() {
|
||||||
|
assert(Current && "Advancing while iterator has reached end");
|
||||||
|
// Get either previous decl or latest decl.
|
||||||
|
Decl *Next = Current->getNextRedeclaration();
|
||||||
|
Current = (Next != Starter ? Next : 0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
redecl_iterator operator++(int) {
|
||||||
|
redecl_iterator tmp(*this);
|
||||||
|
++(*this);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(redecl_iterator x, redecl_iterator y) {
|
||||||
|
return x.Current == y.Current;
|
||||||
|
}
|
||||||
|
friend bool operator!=(redecl_iterator x, redecl_iterator y) {
|
||||||
|
return x.Current != y.Current;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Returns iterator for all the redeclarations of the same decl.
|
||||||
|
/// It will iterate at least once (when this decl is the only one).
|
||||||
|
redecl_iterator redecls_begin() const {
|
||||||
|
return redecl_iterator(const_cast<Decl*>(this));
|
||||||
|
}
|
||||||
|
redecl_iterator redecls_end() const { return redecl_iterator(); }
|
||||||
|
|
||||||
/// getBody - If this Decl represents a declaration for a body of code,
|
/// getBody - If this Decl represents a declaration for a body of code,
|
||||||
/// such as a function or method definition, this method returns the
|
/// such as a function or method definition, this method returns the
|
||||||
|
@ -565,7 +565,7 @@ bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
|
|||||||
|
|
||||||
void
|
void
|
||||||
FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
|
FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
|
||||||
Redeclarable<FunctionDecl>::setPreviousDeclaration(PrevDecl);
|
redeclarable_base::setPreviousDeclaration(PrevDecl);
|
||||||
|
|
||||||
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
|
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
|
||||||
FunctionTemplateDecl *PrevFunTmpl
|
FunctionTemplateDecl *PrevFunTmpl
|
||||||
|
@ -133,16 +133,9 @@ static void ProcessDecl(Decl *D) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case PrintDecls :
|
case PrintDecls :
|
||||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
for (Decl::redecl_iterator I = D->redecls_begin(),
|
||||||
for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),
|
E = D->redecls_end(); I != E; ++I)
|
||||||
E = FD->redecls_end(); I != E; ++I)
|
ASTLocation(*I).print(OS);
|
||||||
ASTLocation(*I).print(OS);
|
|
||||||
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
|
|
||||||
for (VarDecl::redecl_iterator I = VD->redecls_begin(),
|
|
||||||
E = VD->redecls_end(); I != E; ++I)
|
|
||||||
ASTLocation(*I).print(OS);
|
|
||||||
} else
|
|
||||||
ASTLocation(D).print(OS);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user