]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h
Merge ACPICA 20100915.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / StmtIterator.h
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/System/DataTypes.h"
18 #include <cassert>
19 #include <cstddef>
20 #include <iterator>
21
22 namespace clang {
23
24 class Stmt;
25 class Decl;
26 class VariableArrayType;
27
28 class StmtIteratorBase {
29 protected:
30   enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
31          Flags = 0x3 };
32   
33   Stmt **stmt;
34   union { Decl *decl; Decl **DGI; };
35   uintptr_t RawVAPtr;
36   Decl **DGE;
37   
38   bool inDecl() const {
39     return (RawVAPtr & Flags) == DeclMode;
40   }
41
42   bool inDeclGroup() const {
43     return (RawVAPtr & Flags) == DeclGroupMode;
44   }
45
46   bool inSizeOfTypeVA() const {
47     return (RawVAPtr & Flags) == SizeOfTypeVAMode;
48   }
49
50   bool inStmt() const {
51     return (RawVAPtr & Flags) == 0;
52   }
53
54   VariableArrayType* getVAPtr() const {
55     return reinterpret_cast<VariableArrayType*>(RawVAPtr & ~Flags);
56   }
57
58   void setVAPtr(VariableArrayType* P) {
59     assert (inDecl() || inDeclGroup() || inSizeOfTypeVA());
60     RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
61   }
62
63   void NextDecl(bool ImmediateAdvance = true);
64   bool HandleDecl(Decl* D);
65   void NextVA();
66
67   Stmt*& GetDeclExpr() const;
68
69   StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {}
70   StmtIteratorBase(Decl *d, Stmt **s);
71   StmtIteratorBase(VariableArrayType *t);
72   StmtIteratorBase(Decl **dgi, Decl **dge);
73   StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {}
74 };
75
76
77 template <typename DERIVED, typename REFERENCE>
78 class StmtIteratorImpl : public StmtIteratorBase,
79                          public std::iterator<std::forward_iterator_tag,
80                                               REFERENCE, ptrdiff_t,
81                                               REFERENCE, REFERENCE> {
82 protected:
83   StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
84 public:
85   StmtIteratorImpl() {}
86   StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
87   StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
88   StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {}
89   StmtIteratorImpl(VariableArrayType* t) : StmtIteratorBase(t) {}
90
91   DERIVED& operator++() {
92     if (inDecl() || inDeclGroup()) {
93       if (getVAPtr()) NextVA();
94       else NextDecl();
95     }
96     else if (inSizeOfTypeVA())
97       NextVA();
98     else
99       ++stmt;
100
101     return static_cast<DERIVED&>(*this);
102   }
103
104   DERIVED operator++(int) {
105     DERIVED tmp = static_cast<DERIVED&>(*this);
106     operator++();
107     return tmp;
108   }
109
110   bool operator==(const DERIVED& RHS) const {
111     return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr;
112   }
113
114   bool operator!=(const DERIVED& RHS) const {
115     return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr;
116   }
117
118   REFERENCE operator*() const {
119     return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
120   }
121
122   REFERENCE operator->() const { return operator*(); }
123 };
124
125 struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
126   explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
127
128   StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
129
130   StmtIterator(Decl** dgi, Decl** dge)
131    : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
132
133   StmtIterator(VariableArrayType* t)
134     : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
135
136   StmtIterator(Decl* D, Stmt **s = 0)
137     : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {}
138 };
139
140 struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
141                                                    const Stmt*> {
142   explicit ConstStmtIterator() :
143     StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
144
145   ConstStmtIterator(const StmtIterator& RHS) :
146     StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
147 };
148
149 } // end namespace clang
150
151 #endif