diff options
-rw-r--r-- | AST/ExprCXX.cpp | 2 | ||||
-rw-r--r-- | AST/Stmt.cpp | 2 | ||||
-rw-r--r-- | AST/StmtIterator.cpp | 27 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 3 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 14 | ||||
-rw-r--r-- | include/clang/AST/StmtGraphTraits.h | 4 | ||||
-rw-r--r-- | include/clang/AST/StmtIterator.h | 101 |
7 files changed, 142 insertions, 11 deletions
diff --git a/AST/ExprCXX.cpp b/AST/ExprCXX.cpp index 093c37e357..74d471edde 100644 --- a/AST/ExprCXX.cpp +++ b/AST/ExprCXX.cpp @@ -25,7 +25,7 @@ Stmt::child_iterator CXXCastExpr::child_begin() { } Stmt::child_iterator CXXCastExpr::child_end() { - return child_begin()+1; + return ++child_begin(); } // CXXBoolLiteralExpr diff --git a/AST/Stmt.cpp b/AST/Stmt.cpp index 6768705cee..c9a86ed28b 100644 --- a/AST/Stmt.cpp +++ b/AST/Stmt.cpp @@ -168,7 +168,7 @@ Stmt::child_iterator IndirectGotoStmt::child_begin() { return reinterpret_cast<Stmt**>(&Target); } -Stmt::child_iterator IndirectGotoStmt::child_end() { return child_begin()+1; } +Stmt::child_iterator IndirectGotoStmt::child_end() { return ++child_begin(); } // ContinueStmt Stmt::child_iterator ContinueStmt::child_begin() { return NULL; } diff --git a/AST/StmtIterator.cpp b/AST/StmtIterator.cpp new file mode 100644 index 0000000000..aca1f81095 --- /dev/null +++ b/AST/StmtIterator.cpp @@ -0,0 +1,27 @@ +//===--- StmtIterator.cpp - Iterators for Statements ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines internal methods for StmtIterator. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/StmtIterator.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Decl.h" + +using namespace clang; + +void StmtIterator::NextDecl() { assert(false); } +void StmtIterator::PrevDecl() { assert(false); } + +Stmt*& StmtIterator::GetInitializer() const { + assert (D && isa<VarDecl>(D)); + assert (cast<VarDecl>(D)->Init); + return reinterpret_cast<Stmt*&>(cast<VarDecl>(D)->Init); +} diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 4fe9f75390..41094a1ff9 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -268,7 +268,8 @@ protected: : ValueDecl(DK, L, Id, T, PrevDecl), Init(0) { SClass = SC; } private: StorageClass SClass; - Expr *Init; + Expr *Init; + friend class StmtIterator; }; /// BlockVarDecl - Represent a local variable declaration. diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 0aadb079a4..e5cc11163f 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_STMT_H #include "clang/Basic/SourceLocation.h" +#include "clang/AST/StmtIterator.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/iterator" #include <iosfwd> @@ -95,23 +96,24 @@ public: /// Child Iterators: All subclasses must implement child_begin and child_end /// to permit easy iteration over the substatements/subexpessions of an /// AST node. This permits easy iteration over all nodes in the AST. - typedef Stmt** child_iterator; - typedef Stmt* const * const_child_iterator; + typedef StmtIterator child_iterator; + typedef ConstStmtIterator const_child_iterator; typedef std::reverse_iterator<child_iterator> - reverse_child_iterator; + reverse_child_iterator; + typedef std::reverse_iterator<const_child_iterator> - const_reverse_child_iterator; + const_reverse_child_iterator; virtual child_iterator child_begin() = 0; virtual child_iterator child_end() = 0; const_child_iterator child_begin() const { - return (child_iterator) const_cast<Stmt*>(this)->child_begin(); + return const_child_iterator(const_cast<Stmt*>(this)->child_begin()); } const_child_iterator child_end() const { - return (child_iterator) const_cast<Stmt*>(this)->child_end(); + return const_child_iterator(const_cast<Stmt*>(this)->child_end()); } reverse_child_iterator child_rbegin() { diff --git a/include/clang/AST/StmtGraphTraits.h b/include/clang/AST/StmtGraphTraits.h index 43f594b098..80abc80866 100644 --- a/include/clang/AST/StmtGraphTraits.h +++ b/include/clang/AST/StmtGraphTraits.h @@ -60,12 +60,12 @@ template <> struct GraphTraits<const clang::Stmt*> { static inline ChildIteratorType child_begin(NodeType* N) { if (N) return N->child_begin(); - else return NULL; + else return ChildIteratorType(NULL); } static inline ChildIteratorType child_end(NodeType* N) { if (N) return N->child_end(); - else return NULL; + else return ChildIteratorType(NULL); } static nodes_iterator nodes_begin(const clang::Stmt* S) { diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h new file mode 100644 index 0000000000..5281ccfcb9 --- /dev/null +++ b/include/clang/AST/StmtIterator.h @@ -0,0 +1,101 @@ +//===--- StmtIterator.h - Iterators for Statements ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Ted Kremenek and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the StmtIterator and ConstStmtIterator classes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_STMT_ITR_H +#define LLVM_CLANG_AST_STMT_ITR_H + +#include "llvm/ADT/iterator" + +namespace clang { + +class Stmt; +class ScopedDecl; + +class StmtIterator : public bidirectional_iterator<Stmt*, ptrdiff_t> { + Stmt** S; + ScopedDecl* D; + + void NextDecl(); + void PrevDecl(); + Stmt*& GetInitializer() const; +public: + StmtIterator(Stmt** s, ScopedDecl* d = NULL) : S(s), D(d) {} + + StmtIterator& operator++() { + if (D) NextDecl(); + else ++S; + + return *this; + } + + StmtIterator operator++(int) { + StmtIterator tmp = *this; + operator++(); + return tmp; + } + + StmtIterator& operator--() { + if (D) PrevDecl(); + else --S; + + return *this; + } + + StmtIterator operator--(int) { + StmtIterator tmp = *this; + operator--(); + return tmp; + } + + reference operator*() const { return D ? GetInitializer() : *S; } + pointer operator->() const { return D ? &GetInitializer() : S; } + + bool operator==(const StmtIterator& RHS) const { + return D == RHS.D && S == RHS.S; + } + + bool operator!=(const StmtIterator& RHS) const { + return D != RHS.D || S != RHS.S; + } +}; + +class ConstStmtIterator: public bidirectional_iterator<const Stmt*, ptrdiff_t> { + StmtIterator I; +public: + explicit ConstStmtIterator(const StmtIterator& i) : I(i) {} + + ConstStmtIterator& operator++() { ++I; return *this; } + ConstStmtIterator& operator--() { --I; return *this; } + + ConstStmtIterator operator++(int) { + ConstStmtIterator tmp = *this; + operator++(); + return tmp; + } + + ConstStmtIterator operator--(int) { + ConstStmtIterator tmp = *this; + operator--(); + return tmp; + } + + reference operator*() const { return const_cast<reference>(*I); } + pointer operator->() const { return const_cast<pointer>(I.operator->()); } + + bool operator==(const ConstStmtIterator& RHS) const { return I == RHS.I; } + bool operator!=(const ConstStmtIterator& RHS) const { return I != RHS.I; } +}; + +} // end namespace clang + +#endif |