1 //===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===//
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/Support/DataTypes.h"
18 #include "llvm/Support/Compiler.h"
28 class VariableArrayType;
30 class StmtIteratorBase {
32 enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
40 bool inDeclGroup() const {
41 return (RawVAPtr & Flags) == DeclGroupMode;
44 bool inSizeOfTypeVA() const {
45 return (RawVAPtr & Flags) == SizeOfTypeVAMode;
49 return (RawVAPtr & Flags) == StmtMode;
52 const VariableArrayType *getVAPtr() const {
53 return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
56 void setVAPtr(const VariableArrayType *P) {
57 assert (inDeclGroup() || inSizeOfTypeVA());
58 RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
61 void NextDecl(bool ImmediateAdvance = true);
62 bool HandleDecl(Decl* D);
65 Stmt*& GetDeclExpr() const;
67 StmtIteratorBase(Stmt **s) : stmt(s), DGI(0), RawVAPtr(0) {}
68 StmtIteratorBase(const VariableArrayType *t);
69 StmtIteratorBase(Decl **dgi, Decl **dge);
70 StmtIteratorBase() : stmt(0), DGI(0), RawVAPtr(0) {}
74 template <typename DERIVED, typename REFERENCE>
75 class StmtIteratorImpl : public StmtIteratorBase,
76 public std::iterator<std::forward_iterator_tag,
78 REFERENCE, REFERENCE> {
80 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
83 StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
84 StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
85 StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
87 DERIVED& operator++() {
95 return static_cast<DERIVED&>(*this);
98 DERIVED operator++(int) {
99 DERIVED tmp = static_cast<DERIVED&>(*this);
104 bool operator==(const DERIVED& RHS) const {
105 return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
108 bool operator!=(const DERIVED& RHS) const {
109 return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
112 REFERENCE operator*() const {
113 return inStmt() ? *stmt : GetDeclExpr();
116 REFERENCE operator->() const { return operator*(); }
119 struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
120 explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
122 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
124 StmtIterator(Decl** dgi, Decl** dge)
125 : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
127 StmtIterator(const VariableArrayType *t)
128 : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
131 struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
133 explicit ConstStmtIterator() :
134 StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
136 ConstStmtIterator(const StmtIterator& RHS) :
137 StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
140 /// A range of statement iterators.
142 /// This class provides some extra functionality beyond std::pair
143 /// in order to allow the following idiom:
144 /// for (StmtRange range = stmt->children(); range; ++range)
145 struct StmtRange : std::pair<StmtIterator,StmtIterator> {
147 StmtRange(const StmtIterator &begin, const StmtIterator &end)
148 : std::pair<StmtIterator,StmtIterator>(begin, end) {}
150 bool empty() const { return first == second; }
151 LLVM_EXPLICIT operator bool() const { return !empty(); }
153 Stmt *operator->() const { return first.operator->(); }
154 Stmt *&operator*() const { return first.operator*(); }
156 StmtRange &operator++() {
157 assert(!empty() && "incrementing on empty range");
162 StmtRange operator++(int) {
163 assert(!empty() && "incrementing on empty range");
164 StmtRange copy = *this;
169 friend const StmtIterator &begin(const StmtRange &range) {
172 friend const StmtIterator &end(const StmtRange &range) {
177 /// A range of const statement iterators.
179 /// This class provides some extra functionality beyond std::pair
180 /// in order to allow the following idiom:
181 /// for (ConstStmtRange range = stmt->children(); range; ++range)
182 struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> {
184 ConstStmtRange(const ConstStmtIterator &begin,
185 const ConstStmtIterator &end)
186 : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
187 ConstStmtRange(const StmtRange &range)
188 : std::pair<ConstStmtIterator,ConstStmtIterator>(range.first, range.second)
190 ConstStmtRange(const StmtIterator &begin, const StmtIterator &end)
191 : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
193 bool empty() const { return first == second; }
194 LLVM_EXPLICIT operator bool() const { return !empty(); }
196 const Stmt *operator->() const { return first.operator->(); }
197 const Stmt *operator*() const { return first.operator*(); }
199 ConstStmtRange &operator++() {
200 assert(!empty() && "incrementing on empty range");
205 ConstStmtRange operator++(int) {
206 assert(!empty() && "incrementing on empty range");
207 ConstStmtRange copy = *this;
212 friend const ConstStmtIterator &begin(const ConstStmtRange &range) {
215 friend const ConstStmtIterator &end(const ConstStmtRange &range) {
220 } // end namespace clang