Refactored StmtIterator into classes StmtIteratorBase (non-templated)

and StmtIteratorImpl (templated), which StmtIterator and
ConstStmtIterator now succintly subclass.

Implemented iteration over the initializers in DeclStmts.  This is not
thoroughly tested, so there may be bugs.

llvm-svn: 43138
This commit is contained in:
Ted Kremenek 2007-10-18 18:19:31 +00:00
parent 614d84aab3
commit 2ba761c7b8
2 changed files with 96 additions and 78 deletions

View File

@ -12,39 +12,53 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "clang/AST/StmtIterator.h" #include "clang/AST/StmtIterator.h"
#include "clang/AST/Stmt.h" #include "clang/AST/Expr.h"
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
using namespace clang; using namespace clang;
void StmtIterator::NextDecl() { void StmtIteratorBase::NextDecl() {
assert (D); assert (FirstDecl && Ptr.D);
do D = D->getNextDeclarator();
while (D != NULL && !isa<VarDecl>(D)); do Ptr.D = Ptr.D->getNextDeclarator();
while (Ptr.D != NULL && !isa<VarDecl>(Ptr.D));
if (!D) S = NULL;
} }
void StmtIterator::PrevDecl() { StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) {
assert (isa<DeclStmt>(*S));
DeclStmt* DS = cast<DeclStmt>(*S);
ScopedDecl* d = DS->getDecl();
assert (d); assert (d);
if (d == D) { assert(false) ; return; } while (d != NULL) {
if (VarDecl* V = dyn_cast<VarDecl>(d))
if (V->getInit()) break;
d = d->getNextDeclarator();
}
FirstDecl = d;
Ptr.D = d;
}
void StmtIteratorBase::PrevDecl() {
assert (FirstDecl);
assert (Ptr.D != FirstDecl);
// March through the list of decls until we find the decl just before // March through the list of decls until we find the decl just before
// the one we currently point // the one we currently point
while (d->getNextDeclarator() != D) ScopedDecl* d = FirstDecl;
d = d->getNextDeclarator(); ScopedDecl* lastVD = d;
D = d; while (d->getNextDeclarator() != Ptr.D) {
if (VarDecl* V = dyn_cast<VarDecl>(d))
if (V->getInit())
lastVD = d;
d = d->getNextDeclarator();
}
Ptr.D = lastVD;
} }
Stmt*& StmtIterator::GetInitializer() const { Stmt* StmtIteratorBase::GetInitializer() const {
assert (D && isa<VarDecl>(D)); return cast<VarDecl>(Ptr.D)->getInit();
assert (cast<VarDecl>(D)->Init);
return reinterpret_cast<Stmt*&>(cast<VarDecl>(D)->Init);
} }

View File

@ -20,82 +20,86 @@ namespace clang {
class Stmt; class Stmt;
class ScopedDecl; class ScopedDecl;
class StmtIterator : public bidirectional_iterator<Stmt*, ptrdiff_t> { class StmtIteratorBase {
Stmt** S; protected:
ScopedDecl* D; union { Stmt** S; ScopedDecl* D; } Ptr;
ScopedDecl* FirstDecl;
void NextDecl(); void NextDecl();
void PrevDecl(); void PrevDecl();
Stmt*& GetInitializer() const; Stmt* GetInitializer() const;
public:
StmtIterator(Stmt** s, ScopedDecl* d = NULL) : S(s), D(d) {}
StmtIterator& operator++() {
if (D) NextDecl();
else ++S;
return *this;
}
StmtIterator operator++(int) {
StmtIterator tmp = *this;
operator++();
return tmp;
}
StmtIterator& operator--() {
if (D) PrevDecl();
else --S;
return *this;
}
StmtIterator operator--(int) {
StmtIterator tmp = *this;
operator--();
return tmp;
}
reference operator*() const { return D ? GetInitializer() : *S; }
pointer operator->() const { return D ? &GetInitializer() : S; }
bool operator==(const StmtIterator& RHS) const { StmtIteratorBase(Stmt** s) : FirstDecl(NULL) { Ptr.S = s; }
return D == RHS.D && S == RHS.S; StmtIteratorBase(ScopedDecl* d);
} StmtIteratorBase() : FirstDecl(NULL) { Ptr.S = NULL; }
bool operator!=(const StmtIterator& RHS) const {
return D != RHS.D || S != RHS.S;
}
}; };
class ConstStmtIterator: public bidirectional_iterator<const Stmt*, ptrdiff_t> {
StmtIterator I; template <typename DERIVED, typename STMT_PTR>
class StmtIteratorImpl : public StmtIteratorBase,
public std::iterator<std::bidirectional_iterator_tag,
STMT_PTR, ptrdiff_t,
STMT_PTR, STMT_PTR> {
protected:
StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
public: public:
explicit ConstStmtIterator(const StmtIterator& i) : I(i) {} StmtIteratorImpl() {}
StmtIteratorImpl(Stmt** s) : StmtIteratorBase(s) {}
StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {}
ConstStmtIterator& operator++() { ++I; return *this; }
ConstStmtIterator& operator--() { --I; return *this; } DERIVED& operator++() {
if (FirstDecl) NextDecl();
ConstStmtIterator operator++(int) { else ++Ptr.S;
ConstStmtIterator tmp = *this;
return static_cast<DERIVED&>(*this);
}
DERIVED operator++(int) {
DERIVED tmp = static_cast<DERIVED&>(*this);
operator++(); operator++();
return tmp; return tmp;
} }
ConstStmtIterator operator--(int) { DERIVED& operator--() {
ConstStmtIterator tmp = *this; if (FirstDecl) PrevDecl();
else --Ptr.S;
return static_cast<DERIVED&>(*this);
}
DERIVED operator--(int) {
DERIVED tmp = static_cast<DERIVED&>(*this);
operator--(); operator--();
return tmp; return tmp;
} }
bool operator==(const DERIVED& RHS) const {
return FirstDecl == RHS.FirstDecl && Ptr.S == RHS.Ptr.S;
}
reference operator*() const { return const_cast<reference>(*I); } bool operator!=(const DERIVED& RHS) const {
pointer operator->() const { return const_cast<pointer>(I.operator->()); } return FirstDecl != RHS.FirstDecl || Ptr.S != RHS.Ptr.S;
}
bool operator==(const ConstStmtIterator& RHS) const { return I == RHS.I; } STMT_PTR operator*() const {
bool operator!=(const ConstStmtIterator& RHS) const { return I != RHS.I; } return (STMT_PTR) (FirstDecl ? GetInitializer() : *Ptr.S);
}
STMT_PTR operator->() const { return operator*(); }
}; };
struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*> {
StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*>(S) {}
};
struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
const Stmt*> {
ConstStmtIterator(const StmtIterator& RHS) :
StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
};
} // end namespace clang } // end namespace clang
#endif #endif