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