[C++11] Sink the iterator over a Value's users into the Value type
authorChandler Carruth <chandlerc@gmail.com>
Wed, 5 Mar 2014 01:50:35 +0000 (01:50 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Wed, 5 Mar 2014 01:50:35 +0000 (01:50 +0000)
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

include/llvm/IR/CallSite.h
include/llvm/IR/Instructions.h
include/llvm/IR/Use.h
include/llvm/IR/Value.h

index 8c64099d577c54347931922737ed23c5b3b40111..393bb9a5bb2a83e13e5eee8e570d9cbd2636948a 100644 (file)
@@ -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!");
index 2a2c4c69d331484fdc3214bb79b878daabb8bead..24912d7d5c93f817a04e90e7f4ed802b59a42ac1 100644 (file)
@@ -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());
   }
 
index 37967f8c0232f0b30c24e2116ea220ff2f1bffb5..340572a20b383898ef8762a53679a45263ad9a35 100644 (file)
@@ -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)
 
index f1945020d508eeaad7c02e46e9ddd3f690426d8a..b2ed39e917b5538a9703fb738fc81f6316aeb6cc 100644 (file)
@@ -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