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:
parent
ae95d72a52
commit
2f70e71dcc
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*(); }
|
||||
|
|
|
@ -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.
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue