StmtIterator.h revision c65a1fc4f4f84c5a08db7d08bbc2e49f0bb75ff5
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 19namespace clang { 20 21class Stmt; 22class ScopedDecl; 23 24class StmtIteratorBase { 25protected: 26 union { Stmt** S; ScopedDecl* D; } Ptr; 27 ScopedDecl* FirstDecl; 28 29 void NextDecl(); 30 void PrevDecl(); 31 Stmt*& GetInitializer() const; 32 33 StmtIteratorBase(Stmt** s) : FirstDecl(NULL) { Ptr.S = s; } 34 StmtIteratorBase(ScopedDecl* d); 35 StmtIteratorBase() : FirstDecl(NULL) { Ptr.S = NULL; } 36}; 37 38 39template <typename DERIVED, typename REFERENCE> 40class StmtIteratorImpl : public StmtIteratorBase, 41 public std::iterator<std::bidirectional_iterator_tag, 42 REFERENCE, ptrdiff_t, 43 REFERENCE, REFERENCE> { 44protected: 45 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {} 46public: 47 StmtIteratorImpl() {} 48 StmtIteratorImpl(Stmt** s) : StmtIteratorBase(s) {} 49 StmtIteratorImpl(ScopedDecl* d) : StmtIteratorBase(d) {} 50 51 52 DERIVED& operator++() { 53 if (FirstDecl) NextDecl(); 54 else ++Ptr.S; 55 56 return static_cast<DERIVED&>(*this); 57 } 58 59 DERIVED operator++(int) { 60 DERIVED tmp = static_cast<DERIVED&>(*this); 61 operator++(); 62 return tmp; 63 } 64 65 DERIVED& operator--() { 66 if (FirstDecl) PrevDecl(); 67 else --Ptr.S; 68 69 return static_cast<DERIVED&>(*this); 70 } 71 72 DERIVED operator--(int) { 73 DERIVED tmp = static_cast<DERIVED&>(*this); 74 operator--(); 75 return tmp; 76 } 77 78 bool operator==(const DERIVED& RHS) const { 79 return FirstDecl == RHS.FirstDecl && Ptr.S == RHS.Ptr.S; 80 } 81 82 bool operator!=(const DERIVED& RHS) const { 83 return FirstDecl != RHS.FirstDecl || Ptr.S != RHS.Ptr.S; 84 } 85 86 REFERENCE operator*() const { 87 return (REFERENCE) (FirstDecl ? GetInitializer() : *Ptr.S); 88 } 89 90 REFERENCE operator->() const { return operator*(); } 91}; 92 93struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> { 94 explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {} 95 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {} 96 StmtIterator(ScopedDecl* D) : StmtIteratorImpl<StmtIterator,Stmt*&>(D) {} 97}; 98 99struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, 100 const Stmt*> { 101 explicit ConstStmtIterator() : 102 StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {} 103 104 ConstStmtIterator(const StmtIterator& RHS) : 105 StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {} 106}; 107 108} // end namespace clang 109 110#endif 111