From 669c9a28fa4be35e6b6322aa7f2f3b2968189b80 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 18:25:48 +0000 Subject: [PATCH] Split specific_decl_iterator, which had a run-time field for determining what decls are acceptable, into specific_decl_iterator (in which all decls matching the SpecificDecl type requirements are acceptable) and filtered_decl_iterator (which also does a run-time check via a member pointer non-type template parameter). This saves some space in the iterators. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63535 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclBase.h | 97 +++++++++++++++++++++++++++++------- include/clang/AST/DeclObjC.h | 16 +++--- 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 2c15c870c3..0175af6651 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -630,13 +630,9 @@ public: /// specific_decl_iterator - Iterates over a subrange of /// declarations stored in a DeclContext, providing only those that - /// are of type SpecificDecl (or a class derived from it) and, - /// optionally, that meet some additional run-time criteria. This + /// are of type SpecificDecl (or a class derived from it). This /// iterator is used, for example, to provide iteration over just - /// the fields within a RecordDecl (with SpecificDecl = FieldDecl) - /// or the instance methods within an Objective-C interface (with - /// SpecificDecl = ObjCMethodDecl and using - /// ObjCMethodDecl::isInstanceMethod as the run-time criteria). + /// the fields within a RecordDecl (with SpecificDecl = FieldDecl). template class specific_decl_iterator { /// Current - The current, underlying declaration iterator, which @@ -644,18 +640,11 @@ public: /// type SpecificDecl. DeclContext::decl_iterator Current; - /// Acceptable - If non-NULL, points to a member function that - /// will determine if a particular declaration of type - /// SpecificDecl should be visited by the iteration. - bool (SpecificDecl::*Acceptable)() const; - /// SkipToNextDecl - Advances the current position up to the next /// declaration of type SpecificDecl that also meets the criteria /// required by Acceptable. void SkipToNextDecl() { - while (*Current && - (!isa(*Current) || - (Acceptable && !(cast(*Current)->*Acceptable)()))) + while (*Current && !isa(*Current)) ++Current; } @@ -667,7 +656,7 @@ public: difference_type; typedef std::forward_iterator_tag iterator_category; - specific_decl_iterator() : Current(), Acceptable(0) { } + specific_decl_iterator() : Current() { } /// specific_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -677,9 +666,7 @@ public: /// of iterators. For example, if you want Objective-C instance /// methods, SpecificDecl will be ObjCMethodDecl and A will be /// &ObjCMethodDecl::isInstanceMethod. - specific_decl_iterator(DeclContext::decl_iterator C, - bool (SpecificDecl::*A)() const = 0) - : Current(C), Acceptable(A) { + explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) { SkipToNextDecl(); } @@ -709,6 +696,80 @@ public: } }; + /// \brief Iterates over a filtered subrange of declarations stored + /// in a DeclContext. + /// + /// This iterator visits only those declarations that are of type + /// SpecificDecl (or a class derived from it) and that meet some + /// additional run-time criteria. This iterator is used, for + /// example, to provide access to the instance methods within an + /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and + /// Acceptable = ObjCMethodDecl::isInstanceMethod). + template + class filtered_decl_iterator { + /// Current - The current, underlying declaration iterator, which + /// will either be NULL or will point to a declaration of + /// type SpecificDecl. + DeclContext::decl_iterator Current; + + /// SkipToNextDecl - Advances the current position up to the next + /// declaration of type SpecificDecl that also meets the criteria + /// required by Acceptable. + void SkipToNextDecl() { + while (*Current && + (!isa(*Current) || + (Acceptable && !(cast(*Current)->*Acceptable)()))) + ++Current; + } + + public: + typedef SpecificDecl* value_type; + typedef SpecificDecl* reference; + typedef SpecificDecl* pointer; + typedef std::iterator_traits::difference_type + difference_type; + typedef std::forward_iterator_tag iterator_category; + + filtered_decl_iterator() : Current() { } + + /// specific_decl_iterator - Construct a new iterator over a + /// subset of the declarations the range [C, + /// end-of-declarations). If A is non-NULL, it is a pointer to a + /// member function of SpecificDecl that should return true for + /// all of the SpecificDecl instances that will be in the subset + /// of iterators. For example, if you want Objective-C instance + /// methods, SpecificDecl will be ObjCMethodDecl and A will be + /// &ObjCMethodDecl::isInstanceMethod. + explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) { + SkipToNextDecl(); + } + + reference operator*() const { return cast(*Current); } + pointer operator->() const { return cast(*Current); } + + filtered_decl_iterator& operator++() { + ++Current; + SkipToNextDecl(); + return *this; + } + + filtered_decl_iterator operator++(int) { + filtered_decl_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool + operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) { + return x.Current == y.Current; + } + + friend bool + operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) { + return x.Current != y.Current; + } + }; + /// @brief Add the declaration D into this context. /// /// This routine should be invoked when the declaration D has first diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index cda9bddbcc..c77cc15e75 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -279,20 +279,24 @@ public: return method_iterator(decls_end()); } - typedef method_iterator instmeth_iterator; + typedef filtered_decl_iterator + instmeth_iterator; instmeth_iterator instmeth_begin() const { - return instmeth_iterator(decls_begin(), &ObjCMethodDecl::isInstanceMethod); + return instmeth_iterator(decls_begin()); } instmeth_iterator instmeth_end() const { - return instmeth_iterator(decls_end(), &ObjCMethodDecl::isInstanceMethod); + return instmeth_iterator(decls_end()); } - typedef method_iterator classmeth_iterator; + typedef filtered_decl_iterator + classmeth_iterator; classmeth_iterator classmeth_begin() const { - return classmeth_iterator(decls_begin(), &ObjCMethodDecl::isClassMethod); + return classmeth_iterator(decls_begin()); } classmeth_iterator classmeth_end() const { - return classmeth_iterator(decls_end(), &ObjCMethodDecl::isClassMethod); + return classmeth_iterator(decls_end()); } // Get the local instance/class method declared in this interface. -- 2.40.0