]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / AST / StmtIterator.h
1 //===- StmtIterator.h - Iterators for Statements ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the StmtIterator and ConstStmtIterator classes.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_CLANG_AST_STMTITERATOR_H
14 #define LLVM_CLANG_AST_STMTITERATOR_H
15
16 #include <cassert>
17 #include <cstddef>
18 #include <cstdint>
19 #include <iterator>
20
21 namespace clang {
22
23 class Decl;
24 class Stmt;
25 class VariableArrayType;
26
27 class StmtIteratorBase {
28 protected:
29   enum {
30     StmtMode = 0x0,
31     SizeOfTypeVAMode = 0x1,
32     DeclGroupMode = 0x2,
33     Flags = 0x3
34   };
35
36   union {
37     Stmt **stmt;
38     Decl **DGI;
39   };
40   uintptr_t RawVAPtr = 0;
41   Decl **DGE;
42
43   StmtIteratorBase(Stmt **s) : stmt(s) {}
44   StmtIteratorBase(const VariableArrayType *t);
45   StmtIteratorBase(Decl **dgi, Decl **dge);
46   StmtIteratorBase() : stmt(nullptr) {}
47
48   bool inDeclGroup() const {
49     return (RawVAPtr & Flags) == DeclGroupMode;
50   }
51
52   bool inSizeOfTypeVA() const {
53     return (RawVAPtr & Flags) == SizeOfTypeVAMode;
54   }
55
56   bool inStmt() const {
57     return (RawVAPtr & Flags) == StmtMode;
58   }
59
60   const VariableArrayType *getVAPtr() const {
61     return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
62   }
63
64   void setVAPtr(const VariableArrayType *P) {
65     assert(inDeclGroup() || inSizeOfTypeVA());
66     RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
67   }
68
69   void NextDecl(bool ImmediateAdvance = true);
70   bool HandleDecl(Decl* D);
71   void NextVA();
72
73   Stmt*& GetDeclExpr() const;
74 };
75
76 template <typename DERIVED, typename REFERENCE>
77 class StmtIteratorImpl : public StmtIteratorBase,
78                          public std::iterator<std::forward_iterator_tag,
79                                               REFERENCE, ptrdiff_t,
80                                               REFERENCE, REFERENCE> {
81 protected:
82   StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
83
84 public:
85   StmtIteratorImpl() = default;
86   StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
87   StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
88   StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
89
90   DERIVED& operator++() {
91     if (inStmt())
92       ++stmt;
93     else if (getVAPtr())
94       NextVA();
95     else
96       NextDecl();
97
98     return static_cast<DERIVED&>(*this);
99   }
100
101   DERIVED operator++(int) {
102     DERIVED tmp = static_cast<DERIVED&>(*this);
103     operator++();
104     return tmp;
105   }
106
107   bool operator==(const DERIVED& RHS) const {
108     return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
109   }
110
111   bool operator!=(const DERIVED& RHS) const {
112     return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
113   }
114
115   REFERENCE operator*() const {
116     return inStmt() ? *stmt : GetDeclExpr();
117   }
118
119   REFERENCE operator->() const { return operator*(); }
120 };
121
122 struct ConstStmtIterator;
123
124 struct StmtIterator : public StmtIteratorImpl<StmtIterator, Stmt*&> {
125   explicit StmtIterator() = default;
126   StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator, Stmt*&>(S) {}
127   StmtIterator(Decl** dgi, Decl** dge)
128       : StmtIteratorImpl<StmtIterator, Stmt*&>(dgi, dge) {}
129   StmtIterator(const VariableArrayType *t)
130       : StmtIteratorImpl<StmtIterator, Stmt*&>(t) {}
131
132 private:
133   StmtIterator(const StmtIteratorBase &RHS)
134       : StmtIteratorImpl<StmtIterator, Stmt *&>(RHS) {}
135
136   inline friend StmtIterator
137   cast_away_const(const ConstStmtIterator &RHS);
138 };
139
140 struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
141                                                    const Stmt*> {
142   explicit ConstStmtIterator() = default;
143   ConstStmtIterator(const StmtIterator& RHS)
144       : StmtIteratorImpl<ConstStmtIterator, const Stmt*>(RHS) {}
145
146   ConstStmtIterator(Stmt * const *S)
147       : StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
148             const_cast<Stmt **>(S)) {}
149 };
150
151 inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
152   return RHS;
153 }
154
155 } // namespace clang
156
157 #endif // LLVM_CLANG_AST_STMTITERATOR_H