forked from OSchip/llvm-project
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) {
|
||||
SClass = SC;
|
||||
}
|
||||
|
||||
typedef Redeclarable<VarDecl> redeclarable_base;
|
||||
virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
|
||||
|
||||
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,
|
||||
SourceLocation L, IdentifierInfo *Id,
|
||||
QualType T, StorageClass S,
|
||||
|
@ -683,7 +695,18 @@ protected:
|
|||
virtual ~FunctionDecl() {}
|
||||
virtual void Destroy(ASTContext& C);
|
||||
|
||||
typedef Redeclarable<FunctionDecl> redeclarable_base;
|
||||
virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
|
||||
|
||||
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,
|
||||
DeclarationName N, QualType T,
|
||||
StorageClass S = None, bool isInline = false,
|
||||
|
|
|
@ -320,6 +320,62 @@ public:
|
|||
|
||||
/// \brief Whether this particular Decl is a primary one.
|
||||
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,
|
||||
/// such as a function or method definition, this method returns the
|
||||
|
|
|
@ -565,7 +565,7 @@ bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
|
|||
|
||||
void
|
||||
FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
|
||||
Redeclarable<FunctionDecl>::setPreviousDeclaration(PrevDecl);
|
||||
redeclarable_base::setPreviousDeclaration(PrevDecl);
|
||||
|
||||
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
|
||||
FunctionTemplateDecl *PrevFunTmpl
|
||||
|
|
|
@ -133,16 +133,9 @@ static void ProcessDecl(Decl *D) {
|
|||
}
|
||||
|
||||
case PrintDecls :
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),
|
||||
E = FD->redecls_end(); I != E; ++I)
|
||||
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);
|
||||
for (Decl::redecl_iterator I = D->redecls_begin(),
|
||||
E = D->redecls_end(); I != E; ++I)
|
||||
ASTLocation(*I).print(OS);
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue