StmtIterator.h revision f5afb5e1fa1877a4adf3328e5be31b2f959d82eb
1//===--- StmtIterator.h - Iterators for Statements ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the StmtIterator and ConstStmtIterator classes. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_STMT_ITR_H 15#define LLVM_CLANG_AST_STMT_ITR_H 16 17#include "llvm/Support/DataTypes.h" 18#include <cassert> 19#include <iterator> 20 21namespace clang { 22 23class Stmt; 24class Decl; 25class VariableArrayType; 26 27class StmtIteratorBase { 28protected: 29 enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3, 30 Flags = 0x3 }; 31 32 union { Stmt** stmt; Decl* decl; Decl** DGI; }; 33 uintptr_t RawVAPtr; 34 Decl** DGE; 35 36 bool inDecl() const { 37 return (RawVAPtr & Flags) == DeclMode; 38 } 39 40 bool inDeclGroup() const { 41 return (RawVAPtr & Flags) == DeclGroupMode; 42 } 43 44 bool inSizeOfTypeVA() const { 45 return (RawVAPtr & Flags) == SizeOfTypeVAMode; 46 } 47 48 bool inStmt() const { 49 return (RawVAPtr & Flags) == 0; 50 } 51 52 VariableArrayType* getVAPtr() const { 53 return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags); 54 } 55 56 void setVAPtr(VariableArrayType* P) { 57 assert (inDecl() || inDeclGroup() || inSizeOfTypeVA()); 58 RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags); 59 } 60 61 void NextDecl(bool ImmediateAdvance = true); 62 bool HandleDecl(Decl* D); 63 void NextVA(); 64 65 Stmt*& GetDeclExpr() const; 66 67 StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {} 68 StmtIteratorBase(Decl* d); 69 StmtIteratorBase(VariableArrayType* t); 70 StmtIteratorBase(Decl** dgi, Decl** dge); 71 StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {} 72}; 73 74 75template <typename DERIVED, typename REFERENCE> 76class StmtIteratorImpl : public StmtIteratorBase, 77 public std::iterator<std::forward_iterator_tag, 78 REFERENCE, ptrdiff_t, 79 REFERENCE, REFERENCE> { 80protected: 81 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {} 82public: 83 StmtIteratorImpl() {} 84 StmtIteratorImpl(Stmt** s) : StmtIteratorBase(s) {} 85 StmtIteratorImpl(Decl** dgi, Decl** dge) : StmtIteratorBase(dgi, dge) {} 86 StmtIteratorImpl(Decl* d) : StmtIteratorBase(d) {} 87 StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {} 88 89 DERIVED& operator++() { 90 if (inDecl() || inDeclGroup()) { 91 if (getVAPtr()) NextVA(); 92 else NextDecl(); 93 } 94 else if (inSizeOfTypeVA()) 95 NextVA(); 96 else 97 ++stmt; 98 99 return static_cast<DERIVED&>(*this); 100 } 101 102 DERIVED operator++(int) { 103 DERIVED tmp = static_cast<DERIVED&>(*this); 104 operator++(); 105 return tmp; 106 } 107 108 bool operator==(const DERIVED& RHS) const { 109 return stmt == RHS.stmt && RawVAPtr == RHS.RawVAPtr; 110 } 111 112 bool operator!=(const DERIVED& RHS) const { 113 return stmt != RHS.stmt || RawVAPtr != RHS.RawVAPtr; 114 } 115 116 REFERENCE operator*() const { 117 return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr()); 118 } 119 120 REFERENCE operator->() const { return operator*(); } 121}; 122 123struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> { 124 explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {} 125 126 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {} 127 StmtIterator(Decl** dgi, Decl** dge) 128 : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {} 129 130 StmtIterator(VariableArrayType* t):StmtIteratorImpl<StmtIterator,Stmt*&>(t) {} 131 StmtIterator(Decl* D) : StmtIteratorImpl<StmtIterator,Stmt*&>(D) {} 132}; 133 134struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, 135 const Stmt*> { 136 explicit ConstStmtIterator() : 137 StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {} 138 139 ConstStmtIterator(const StmtIterator& RHS) : 140 StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {} 141}; 142 143} // end namespace clang 144 145#endif 146