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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43138 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2007-10-18 18:19:31 +00:00
Родитель 401aa7b146
Коммит c325e7f51b
2 изменённых файлов: 96 добавлений и 78 удалений

Просмотреть файл

@ -12,39 +12,53 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/StmtIterator.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Decl.h"
using namespace clang;
void StmtIterator::NextDecl() {
assert (D);
do D = D->getNextDeclarator();
while (D != NULL && !isa<VarDecl>(D));
if (!D) S = NULL;
void StmtIteratorBase::NextDecl() {
assert (FirstDecl && Ptr.D);
do Ptr.D = Ptr.D->getNextDeclarator();
while (Ptr.D != NULL && !isa<VarDecl>(Ptr.D));
}
void StmtIterator::PrevDecl() {
assert (isa<DeclStmt>(*S));
DeclStmt* DS = cast<DeclStmt>(*S);
ScopedDecl* d = DS->getDecl();
StmtIteratorBase::StmtIteratorBase(ScopedDecl* 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
// the one we currently point
while (d->getNextDeclarator() != D)
d = d->getNextDeclarator();
ScopedDecl* d = FirstDecl;
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 {
assert (D && isa<VarDecl>(D));
assert (cast<VarDecl>(D)->Init);
return reinterpret_cast<Stmt*&>(cast<VarDecl>(D)->Init);
Stmt* StmtIteratorBase::GetInitializer() const {
return cast<VarDecl>(Ptr.D)->getInit();
}

Просмотреть файл

@ -20,82 +20,86 @@ namespace clang {
class Stmt;
class ScopedDecl;
class StmtIterator : public bidirectional_iterator<Stmt*, ptrdiff_t> {
Stmt** S;
ScopedDecl* D;
class StmtIteratorBase {
protected:
union { Stmt** S; ScopedDecl* D; } Ptr;
ScopedDecl* FirstDecl;
void NextDecl();
void PrevDecl();
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; }
Stmt* GetInitializer() const;
bool operator==(const StmtIterator& RHS) const {
return D == RHS.D && S == RHS.S;
}
bool operator!=(const StmtIterator& RHS) const {
return D != RHS.D || S != RHS.S;
}
StmtIteratorBase(Stmt** s) : FirstDecl(NULL) { Ptr.S = s; }
StmtIteratorBase(ScopedDecl* d);
StmtIteratorBase() : FirstDecl(NULL) { Ptr.S = NULL; }
};
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:
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; }
ConstStmtIterator operator++(int) {
ConstStmtIterator tmp = *this;
DERIVED& operator++() {
if (FirstDecl) NextDecl();
else ++Ptr.S;
return static_cast<DERIVED&>(*this);
}
DERIVED operator++(int) {
DERIVED tmp = static_cast<DERIVED&>(*this);
operator++();
return tmp;
}
ConstStmtIterator operator--(int) {
ConstStmtIterator tmp = *this;
DERIVED& operator--() {
if (FirstDecl) PrevDecl();
else --Ptr.S;
return static_cast<DERIVED&>(*this);
}
DERIVED operator--(int) {
DERIVED tmp = static_cast<DERIVED&>(*this);
operator--();
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); }
pointer operator->() const { return const_cast<pointer>(I.operator->()); }
bool operator!=(const DERIVED& RHS) const {
return FirstDecl != RHS.FirstDecl || Ptr.S != RHS.Ptr.S;
}
bool operator==(const ConstStmtIterator& RHS) const { return I == RHS.I; }
bool operator!=(const ConstStmtIterator& RHS) const { return I != RHS.I; }
STMT_PTR operator*() const {
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
#endif