StmtIterator.h revision f4c7371fb1d3cebcfb40abad4537bb82515704ea
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 <cstddef> 20#include <iterator> 21 22namespace clang { 23 24class Stmt; 25class Decl; 26class VariableArrayType; 27 28class StmtIteratorBase { 29protected: 30 enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3, 31 Flags = 0x3 }; 32 33 Stmt **stmt; 34 union { Decl *decl; Decl **DGI; }; 35 uintptr_t RawVAPtr; 36 Decl **DGE; 37 38 bool inDecl() const { 39 return (RawVAPtr & Flags) == DeclMode; 40 } 41 42 bool inDeclGroup() const { 43 return (RawVAPtr & Flags) == DeclGroupMode; 44 } 45 46 bool inSizeOfTypeVA() const { 47 return (RawVAPtr & Flags) == SizeOfTypeVAMode; 48 } 49 50 bool inStmt() const { 51 return (RawVAPtr & Flags) == 0; 52 } 53 54 const VariableArrayType *getVAPtr() const { 55 return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags); 56 } 57 58 void setVAPtr(const VariableArrayType *P) { 59 assert (inDecl() || inDeclGroup() || inSizeOfTypeVA()); 60 RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags); 61 } 62 63 void NextDecl(bool ImmediateAdvance = true); 64 bool HandleDecl(Decl* D); 65 void NextVA(); 66 67 Stmt*& GetDeclExpr() const; 68 69 StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {} 70 StmtIteratorBase(Decl *d, Stmt **s); 71 StmtIteratorBase(const VariableArrayType *t); 72 StmtIteratorBase(Decl **dgi, Decl **dge); 73 StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {} 74}; 75 76 77template <typename DERIVED, typename REFERENCE> 78class StmtIteratorImpl : public StmtIteratorBase, 79 public std::iterator<std::forward_iterator_tag, 80 REFERENCE, ptrdiff_t, 81 REFERENCE, REFERENCE> { 82protected: 83 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {} 84public: 85 StmtIteratorImpl() {} 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(const VariableArrayType *t) : StmtIteratorBase(t) {} 90 91 DERIVED& operator++() { 92 if (inDecl() || inDeclGroup()) { 93 if (getVAPtr()) NextVA(); 94 else NextDecl(); 95 } 96 else if (inSizeOfTypeVA()) 97 NextVA(); 98 else 99 ++stmt; 100 101 return static_cast<DERIVED&>(*this); 102 } 103 104 DERIVED operator++(int) { 105 DERIVED tmp = static_cast<DERIVED&>(*this); 106 operator++(); 107 return tmp; 108 } 109 110 bool operator==(const DERIVED& RHS) const { 111 return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr; 112 } 113 114 bool operator!=(const DERIVED& RHS) const { 115 return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr; 116 } 117 118 REFERENCE operator*() const { 119 return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr()); 120 } 121 122 REFERENCE operator->() const { return operator*(); } 123}; 124 125struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> { 126 explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {} 127 128 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {} 129 130 StmtIterator(Decl** dgi, Decl** dge) 131 : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {} 132 133 StmtIterator(const VariableArrayType *t) 134 : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {} 135 136 StmtIterator(Decl* D, Stmt **s = 0) 137 : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {} 138}; 139 140struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, 141 const Stmt*> { 142 explicit ConstStmtIterator() : 143 StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {} 144 145 ConstStmtIterator(const StmtIterator& RHS) : 146 StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {} 147}; 148 149} // end namespace clang 150 151#endif 152