163c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall//===--- StmtIterator.h - Iterators for Statements --------------*- C++ -*-===//
29caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//
39caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//                     The LLVM Compiler Infrastructure
49caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
79caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//
89caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//===----------------------------------------------------------------------===//
99caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//
109caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek// This file defines the StmtIterator and ConstStmtIterator classes.
119caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//
129caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek//===----------------------------------------------------------------------===//
139caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek
149caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek#ifndef LLVM_CLANG_AST_STMT_ITR_H
159caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek#define LLVM_CLANG_AST_STMT_ITR_H
169caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek
1703013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/DataTypes.h"
18481038b5f37b77d7aa24c3ed5a751bc9c37e32e6Hartmut Kaiser#include <cassert>
19ea3fe7c72b73ae09070ced4dc12ddbfbd29c0b1aDaniel Dunbar#include <cstddef>
20f5afb5e1fa1877a4adf3328e5be31b2f959d82ebGabor Greif#include <iterator>
217a3a8148ab21dba3965622b03969bae721d561e2NAKAMURA Takumi#include <utility>
229caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek
239caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremeneknamespace clang {
249caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek
259caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenekclass Stmt;
263e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenekclass Decl;
2765f31e451c8d631f0e76cb9c8935465d68830cb1Ted Kremenekclass VariableArrayType;
281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
29c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenekclass StmtIteratorBase {
30c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenekprotected:
313e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek  enum { DeclMode = 0x1, SizeOfTypeVAMode = 0x2, DeclGroupMode = 0x3,
323e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek         Flags = 0x3 };
33b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek
34b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek  Stmt **stmt;
35b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek  union { Decl *decl; Decl **DGI; };
361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  uintptr_t RawVAPtr;
37b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek  Decl **DGE;
38b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek
39b51d2b2d5497693783338c58dd778b6427e85ba7Ted Kremenek  bool inDecl() const {
403e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek    return (RawVAPtr & Flags) == DeclMode;
413e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek  }
421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
433e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek  bool inDeclGroup() const {
443e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek    return (RawVAPtr & Flags) == DeclGroupMode;
45b51d2b2d5497693783338c58dd778b6427e85ba7Ted Kremenek  }
461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  bool inSizeOfTypeVA() const {
483e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek    return (RawVAPtr & Flags) == SizeOfTypeVAMode;
493e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek  }
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
513e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek  bool inStmt() const {
523e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek    return (RawVAPtr & Flags) == 0;
53b51d2b2d5497693783338c58dd778b6427e85ba7Ted Kremenek  }
541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  const VariableArrayType *getVAPtr() const {
56f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall    return reinterpret_cast<const VariableArrayType*>(RawVAPtr & ~Flags);
5792866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  }
581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  void setVAPtr(const VariableArrayType *P) {
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    assert (inDecl() || inDeclGroup() || inSizeOfTypeVA());
61699e9fbeae34cdd651b8e6308649c8939f090cbdTed Kremenek    RawVAPtr = reinterpret_cast<uintptr_t>(P) | (RawVAPtr & Flags);
6292866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  }
631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6492866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  void NextDecl(bool ImmediateAdvance = true);
653e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek  bool HandleDecl(Decl* D);
6692866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  void NextVA();
671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68b990f1834b4ba1c8e67ace010b0f554d0e59c1eaTed Kremenek  Stmt*& GetDeclExpr() const;
69c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek
70b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek  StmtIteratorBase(Stmt **s) : stmt(s), decl(0), RawVAPtr(0) {}
7135628d1f17c817f8c240208db7ba490e3109981bTed Kremenek  StmtIteratorBase(Decl *d, Stmt **s);
72f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  StmtIteratorBase(const VariableArrayType *t);
73b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek  StmtIteratorBase(Decl **dgi, Decl **dge);
74b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek  StmtIteratorBase() : stmt(0), decl(0), RawVAPtr(0) {}
75c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek};
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7822c0fcba14e069bd3d35305ecd6d952f41666610Ted Kremenektemplate <typename DERIVED, typename REFERENCE>
791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass StmtIteratorImpl : public StmtIteratorBase,
8092866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek                         public std::iterator<std::forward_iterator_tag,
811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              REFERENCE, ptrdiff_t,
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                                              REFERENCE, REFERENCE> {
83c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenekprotected:
84c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek  StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
85c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenekpublic:
861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  StmtIteratorImpl() {}
8735628d1f17c817f8c240208db7ba490e3109981bTed Kremenek  StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
8835628d1f17c817f8c240208db7ba490e3109981bTed Kremenek  StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
8935628d1f17c817f8c240208db7ba490e3109981bTed Kremenek  StmtIteratorImpl(Decl *d, Stmt **s) : StmtIteratorBase(d, s) {}
90f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  StmtIteratorImpl(const VariableArrayType *t) : StmtIteratorBase(t) {}
911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9292866e2e90f6d93fb95e25a7ac4438e239d89ce6Ted Kremenek  DERIVED& operator++() {
93165ce3c8a16542182adedae6475ed08ae4972e31Benjamin Kramer    if (inStmt())
94165ce3c8a16542182adedae6475ed08ae4972e31Benjamin Kramer      ++stmt;
95165ce3c8a16542182adedae6475ed08ae4972e31Benjamin Kramer    else if (getVAPtr())
963e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek      NextVA();
97699e9fbeae34cdd651b8e6308649c8939f090cbdTed Kremenek    else
98165ce3c8a16542182adedae6475ed08ae4972e31Benjamin Kramer      NextDecl();
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
100c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek    return static_cast<DERIVED&>(*this);
1019caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek  }
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek  DERIVED operator++(int) {
104c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek    DERIVED tmp = static_cast<DERIVED&>(*this);
1059caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek    operator++();
1069caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek    return tmp;
1079caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek  }
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
109c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek  bool operator==(const DERIVED& RHS) const {
110b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek    return stmt == RHS.stmt && decl == RHS.decl && RawVAPtr == RHS.RawVAPtr;
1119caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek  }
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek  bool operator!=(const DERIVED& RHS) const {
114b03f630a5d4256220ac48a6f04b765c34c9e8993Ted Kremenek    return stmt != RHS.stmt || decl != RHS.decl || RawVAPtr != RHS.RawVAPtr;
1159caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek  }
1161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  REFERENCE operator*() const {
1183e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek    return (REFERENCE) (inStmt() ? *stmt : GetDeclExpr());
1199caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek  }
1201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  REFERENCE operator->() const { return operator*(); }
1229caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek};
123c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek
12422c0fcba14e069bd3d35305ecd6d952f41666610Ted Kremenekstruct StmtIterator : public StmtIteratorImpl<StmtIterator,Stmt*&> {
12522c0fcba14e069bd3d35305ecd6d952f41666610Ted Kremenek  explicit StmtIterator() : StmtIteratorImpl<StmtIterator,Stmt*&>() {}
126b51d2b2d5497693783338c58dd778b6427e85ba7Ted Kremenek
127f816f77480e70caadfdbd741cf17d84a6be30b71Ted Kremenek  StmtIterator(Stmt** S) : StmtIteratorImpl<StmtIterator,Stmt*&>(S) {}
12835628d1f17c817f8c240208db7ba490e3109981bTed Kremenek
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  StmtIterator(Decl** dgi, Decl** dge)
1303e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek   : StmtIteratorImpl<StmtIterator,Stmt*&>(dgi, dge) {}
1313e6d1203b3346147cee51a8a6d374f1867f2cd23Ted Kremenek
132f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall  StmtIterator(const VariableArrayType *t)
13335628d1f17c817f8c240208db7ba490e3109981bTed Kremenek    : StmtIteratorImpl<StmtIterator,Stmt*&>(t) {}
13435628d1f17c817f8c240208db7ba490e3109981bTed Kremenek
13535628d1f17c817f8c240208db7ba490e3109981bTed Kremenek  StmtIterator(Decl* D, Stmt **s = 0)
13635628d1f17c817f8c240208db7ba490e3109981bTed Kremenek    : StmtIteratorImpl<StmtIterator,Stmt*&>(D, s) {}
137c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek};
138c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek
139c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenekstruct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator,
1409ac5928abeb3a47592201e1c30fe2930c20a507eTed Kremenek                                                   const Stmt*> {
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  explicit ConstStmtIterator() :
1429ac5928abeb3a47592201e1c30fe2930c20a507eTed Kremenek    StmtIteratorImpl<ConstStmtIterator,const Stmt*>() {}
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ConstStmtIterator(const StmtIterator& RHS) :
145c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek    StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {}
146c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek};
147c325e7f51b4c92efd711b8ad289ec16da8cd64f0Ted Kremenek
1487502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall/// A range of statement iterators.
1497502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall///
1507502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall/// This class provides some extra functionality beyond std::pair
1517502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall/// in order to allow the following idiom:
1527502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall///   for (StmtRange range = stmt->children(); range; ++range)
1537502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCallstruct StmtRange : std::pair<StmtIterator,StmtIterator> {
1547502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  StmtRange() {}
1557502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  StmtRange(const StmtIterator &begin, const StmtIterator &end)
1567502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    : std::pair<StmtIterator,StmtIterator>(begin, end) {}
1577502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
1587502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  bool empty() const { return first == second; }
1597502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  operator bool() const { return !empty(); }
1607502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
1617502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  Stmt *operator->() const { return first.operator->(); }
1627502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  Stmt *&operator*() const { return first.operator*(); }
1637502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
1647502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  StmtRange &operator++() {
1657502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    assert(!empty() && "incrementing on empty range");
1667502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    ++first;
1677502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return *this;
1687502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
16963c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall
1707502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  StmtRange operator++(int) {
1717502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    assert(!empty() && "incrementing on empty range");
1727502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    StmtRange copy = *this;
1737502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    ++first;
1747502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return copy;
1757502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
17663c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall
1777502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  friend const StmtIterator &begin(const StmtRange &range) {
1787502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return range.first;
1797502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
1807502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  friend const StmtIterator &end(const StmtRange &range) {
1817502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return range.second;
1827502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
1837502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall};
1847502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
1857502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall/// A range of const statement iterators.
1867502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall///
1877502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall/// This class provides some extra functionality beyond std::pair
1887502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall/// in order to allow the following idiom:
1897502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall///   for (ConstStmtRange range = stmt->children(); range; ++range)
1907502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCallstruct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> {
1917502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  ConstStmtRange() {}
1927502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  ConstStmtRange(const ConstStmtIterator &begin,
1937502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall                 const ConstStmtIterator &end)
1947502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
1957502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  ConstStmtRange(const StmtRange &range)
1967502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    : std::pair<ConstStmtIterator,ConstStmtIterator>(range.first, range.second)
1977502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  {}
1987502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  ConstStmtRange(const StmtIterator &begin, const StmtIterator &end)
1997502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {}
2007502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
2017502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  bool empty() const { return first == second; }
2027502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  operator bool() const { return !empty(); }
2037502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
2047502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  const Stmt *operator->() const { return first.operator->(); }
2057502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  const Stmt *operator*() const { return first.operator*(); }
2067502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
2077502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  ConstStmtRange &operator++() {
2087502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    assert(!empty() && "incrementing on empty range");
2097502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    ++first;
2107502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return *this;
2117502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
2127502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
2137502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  ConstStmtRange operator++(int) {
2147502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    assert(!empty() && "incrementing on empty range");
2157502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    ConstStmtRange copy = *this;
2167502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    ++first;
2177502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return copy;
2187502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
2197502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall
2207502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  friend const ConstStmtIterator &begin(const ConstStmtRange &range) {
2217502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return range.first;
2227502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
2237502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  friend const ConstStmtIterator &end(const ConstStmtRange &range) {
2247502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall    return range.second;
2257502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall  }
2267502c1d3ce8bb97bcc4f7bebef507040bd93b26fJohn McCall};
22763c00d7f35fa060c0a446c9df3a4402d9c7757feJohn McCall
2289caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek} // end namespace clang
2299caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek
2309caf8b1ca6beb254f420dada3c0e94d5ef027f58Ted Kremenek#endif
231