1 //===--- StmtIterator.h - Iterators for Statements ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the StmtIterator and ConstStmtIterator classes.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_STMT_ITR_H
15 #define LLVM_CLANG_AST_STMT_ITR_H
17 #include "llvm/System/DataTypes.h"
26 class VariableArrayType;
28 class StmtIteratorBase {
30 enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
34 union { Decl *decl; Decl **DGI; };
39 return (RawVAPtr & Flags) == DeclMode;
42 bool inDeclGroup() const {
43 return (RawVAPtr & Flags) == DeclGroupMode;
46 bool inSizeOfTypeVA() const {
47 return (RawVAPtr & Flags) == SizeOfTypeVAMode;
51 return (RawVAPtr & Flags) == 0;
54 VariableArrayType* getVAPtr() const {
55 return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags);
58 void setVAPtr(VariableArrayType* P) {
59 assert (inDecl() || inDeclGroup() || inSizeOfTypeVA());
60 RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
63 void NextDecl(bool ImmediateAdvance = true);
64 bool HandleDecl(Decl* D);
67 Stmt*& GetDeclExpr() const;
69 StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {}
70 StmtIteratorBase(Decl *d, Stmt **s);
71 StmtIteratorBase(VariableArrayType *t);
72 StmtIteratorBase(Decl **dgi, Decl **dge);
73 StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {}
77 template <typename DERIVED, typename REFERENCE>
78 class StmtIteratorImpl : public StmtIteratorBase,
79 public std::iterator<std::forward_iterator_tag,
81 REFERENCE, REFERENCE> {
83 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
86 StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
87 StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
88 StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {}
89 StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {}
91 DERIVED& operator++() {
92 if (inDecl() || inDeclGroup()) {
93 if (getVAPtr()) NextVA();
96 else if (inSizeOfTypeVA())
101 return static_cast<DERIVED&>(*this);
104 DERIVED operator++(int) {
105 DERIVED tmp = static_cast<DERIVED&>(*this);
110 bool operator==(const DERIVED& RHS) const {
111 return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr;
114 bool operator!=(const DERIVED& RHS) const {
115 return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr;
118 REFERENCE operator*() const {
119 return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
122 REFERENCE operator->() const { return operator*(); }
125 struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
126 explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
128 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
130 StmtIterator(Decl** dgi, Decl** dge)
131 : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
133 StmtIterator(VariableArrayType* t)
134 : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
136 StmtIterator(Decl* D, Stmt **s = 0)
137 : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {}
140 struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
142 explicit ConstStmtIterator() :
143 StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
145 ConstStmtIterator(const StmtIterator& RHS) :
146 StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
149 } // end namespace clang