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