File indexing completed on 2026-05-10 08:36:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_AST_STMTITERATOR_H
0014 #define LLVM_CLANG_AST_STMTITERATOR_H
0015
0016 #include <cassert>
0017 #include <cstddef>
0018 #include <cstdint>
0019 #include <iterator>
0020
0021 namespace clang {
0022
0023 class Decl;
0024 class Stmt;
0025 class VariableArrayType;
0026
0027 class StmtIteratorBase {
0028 protected:
0029 enum {
0030 StmtMode = 0x0,
0031 SizeOfTypeVAMode = 0x1,
0032 DeclGroupMode = 0x2,
0033 Flags = 0x3
0034 };
0035
0036 union {
0037 Stmt **stmt;
0038 Decl **DGI;
0039 };
0040 uintptr_t RawVAPtr = 0;
0041 Decl **DGE;
0042
0043 StmtIteratorBase(Stmt **s) : stmt(s) {}
0044 StmtIteratorBase(const VariableArrayType *t);
0045 StmtIteratorBase(Decl **dgi, Decl **dge);
0046 StmtIteratorBase() : stmt(nullptr) {}
0047
0048 bool inDeclGroup() const {
0049 return (RawVAPtr & Flags) == DeclGroupMode;
0050 }
0051
0052 bool inSizeOfTypeVA() const {
0053 return (RawVAPtr & Flags) == SizeOfTypeVAMode;
0054 }
0055
0056 bool inStmt() const {
0057 return (RawVAPtr & Flags) == StmtMode;
0058 }
0059
0060 const VariableArrayType *getVAPtr() const {
0061 return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
0062 }
0063
0064 void setVAPtr(const VariableArrayType *P) {
0065 assert(inDeclGroup() || inSizeOfTypeVA());
0066 RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
0067 }
0068
0069 void NextDecl(bool ImmediateAdvance = true);
0070 bool HandleDecl(Decl* D);
0071 void NextVA();
0072
0073 Stmt*& GetDeclExpr() const;
0074 };
0075
0076 template <typename DERIVED, typename REFERENCE>
0077 class StmtIteratorImpl : public StmtIteratorBase {
0078 protected:
0079 StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
0080
0081 public:
0082 using iterator_category = std::forward_iterator_tag;
0083 using value_type = REFERENCE;
0084 using difference_type = std::ptrdiff_t;
0085 using pointer = REFERENCE;
0086 using reference = REFERENCE;
0087
0088 StmtIteratorImpl() = default;
0089 StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
0090 StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
0091 StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
0092
0093 DERIVED& operator++() {
0094 if (inStmt())
0095 ++stmt;
0096 else if (getVAPtr())
0097 NextVA();
0098 else
0099 NextDecl();
0100
0101 return static_cast<DERIVED&>(*this);
0102 }
0103
0104 DERIVED operator++(int) {
0105 DERIVED tmp = static_cast<DERIVED&>(*this);
0106 operator++();
0107 return tmp;
0108 }
0109
0110 friend bool operator==(const DERIVED &LHS, const DERIVED &RHS) {
0111 return LHS.stmt == RHS.stmt && LHS.DGI == RHS.DGI &&
0112 LHS.RawVAPtr == RHS.RawVAPtr;
0113 }
0114
0115 friend bool operator!=(const DERIVED &LHS, const DERIVED &RHS) {
0116 return !(LHS == RHS);
0117 }
0118
0119 REFERENCE operator*() const {
0120 return inStmt() ? *stmt : GetDeclExpr();
0121 }
0122
0123 REFERENCE operator->() const { return operator*(); }
0124 };
0125
0126 struct ConstStmtIterator;
0127
0128 struct StmtIterator : public StmtIteratorImpl<StmtIterator, Stmt*&> {
0129 explicit StmtIterator() = default;
0130 StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator, Stmt*&>(S) {}
0131 StmtIterator(Decl** dgi, Decl** dge)
0132 : StmtIteratorImpl<StmtIterator, Stmt*&>(dgi, dge) {}
0133 StmtIterator(const VariableArrayType *t)
0134 : StmtIteratorImpl<StmtIterator, Stmt*&>(t) {}
0135
0136 private:
0137 StmtIterator(const StmtIteratorBase &RHS)
0138 : StmtIteratorImpl<StmtIterator, Stmt *&>(RHS) {}
0139
0140 inline friend StmtIterator
0141 cast_away_const(const ConstStmtIterator &RHS);
0142 };
0143
0144 struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
0145 const Stmt*> {
0146 explicit ConstStmtIterator() = default;
0147 ConstStmtIterator(const StmtIterator& RHS)
0148 : StmtIteratorImpl<ConstStmtIterator, const Stmt*>(RHS) {}
0149
0150 ConstStmtIterator(Stmt * const *S)
0151 : StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
0152 const_cast<Stmt **>(S)) {}
0153 };
0154
0155 inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
0156 return RHS;
0157 }
0158
0159 }
0160
0161 #endif