LCOV - code coverage report
Current view: top level - clang/AST - StmtIterator.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 17 21 81.0 %
Date: 2016-01-31 12:01:00 Functions: 15 16 93.8 %

          Line data    Source code
       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 "llvm/Support/Compiler.h"
      18             : #include "llvm/Support/DataTypes.h"
      19             : #include <cassert>
      20             : #include <cstddef>
      21             : #include <iterator>
      22             : #include <utility>
      23             : 
      24             : namespace clang {
      25             : 
      26             : class Stmt;
      27             : class Decl;
      28             : class VariableArrayType;
      29             : 
      30             : class StmtIteratorBase {
      31             : protected:
      32             :   enum { StmtMode = 0x0, SizeOfTypeVAMode = 0x1, DeclGroupMode = 0x2,
      33             :          Flags = 0x3 };
      34             :   
      35             :   union {
      36             :     Stmt **stmt;
      37             :     Decl **DGI;
      38             :   };
      39             :   uintptr_t RawVAPtr;
      40             :   Decl **DGE;
      41             :   
      42             :   bool inDeclGroup() const {
      43             :     return (RawVAPtr & Flags) == DeclGroupMode;
      44             :   }
      45             : 
      46             :   bool inSizeOfTypeVA() const {
      47             :     return (RawVAPtr & Flags) == SizeOfTypeVAMode;
      48             :   }
      49             : 
      50             :   bool inStmt() const {
      51         104 :     return (RawVAPtr & Flags) == StmtMode;
      52             :   }
      53             : 
      54             :   const VariableArrayType *getVAPtr() const {
      55           0 :     return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
      56             :   }
      57             : 
      58             :   void setVAPtr(const VariableArrayType *P) {
      59             :     assert (inDeclGroup() || inSizeOfTypeVA());
      60             :     RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
      61             :   }
      62             : 
      63             :   void NextDecl(bool ImmediateAdvance = true);
      64             :   bool HandleDecl(Decl* D);
      65             :   void NextVA();
      66             : 
      67             :   Stmt*& GetDeclExpr() const;
      68             : 
      69          92 :   StmtIteratorBase(Stmt **s) : stmt(s), RawVAPtr(0) {}
      70             :   StmtIteratorBase(const VariableArrayType *t);
      71             :   StmtIteratorBase(Decl **dgi, Decl **dge);
      72          46 :   StmtIteratorBase() : stmt(nullptr), RawVAPtr(0) {}
      73             : };
      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             : public:
      84          46 :   StmtIteratorImpl() {}
      85          92 :   StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
      86             :   StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
      87             :   StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
      88             : 
      89             :   DERIVED& operator++() {
      90          52 :     if (inStmt())
      91          52 :       ++stmt;
      92           0 :     else if (getVAPtr())
      93           0 :       NextVA();
      94             :     else
      95           0 :       NextDecl();
      96             : 
      97          52 :     return static_cast<DERIVED&>(*this);
      98             :   }
      99             : 
     100             :   DERIVED operator++(int) {
     101             :     DERIVED tmp = static_cast<DERIVED&>(*this);
     102             :     operator++();
     103             :     return tmp;
     104             :   }
     105             : 
     106             :   bool operator==(const DERIVED& RHS) const {
     107          14 :     return stmt == RHS.stmt && DGI == RHS.DGI && RawVAPtr == RHS.RawVAPtr;
     108             :   }
     109             : 
     110             :   bool operator!=(const DERIVED& RHS) const {
     111         368 :     return stmt != RHS.stmt || DGI != RHS.DGI || RawVAPtr != RHS.RawVAPtr;
     112             :   }
     113             : 
     114             :   REFERENCE operator*() const {
     115         156 :     return inStmt() ? *stmt : GetDeclExpr();
     116             :   }
     117             : 
     118             :   REFERENCE operator->() const { return operator*(); }
     119             : };
     120             : 
     121             : struct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
     122          46 :   explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
     123             : 
     124          92 :   StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
     125             : 
     126             :   StmtIterator(Decl** dgi, Decl** dge)
     127             :    : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
     128             : 
     129             :   StmtIterator(const VariableArrayType *t)
     130             :     : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
     131             : };
     132             : 
     133             : struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
     134             :                                                    const Stmt*> {
     135             :   explicit ConstStmtIterator() :
     136             :     StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
     137             : 
     138             :   ConstStmtIterator(const StmtIterator& RHS) :
     139             :     StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
     140             : };
     141             : 
     142             : /// A range of statement iterators.
     143             : ///
     144             : /// This class provides some extra functionality beyond std::pair
     145             : /// in order to allow the following idiom:
     146             : ///   for (StmtRange range = stmt->children(); range; ++range)
     147             : struct StmtRange : std::pair<StmtIterator,StmtIterator> {
     148          18 :   StmtRange() {}
     149             :   StmtRange(const StmtIterator &begin, const StmtIterator &end)
     150          46 :     : std::pair<StmtIterator,StmtIterator>(begin, end) {}
     151             : 
     152             :   bool empty() const { return first == second; }
     153             :   explicit operator bool() const { return !empty(); }
     154             : 
     155             :   Stmt *operator->() const { return first.operator->(); }
     156             :   Stmt *&operator*() const { return first.operator*(); }
     157             : 
     158             :   StmtRange &operator++() {
     159             :     assert(!empty() && "incrementing on empty range");
     160             :     ++first;
     161             :     return *this;
     162             :   }
     163             : 
     164             :   StmtRange operator++(int) {
     165             :     assert(!empty() && "incrementing on empty range");
     166             :     StmtRange copy = *this;
     167             :     ++first;
     168             :     return copy;
     169             :   }
     170             : 
     171             :   friend const StmtIterator &begin(const StmtRange &range) {
     172          64 :     return range.first;
     173             :   }
     174             :   friend const StmtIterator &end(const StmtRange &range) {
     175          64 :     return range.second;
     176             :   }
     177             : };
     178             : 
     179             : /// A range of const statement iterators.
     180             : ///
     181             : /// This class provides some extra functionality beyond std::pair
     182             : /// in order to allow the following idiom:
     183             : ///   for (ConstStmtRange range = stmt->children(); range; ++range)
     184             : struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> {
     185             :   ConstStmtRange() {}
     186             :   ConstStmtRange(const ConstStmtIterator &begin,
     187             :                  const ConstStmtIterator &end)
     188             :     : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
     189             :   ConstStmtRange(const StmtRange &range)
     190             :     : std::pair<ConstStmtIterator,ConstStmtIterator>(range.first, range.second)
     191             :   {}
     192             :   ConstStmtRange(const StmtIterator &begin, const StmtIterator &end)
     193             :     : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
     194             : 
     195             :   bool empty() const { return first == second; }
     196             :   explicit operator bool() const { return !empty(); }
     197             : 
     198             :   const Stmt *operator->() const { return first.operator->(); }
     199             :   const Stmt *operator*() const { return first.operator*(); }
     200             : 
     201             :   ConstStmtRange &operator++() {
     202             :     assert(!empty() && "incrementing on empty range");
     203             :     ++first;
     204             :     return *this;
     205             :   }
     206             : 
     207             :   ConstStmtRange operator++(int) {
     208             :     assert(!empty() && "incrementing on empty range");
     209             :     ConstStmtRange copy = *this;
     210             :     ++first;
     211             :     return copy;
     212             :   }
     213             : 
     214             :   friend const ConstStmtIterator &begin(const ConstStmtRange &range) {
     215             :     return range.first;
     216             :   }
     217             :   friend const ConstStmtIterator &end(const ConstStmtRange &range) {
     218             :     return range.second;
     219             :   }
     220             : };
     221             : 
     222             : } // end namespace clang
     223             : 
     224             : #endif

Generated by: LCOV version 1.11