From: Ted Kremenek Date: Mon, 29 Oct 2007 20:50:16 +0000 (+0000) Subject: Modified StmtIterator to support iteration over the size expressions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92866e2e90f6d93fb95e25a7ac4438e239d89ce6;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43471 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/StmtIterator.cpp b/AST/StmtIterator.cpp index 7a516a781f..9db5f6134f 100644 --- a/AST/StmtIterator.cpp +++ b/AST/StmtIterator.cpp @@ -17,63 +17,85 @@ using namespace clang; -static inline bool declHasExpr(ScopedDecl *decl) { - if (VarDecl* D = dyn_cast(decl)) - if (D->getInit()) - return true; - - if (EnumConstantDecl* D = dyn_cast(decl)) - if (D->getInitExpr()) - return true; +static inline VariableArrayType* FindVA(Type* t) { + while (ArrayType* vt = dyn_cast(t)) { + if (VariableArrayType* vat = dyn_cast(vt)) + if (vat->getSizeExpr()) + return vat; + + t = vt->getElementType().getTypePtr(); + } - return false; + return NULL; } -void StmtIteratorBase::NextDecl() { - assert (FirstDecl && decl); +void StmtIteratorBase::NextVA() { + assert (getVAPtr()); - do decl = decl->getNextDeclarator(); - while (decl != NULL && !declHasExpr(decl)); - - if (decl == NULL) FirstDecl = NULL; -} + VariableArrayType* p = getVAPtr(); + p = FindVA(p->getElementType().getTypePtr()); + setVAPtr(p); -StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) { - assert (d); - - while (d != NULL && !declHasExpr(d)) - d = d->getNextDeclarator(); - - FirstDecl = d; - decl = d; + if (!p) { + VarDecl* VD = cast(decl); + + if (!VD->Init) + NextDecl(); + } } -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 +void StmtIteratorBase::NextDecl(bool ImmediateAdvance) { + assert (inDeclMode()); + assert (getVAPtr() == NULL); + assert (decl); - ScopedDecl* d = FirstDecl; - ScopedDecl* lastVD = d; + if (ImmediateAdvance) { + decl = decl->getNextDeclarator(); + + if (!decl) { + RawVAPtr = 0; + return; + } + } - while (d->getNextDeclarator() != decl) { - if (VarDecl* V = dyn_cast(d)) - if (V->getInit()) - lastVD = d; + for ( ; decl ; decl = decl->getNextDeclarator()) { + if (!decl) { + RawVAPtr = 0; + return; + } - d = d->getNextDeclarator(); + if (VarDecl* VD = dyn_cast(decl)) { + if (VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) { + setVAPtr(VAPtr); + return; + } + + if (VD->getInit()) + return; + } + else if (EnumConstantDecl* ECD = dyn_cast(decl)) + if (ECD->getInitExpr()) + return; } - - decl = lastVD; +} + +StmtIteratorBase::StmtIteratorBase(ScopedDecl* d) + : decl(d), RawVAPtr(DeclMode) { + assert (decl); + NextDecl(false); } Stmt*& StmtIteratorBase::GetDeclExpr() const { - if (VarDecl* D = dyn_cast(decl)) - return reinterpret_cast(D->Init); - else { - EnumConstantDecl* Decl = cast(decl); - return reinterpret_cast(Decl->Init); + if (VariableArrayType* VAPtr = getVAPtr()) { + assert (VAPtr->SizeExpr); + return reinterpret_cast(VAPtr->SizeExpr); } + + if (VarDecl* VD = dyn_cast(decl)) { + assert (VD->Init); + return reinterpret_cast(VD->Init); + } + + EnumConstantDecl* ECD = cast(decl); + return reinterpret_cast(ECD->Init); } diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 5f4c0d39c5..93f6850977 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -100,12 +100,6 @@ public: typedef StmtIterator child_iterator; typedef ConstStmtIterator const_child_iterator; - typedef std::reverse_iterator - reverse_child_iterator; - - typedef std::reverse_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(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 diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h index 714c3bd058..295db7fa50 100644 --- a/include/clang/AST/StmtIterator.h +++ b/include/clang/AST/StmtIterator.h @@ -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(RawVAPtr & ~DeclMode); + } + + void setVAPtr(VariableArrayType* P) { + assert (inDeclMode()); + RawVAPtr = reinterpret_cast(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 class StmtIteratorImpl : public StmtIteratorBase, - public std::iterator { 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(*this); @@ -64,29 +81,16 @@ public: return tmp; } - DERIVED& operator--() { - if (FirstDecl) PrevDecl(); - else --stmt; - - return static_cast(*this); - } - - DERIVED operator--(int) { - DERIVED tmp = static_cast(*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*(); } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 3a99e2b484..3140901b7e 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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. };