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