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