StmtIterator.h 4.4 KB

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