зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
401aa7b146
Коммит
c325e7f51b
|
@ -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));
|
||||
void StmtIteratorBase::NextDecl() {
|
||||
assert (FirstDecl && Ptr.D);
|
||||
|
||||
if (!D) S = NULL;
|
||||
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)
|
||||
ScopedDecl* d = FirstDecl;
|
||||
ScopedDecl* lastVD = d;
|
||||
|
||||
while (d->getNextDeclarator() != Ptr.D) {
|
||||
if (VarDecl* V = dyn_cast<VarDecl>(d))
|
||||
if (V->getInit())
|
||||
lastVD = d;
|
||||
|
||||
d = d->getNextDeclarator();
|
||||
|
||||
D = d;
|
||||
}
|
||||
|
||||
Stmt*& StmtIterator::GetInitializer() const {
|
||||
assert (D && isa<VarDecl>(D));
|
||||
assert (cast<VarDecl>(D)->Init);
|
||||
return reinterpret_cast<Stmt*&>(cast<VarDecl>(D)->Init);
|
||||
Ptr.D = lastVD;
|
||||
}
|
||||
|
||||
Stmt* StmtIteratorBase::GetInitializer() const {
|
||||
return cast<VarDecl>(Ptr.D)->getInit();
|
||||
}
|
||||
|
|
|
@ -21,79 +21,83 @@ 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) {}
|
||||
Stmt* GetInitializer() const;
|
||||
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
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; }
|
||||
bool operator!=(const DERIVED& RHS) const {
|
||||
return FirstDecl != RHS.FirstDecl || Ptr.S != RHS.Ptr.S;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче