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