Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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. protected:
  79.   StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
  80.  
  81. public:
  82.   using iterator_category = std::forward_iterator_tag;
  83.   using value_type = REFERENCE;
  84.   using difference_type = std::ptrdiff_t;
  85.   using pointer = REFERENCE;
  86.   using reference = REFERENCE;
  87.  
  88.   StmtIteratorImpl() = default;
  89.   StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
  90.   StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
  91.   StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
  92.  
  93.   DERIVED& operator++() {
  94.     if (inStmt())
  95.       ++stmt;
  96.     else if (getVAPtr())
  97.       NextVA();
  98.     else
  99.       NextDecl();
  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.   friend bool operator==(const DERIVED &LHS, const DERIVED &RHS) {
  111.     return LHS.stmt == RHS.stmt && LHS.DGI == RHS.DGI &&
  112.            LHS.RawVAPtr == RHS.RawVAPtr;
  113.   }
  114.  
  115.   friend bool operator!=(const DERIVED &LHS, const DERIVED &RHS) {
  116.     return !(LHS == RHS);
  117.   }
  118.  
  119.   REFERENCE operator*() const {
  120.     return inStmt() ? *stmt : GetDeclExpr();
  121.   }
  122.  
  123.   REFERENCE operator->() const { return operator*(); }
  124. };
  125.  
  126. struct ConstStmtIterator;
  127.  
  128. struct StmtIterator : public StmtIteratorImpl<StmtIterator, Stmt*&> {
  129.   explicit StmtIterator() = default;
  130.   StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator, Stmt*&>(S) {}
  131.   StmtIterator(Decl** dgi, Decl** dge)
  132.       : StmtIteratorImpl<StmtIterator, Stmt*&>(dgi, dge) {}
  133.   StmtIterator(const VariableArrayType *t)
  134.       : StmtIteratorImpl<StmtIterator, Stmt*&>(t) {}
  135.  
  136. private:
  137.   StmtIterator(const StmtIteratorBase &RHS)
  138.       : StmtIteratorImpl<StmtIterator, Stmt *&>(RHS) {}
  139.  
  140.   inline friend StmtIterator
  141.   cast_away_const(const ConstStmtIterator &RHS);
  142. };
  143.  
  144. struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
  145.                                                    const Stmt*> {
  146.   explicit ConstStmtIterator() = default;
  147.   ConstStmtIterator(const StmtIterator& RHS)
  148.       : StmtIteratorImpl<ConstStmtIterator, const Stmt*>(RHS) {}
  149.  
  150.   ConstStmtIterator(Stmt * const *S)
  151.       : StmtIteratorImpl<ConstStmtIterator, const Stmt *>(
  152.             const_cast<Stmt **>(S)) {}
  153. };
  154.  
  155. inline StmtIterator cast_away_const(const ConstStmtIterator &RHS) {
  156.   return RHS;
  157. }
  158.  
  159. } // namespace clang
  160.  
  161. #endif // LLVM_CLANG_AST_STMTITERATOR_H
  162.