diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-03-05 01:50:35 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-03-05 01:50:35 +0000 |
commit | d1fe495464e4abc384565813cbf1cb8b130e5a6d (patch) | |
tree | 6e1222dc004b8b8d75d99d363c4536a1dc0a59c9 /include/llvm/IR | |
parent | 8b3fad9343111eec5931492fbd812ad578c71089 (diff) | |
download | llvm-d1fe495464e4abc384565813cbf1cb8b130e5a6d.tar.gz llvm-d1fe495464e4abc384565813cbf1cb8b130e5a6d.tar.bz2 llvm-d1fe495464e4abc384565813cbf1cb8b130e5a6d.tar.xz |
[C++11] Sink the iterator over a Value's users into the Value type
itself and teach it to convert between the non-const and const variants.
De-templatetize its usage in APIs to just use the const variant which
always works for those use cases. Also, rename its implementation to
reflect that it is an iterator over *users* not over *uses*.
This is a step toward providing both iterator and range support for
walking the *uses* distinct from the *users*. In a subsequent patch this
will get renamed to make it clear that this is an adaptor over the
fundamental use iterator.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202923 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/IR')
-rw-r--r-- | include/llvm/IR/CallSite.h | 4 | ||||
-rw-r--r-- | include/llvm/IR/Instructions.h | 3 | ||||
-rw-r--r-- | include/llvm/IR/Use.h | 50 | ||||
-rw-r--r-- | include/llvm/IR/Value.h | 62 |
4 files changed, 60 insertions, 59 deletions
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h index 8c64099d57..393bb9a5bb 100644 --- a/include/llvm/IR/CallSite.h +++ b/include/llvm/IR/CallSite.h @@ -104,7 +104,7 @@ public: /// isCallee - Determine whether the passed iterator points to the /// callee operand's Use. /// - bool isCallee(value_use_iterator<UserTy> UI) const { + bool isCallee(Value::const_use_iterator UI) const { return getCallee() == &UI.getUse(); } @@ -121,7 +121,7 @@ public: /// Given a value use iterator, returns the argument that corresponds to it. /// Iterator must actually correspond to an argument. - unsigned getArgumentNo(value_use_iterator<UserTy> I) const { + unsigned getArgumentNo(Value::const_use_iterator I) const { assert(getInstruction() && "Not a call or invoke instruction!"); assert(arg_begin() <= &I.getUse() && &I.getUse() < arg_end() && "Argument # out of range!"); diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 2a2c4c69d3..24912d7d5c 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -2100,8 +2100,7 @@ public: /// getIncomingBlock - Return incoming basic block corresponding /// to value use iterator. /// - template <typename U> - BasicBlock *getIncomingBlock(value_use_iterator<U> I) const { + BasicBlock *getIncomingBlock(Value::const_use_iterator I) const { return getIncomingBlock(I.getUse()); } diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h index 37967f8c02..340572a20b 100644 --- a/include/llvm/IR/Use.h +++ b/include/llvm/IR/Use.h @@ -165,56 +165,6 @@ template <> struct simplify_type<const Use> { static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); } }; -template<typename UserTy> // UserTy == 'User' or 'const User' -class value_use_iterator : public std::iterator<std::forward_iterator_tag, - UserTy*, ptrdiff_t> { - typedef std::iterator<std::forward_iterator_tag, UserTy*, ptrdiff_t> super; - typedef value_use_iterator<UserTy> _Self; - - Use *U; - explicit value_use_iterator(Use *u) : U(u) {} - friend class Value; -public: - typedef typename super::reference reference; - typedef typename super::pointer pointer; - - value_use_iterator() {} - - bool operator==(const _Self &x) const { - return U == x.U; - } - bool operator!=(const _Self &x) const { - return !operator==(x); - } - - /// \brief Returns true if this iterator is equal to use_end() on the value. - bool atEnd() const { return U == 0; } - - // Iterator traversal: forward iteration only - _Self &operator++() { // Preincrement - assert(U && "Cannot increment end iterator!"); - U = U->getNext(); - return *this; - } - _Self operator++(int) { // Postincrement - _Self tmp = *this; ++*this; return tmp; - } - - // Retrieve a pointer to the current User. - UserTy *operator*() const { - assert(U && "Cannot dereference end iterator!"); - return U->getUser(); - } - - UserTy *operator->() const { return operator*(); } - - Use &getUse() const { return *U; } - - /// \brief Return the operand # of this use in its User. - /// FIXME: Replace all callers with a direct call to Use::getOperandNo. - unsigned getOperandNo() const { return U->getOperandNo(); } -}; - // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef) diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index f1945020d5..b2ed39e917 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -75,6 +75,58 @@ protected: unsigned char SubclassOptionalData : 7; private: + template <typename UserTy> // UserTy == 'User' or 'const User' + class user_iterator_impl + : public std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> { + typedef std::iterator<std::forward_iterator_tag, UserTy *, ptrdiff_t> super; + + Use *U; + explicit user_iterator_impl(Use *u) : U(u) {} + friend class Value; + + public: + typedef typename super::reference reference; + typedef typename super::pointer pointer; + + user_iterator_impl() {} + + bool operator==(const user_iterator_impl &x) const { return U == x.U; } + bool operator!=(const user_iterator_impl &x) const { return !operator==(x); } + + /// \brief Returns true if this iterator is equal to use_end() on the value. + bool atEnd() const { return U == 0; } + + // Iterator traversal: forward iteration only + user_iterator_impl &operator++() { // Preincrement + assert(U && "Cannot increment end iterator!"); + U = U->getNext(); + return *this; + } + user_iterator_impl operator++(int) { // Postincrement + auto tmp = *this; + ++*this; + return tmp; + } + + // Retrieve a pointer to the current User. + UserTy *operator*() const { + assert(U && "Cannot dereference end iterator!"); + return U->getUser(); + } + + UserTy *operator->() const { return operator*(); } + + operator user_iterator_impl<const UserTy>() const { + return user_iterator_impl<const UserTy>(U); + } + + Use &getUse() const { return *U; } + + /// \brief Return the operand # of this use in its User. + /// FIXME: Replace all callers with a direct call to Use::getOperandNo. + unsigned getOperandNo() const { return U->getOperandNo(); } + }; + /// SubclassData - This member is defined by this class, but is not used for /// anything. Subclasses can use it to hold whatever state they find useful. /// This field is initialized to zero by the ctor. @@ -151,16 +203,16 @@ public: //---------------------------------------------------------------------- // Methods for handling the chain of uses of this Value. // - typedef value_use_iterator<User> use_iterator; - typedef value_use_iterator<const User> const_use_iterator; - bool use_empty() const { return UseList == 0; } + + typedef user_iterator_impl<User> use_iterator; + typedef user_iterator_impl<const User> const_use_iterator; use_iterator use_begin() { return use_iterator(UseList); } const_use_iterator use_begin() const { return const_use_iterator(UseList); } use_iterator use_end() { return use_iterator(0); } const_use_iterator use_end() const { return const_use_iterator(0); } - User *use_back() { return *use_begin(); } - const User *use_back() const { return *use_begin(); } + User *use_back() { return *use_begin(); } + const User *use_back() const { return *use_begin(); } /// hasOneUse - Return true if there is exactly one user of this value. This /// is specialized because it is a common request and does not require |