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