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;
|
using namespace clang;
|
||||||
|
|
||||||
static inline bool declHasExpr(ScopedDecl *decl) {
|
static inline VariableArrayType* FindVA(Type* t) {
|
||||||
if (VarDecl* D = dyn_cast<VarDecl>(decl))
|
while (ArrayType* vt = dyn_cast<ArrayType>(t)) {
|
||||||
if (D->getInit())
|
if (VariableArrayType* vat = dyn_cast<VariableArrayType>(vt))
|
||||||
return true;
|
if (vat->getSizeExpr())
|
||||||
|
return vat;
|
||||||
if (EnumConstantDecl* D = dyn_cast<EnumConstantDecl>(decl))
|
|
||||||
if (D->getInitExpr())
|
t = vt->getElementType().getTypePtr();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
Stmt*& StmtIteratorBase::GetDeclExpr() const {
|
||||||
if (VarDecl* D = dyn_cast<VarDecl>(decl))
|
if (VariableArrayType* VAPtr = getVAPtr()) {
|
||||||
return reinterpret_cast<Stmt*&>(D->Init);
|
assert (VAPtr->SizeExpr);
|
||||||
else {
|
return reinterpret_cast<Stmt*&>(VAPtr->SizeExpr);
|
||||||
EnumConstantDecl* Decl = cast<EnumConstantDecl>(decl);
|
|
||||||
return reinterpret_cast<Stmt*&>(Decl->Init);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 StmtIterator child_iterator;
|
||||||
typedef ConstStmtIterator const_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_begin() = 0;
|
||||||
virtual child_iterator child_end() = 0;
|
virtual child_iterator child_end() = 0;
|
||||||
|
|
||||||
|
@ -116,22 +110,6 @@ public:
|
||||||
const_child_iterator child_end() const {
|
const_child_iterator child_end() const {
|
||||||
return const_child_iterator(const_cast<Stmt*>(this)->child_end());
|
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
|
/// DeclStmt - Adaptor class for mixing declarations with statements and
|
||||||
|
|
|
@ -24,23 +24,37 @@ class VariableArrayType;
|
||||||
|
|
||||||
class StmtIteratorBase {
|
class StmtIteratorBase {
|
||||||
protected:
|
protected:
|
||||||
|
enum { DeclMode = 0x1 };
|
||||||
union { Stmt** stmt; ScopedDecl* decl; };
|
union { Stmt** stmt; ScopedDecl* decl; };
|
||||||
ScopedDecl* FirstDecl;
|
uintptr_t RawVAPtr;
|
||||||
VariableArrayType* vat;
|
|
||||||
|
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;
|
Stmt*& GetDeclExpr() const;
|
||||||
|
|
||||||
StmtIteratorBase(Stmt** s) : stmt(s), FirstDecl(NULL), vat(NULL) {}
|
StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {}
|
||||||
StmtIteratorBase(ScopedDecl* d);
|
StmtIteratorBase(ScopedDecl* d);
|
||||||
StmtIteratorBase() : stmt(NULL), FirstDecl(NULL), vat(NULL) {}
|
StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename DERIVED, typename REFERENCE>
|
template <typename DERIVED, typename REFERENCE>
|
||||||
class StmtIteratorImpl : public StmtIteratorBase,
|
class StmtIteratorImpl : public StmtIteratorBase,
|
||||||
public std::iterator<std::bidirectional_iterator_tag,
|
public std::iterator<std::forward_iterator_tag,
|
||||||
REFERENCE, ptrdiff_t,
|
REFERENCE, ptrdiff_t,
|
||||||
REFERENCE, REFERENCE> {
|
REFERENCE, REFERENCE> {
|
||||||
protected:
|
protected:
|
||||||
|
@ -51,8 +65,11 @@ public:
|
||||||
StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {}
|
StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {}
|
||||||
|
|
||||||
|
|
||||||
DERIVED& operator++() {
|
DERIVED& operator++() {
|
||||||
if (FirstDecl) NextDecl();
|
if (inDeclMode()) {
|
||||||
|
if (getVAPtr()) NextVA();
|
||||||
|
else NextDecl();
|
||||||
|
}
|
||||||
else ++stmt;
|
else ++stmt;
|
||||||
|
|
||||||
return static_cast<DERIVED&>(*this);
|
return static_cast<DERIVED&>(*this);
|
||||||
|
@ -64,29 +81,16 @@ public:
|
||||||
return tmp;
|
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 {
|
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 {
|
bool operator!=(const DERIVED& RHS) const {
|
||||||
return FirstDecl != RHS.FirstDecl || stmt != RHS.stmt;
|
return stmt != RHS.stmt || RawVAPtr != RHS.RawVAPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
REFERENCE operator*() const {
|
REFERENCE operator*() const {
|
||||||
return (REFERENCE) (FirstDecl ? GetDeclExpr() : *stmt);
|
return (REFERENCE) (inDeclMode() ? GetDeclExpr() : *stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
REFERENCE operator->() const { return operator*(); }
|
REFERENCE operator->() const { return operator*(); }
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace clang {
|
||||||
class OCUVectorType;
|
class OCUVectorType;
|
||||||
class BuiltinType;
|
class BuiltinType;
|
||||||
class ObjcQualifiedInterfaceType;
|
class ObjcQualifiedInterfaceType;
|
||||||
|
class StmtIteratorBase;
|
||||||
|
|
||||||
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
|
/// 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
|
/// their own: instead each reference to a type stores the qualifiers. This
|
||||||
|
@ -589,6 +590,7 @@ public:
|
||||||
}
|
}
|
||||||
static bool classof(const VariableArrayType *) { return true; }
|
static bool classof(const VariableArrayType *) { return true; }
|
||||||
|
|
||||||
|
friend class StmtIteratorBase;
|
||||||
// FIXME: Who owns VariableArrayType's? What are the semantics
|
// FIXME: Who owns VariableArrayType's? What are the semantics
|
||||||
// for serialization.
|
// for serialization.
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue