Modified StmtIterator to support iteration over the size expressions

of VariableTypeArray types that appear in DeclStmts.

Removed operator-- from StmtIterator.  operator-- added undesired
complexity, and we have no consumers of it.

llvm-svn: 43471
This commit is contained in:
Ted Kremenek 2007-10-29 20:50:16 +00:00
parent ae95d72a52
commit 2f70e71dcc
4 changed files with 106 additions and 100 deletions

View File

@ -17,63 +17,85 @@
using namespace clang;
static inline bool declHasExpr(ScopedDecl *decl) {
if (VarDecl* D = dyn_cast<VarDecl>(decl))
if (D->getInit())
return true;
if (EnumConstantDecl* D = dyn_cast<EnumConstantDecl>(decl))
if (D->getInitExpr())
return true;
return false;
}
void StmtIteratorBase::NextDecl() {
assert (FirstDecl && decl);
do decl = decl->getNextDeclarator();
while (decl != NULL && !declHasExpr(decl));
if (decl == NULL) FirstDecl = NULL;
}
StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) {
assert (d);
while (d != NULL && !declHasExpr(d))
d = d->getNextDeclarator();
FirstDecl = d;
decl = d;
}
void StmtIteratorBase::PrevDecl() {
assert (FirstDecl);
assert (decl != FirstDecl);
// March through the list of decls until we find the decl just before
// the one we currently point
ScopedDecl* d = FirstDecl;
ScopedDecl* lastVD = d;
while (d->getNextDeclarator() != decl) {
if (VarDecl* V = dyn_cast<VarDecl>(d))
if (V->getInit())
lastVD = d;
d = d->getNextDeclarator();
static inline VariableArrayType* FindVA(Type* t) {
while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
if (vat->getSizeExpr())
return vat;
t = vt->getElementType().getTypePtr();
}
decl = lastVD;
return NULL;
}
void StmtIteratorBase::NextVA() {
assert (getVAPtr());
VariableArrayType* p = getVAPtr();
p = FindVA(p->getElementType().getTypePtr());
setVAPtr(p);
if (!p) {
VarDecl* VD = cast<VarDecl>(decl);
if (!VD->Init)
NextDecl();
}
}
void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
assert (inDeclMode());
assert (getVAPtr() == NULL);
assert (decl);
if (ImmediateAdvance) {
decl = decl->getNextDeclarator();
if (!decl) {
RawVAPtr = 0;
return;
}
}
for ( ; decl ; decl = decl->getNextDeclarator()) {
if (!decl) {
RawVAPtr = 0;
return;
}
if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
setVAPtr(VAPtr);
return;
}
if (VD->getInit())
return;
}
else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(decl))
if (ECD->getInitExpr())
return;
}
}
StmtIteratorBase::StmtIteratorBase(ScopedDecl* d)
: decl(d), RawVAPtr(DeclMode) {
assert (decl);
NextDecl(false);
}
Stmt*& StmtIteratorBase::GetDeclExpr() const {
if (VarDecl* D = dyn_cast<VarDecl>(decl))
return reinterpret_cast<Stmt*&>(D->Init);
else {
EnumConstantDecl* Decl = cast<EnumConstantDecl>(decl);
return reinterpret_cast<Stmt*&>(Decl->Init);
if (VariableArrayType* VAPtr = getVAPtr()) {
assert (VAPtr->SizeExpr);
return reinterpret_cast<Stmt*&>(VAPtr->SizeExpr);
}
if (VarDecl* VD = dyn_cast<VarDecl>(decl)) {
assert (VD->Init);
return reinterpret_cast<Stmt*&>(VD->Init);
}
EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl);
return reinterpret_cast<Stmt*&>(ECD->Init);
}

View File

@ -100,12 +100,6 @@ public:
typedef StmtIterator child_iterator;
typedef ConstStmtIterator const_child_iterator;
typedef std::reverse_iterator<child_iterator>
reverse_child_iterator;
typedef std::reverse_iterator<const_child_iterator>
const_reverse_child_iterator;
virtual child_iterator child_begin() = 0;
virtual child_iterator child_end() = 0;
@ -116,22 +110,6 @@ public:
const_child_iterator child_end() const {
return const_child_iterator(const_cast<Stmt*>(this)->child_end());
}
reverse_child_iterator child_rbegin() {
return reverse_child_iterator(child_end());
}
reverse_child_iterator child_rend() {
return reverse_child_iterator(child_begin());
}
const_reverse_child_iterator child_rbegin() const {
return const_reverse_child_iterator(child_end());
}
const_reverse_child_iterator child_rend() const {
return const_reverse_child_iterator(child_begin());
}
};
/// DeclStmt - Adaptor class for mixing declarations with statements and

View File

@ -24,23 +24,37 @@ class VariableArrayType;
class StmtIteratorBase {
protected:
enum { DeclMode = 0x1 };
union { Stmt** stmt; ScopedDecl* decl; };
ScopedDecl* FirstDecl;
VariableArrayType* vat;
uintptr_t RawVAPtr;
bool inDeclMode() const {
return RawVAPtr & DeclMode ? true : false;
}
VariableArrayType* getVAPtr() const {
return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~DeclMode);
}
void setVAPtr(VariableArrayType* P) {
assert (inDeclMode());
RawVAPtr = reinterpret_cast<uintptr_t>(P) | DeclMode;
}
void NextDecl(bool ImmediateAdvance = true);
void NextVA();
void NextDecl();
void PrevDecl();
Stmt*& GetDeclExpr() const;
StmtIteratorBase(Stmt** s) : stmt(s), FirstDecl(NULL), vat(NULL) {}
StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {}
StmtIteratorBase(ScopedDecl* d);
StmtIteratorBase() : stmt(NULL), FirstDecl(NULL), vat(NULL) {}
StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {}
};
template <typename DERIVED, typename REFERENCE>
class StmtIteratorImpl : public StmtIteratorBase,
public std::iterator<std::bidirectional_iterator_tag,
public std::iterator<std::forward_iterator_tag,
REFERENCE, ptrdiff_t,
REFERENCE, REFERENCE> {
protected:
@ -51,8 +65,11 @@ public:
StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {}
DERIVED& operator++() {
if (FirstDecl) NextDecl();
DERIVED& operator++() {
if (inDeclMode()) {
if (getVAPtr()) NextVA();
else NextDecl();
}
else ++stmt;
return static_cast<DERIVED&>(*this);
@ -64,29 +81,16 @@ public:
return tmp;
}
DERIVED& operator--() {
if (FirstDecl) PrevDecl();
else --stmt;
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 && stmt == RHS.stmt;
return stmt == RHS.stmt && RawVAPtr == RHS.RawVAPtr;
}
bool operator!=(const DERIVED& RHS) const {
return FirstDecl != RHS.FirstDecl || stmt != RHS.stmt;
return stmt != RHS.stmt || RawVAPtr != RHS.RawVAPtr;
}
REFERENCE operator*() const {
return (REFERENCE) (FirstDecl ? GetDeclExpr() : *stmt);
return (REFERENCE) (inDeclMode() ? GetDeclExpr() : *stmt);
}
REFERENCE operator->() const { return operator*(); }

View File

@ -49,6 +49,7 @@ namespace clang {
class OCUVectorType;
class BuiltinType;
class ObjcQualifiedInterfaceType;
class StmtIteratorBase;
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
@ -589,6 +590,7 @@ public:
}
static bool classof(const VariableArrayType *) { return true; }
friend class StmtIteratorBase;
// FIXME: Who owns VariableArrayType's? What are the semantics
// for serialization.
};