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