StmtIterator.h revision 699e9fbeae34cdd651b8e6308649c8939f090cbd
1//===--- StmtIterator.h - Iterators for Statements ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Ted Kremenek and is distributed under 6// the University of Illinois Open Source 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, VASizeMode = 0x2, Flags = 0x3 }; 29 union { Stmt** stmt; ScopedDecl* decl; }; 30 uintptr_t RawVAPtr; 31 32 bool inDeclMode() const { return RawVAPtr & DeclMode ? true : false; } 33 bool inVASizeMode() const { return RawVAPtr & VASizeMode ? true : false; } 34 bool hasFlags() const { return RawVAPtr & Flags ? true : false; } 35 36 VariableArrayType* getVAPtr() const { 37 return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags); 38 } 39 40 void setVAPtr(VariableArrayType* P) { 41 assert (inDeclMode() || inVASizeMode()); 42 RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags); 43 } 44 45 void NextDecl(bool ImmediateAdvance = true); 46 void NextVA(); 47 48 Stmt*& GetDeclExpr() const; 49 50 StmtIteratorBase(Stmt** s) : stmt(s), RawVAPtr(0) {} 51 StmtIteratorBase(ScopedDecl* d); 52 StmtIteratorBase(VariableArrayType* t); 53 StmtIteratorBase() : stmt(NULL), RawVAPtr(0) {} 54}; 55 56 57template <typename DERIVED, typename REFERENCE> 58class StmtIteratorImpl : public StmtIteratorBase, 59 public std::iterator<std::forward_iterator_tag, 60 REFERENCE, ptrdiff_t, 61 REFERENCE, REFERENCE> { 62protected: 63 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {} 64public: 65 StmtIteratorImpl() {} 66 StmtIteratorImpl(Stmt** s) : StmtIteratorBase(s) {} 67 StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {} 68 StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {} 69 70 DERIVED& operator++() { 71 if (inDeclMode()) { 72 if (getVAPtr()) NextVA(); 73 else NextDecl(); 74 } 75 else if (inVASizeMode()) 76 NextVA(); 77 else 78 ++stmt; 79 80 return static_cast<DERIVED&>(*this); 81 } 82 83 DERIVED operator++(int) { 84 DERIVED tmp = static_cast<DERIVED&>(*this); 85 operator++(); 86 return tmp; 87 } 88 89 bool operator==(const DERIVED& RHS) const { 90 return stmt == RHS.stmt && RawVAPtr == RHS.RawVAPtr; 91 } 92 93 bool operator!=(const DERIVED& RHS) const { 94 return stmt != RHS.stmt || RawVAPtr != RHS.RawVAPtr; 95 } 96 97 REFERENCE operator*() const { 98 return (REFERENCE) (hasFlags() ? GetDeclExpr() : *stmt); 99 } 100 101 REFERENCE operator->() const { return operator*(); } 102}; 103 104struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> { 105 explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {} 106 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {} 107 StmtIterator(VariableArrayType* t):StmtIteratorImpl<StmtIterator,Stmt*&>(t) {} 108 StmtIterator(ScopedDecl* D) : StmtIteratorImpl<StmtIterator,Stmt*&>(D) {} 109}; 110 111struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, 112 const Stmt*> { 113 explicit ConstStmtIterator() : 114 StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {} 115 116 ConstStmtIterator(const StmtIterator& RHS) : 117 StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {} 118}; 119 120} // end namespace clang 121 122#endif 123