<div dir="ltr"><div dir="ltr" class="gmail_msg">Seeing some failures - missed negation I guess so I added some '!' in r294357.<br class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><font face="monospace" class="gmail_msg">IListIteratorTest.cpp:162:3: error: static_assert failed "unexpected implicit conversion"</font></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><font face="monospace" class="gmail_msg">  static_assert(std::is_convertible<iterator, reverse_iterator>::value,</font></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><font face="monospace" class="gmail_msg">  ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">IListIteratorTest.cpp:164:3: error: static_assert failed "unexpected implicit conversion"</font></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><font face="monospace" class="gmail_msg">  static_assert(std::is_convertible<reverse_iterator, iterator>::value,</font></div></div><div dir="ltr" class="gmail_msg"><div class="gmail_msg"><font face="monospace" class="gmail_msg">  ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">IListIteratorTest.cpp:166:3: error: static_assert failed "unexpected implicit conversion"</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">  static_assert(</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">  ^</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">IListIteratorTest.cpp:169:3: error: static_assert failed "unexpected implicit conversion"</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">  static_assert(</font></div><div class="gmail_msg"><font face="monospace" class="gmail_msg">  ^</font></div></div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Tue, Feb 7, 2017 at 1:15 PM Duncan P. N. Exon Smith via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br class="gmail_msg">
Date: Tue Feb  7 15:03:50 2017<br class="gmail_msg">
New Revision: 294349<br class="gmail_msg">
<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=294349&view=rev" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project?rev=294349&view=rev</a><br class="gmail_msg">
Log:<br class="gmail_msg">
ADT: Add explicit conversions for reverse ilist iterators<br class="gmail_msg">
<br class="gmail_msg">
Add explicit conversions between forward and reverse ilist iterators.<br class="gmail_msg">
These follow the conversion conventions of std::reverse_iterator, which<br class="gmail_msg">
are off-by-one: the newly-constructed "reverse" iterator dereferences to<br class="gmail_msg">
the previous node of the one sent in.  This has the benefit of<br class="gmail_msg">
converting reverse ranges in place:<br class="gmail_msg">
  - If [I, E) is a valid range,<br class="gmail_msg">
  - then [reverse(E), reverse(I)) gives the same range in reverse order.<br class="gmail_msg">
<br class="gmail_msg">
ilist_iterator::getReverse() is unchanged: it returns a reverse iterator<br class="gmail_msg">
to the *same* node.<br class="gmail_msg">
<br class="gmail_msg">
Modified:<br class="gmail_msg">
    llvm/trunk/include/llvm/ADT/ilist_iterator.h<br class="gmail_msg">
    llvm/trunk/include/llvm/CodeGen/MachineInstrBundleIterator.h<br class="gmail_msg">
    llvm/trunk/unittests/ADT/IListIteratorTest.cpp<br class="gmail_msg">
    llvm/trunk/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/ADT/ilist_iterator.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist_iterator.h?rev=294349&r1=294348&r2=294349&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist_iterator.h?rev=294349&r1=294348&r2=294349&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/ADT/ilist_iterator.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/ADT/ilist_iterator.h Tue Feb  7 15:03:50 2017<br class="gmail_msg">
@@ -102,10 +102,23 @@ public:<br class="gmail_msg">
     return *this;<br class="gmail_msg">
   }<br class="gmail_msg">
<br class="gmail_msg">
-  /// Convert from an iterator to its reverse.<br class="gmail_msg">
+  /// Explicit conversion between forward/reverse iterators.<br class="gmail_msg">
   ///<br class="gmail_msg">
-  /// TODO: Roll this into the implicit constructor once we're sure that no one<br class="gmail_msg">
-  /// is relying on the std::reverse_iterator off-by-one semantics.<br class="gmail_msg">
+  /// Translate between forward and reverse iterators without changing range<br class="gmail_msg">
+  /// boundaries.  The resulting iterator will dereference (and have a handle)<br class="gmail_msg">
+  /// to the previous node, which is somewhat unexpected; but converting the<br class="gmail_msg">
+  /// two endpoints in a range will give the same range in reverse.<br class="gmail_msg">
+  ///<br class="gmail_msg">
+  /// This matches std::reverse_iterator conversions.<br class="gmail_msg">
+  explicit ilist_iterator(<br class="gmail_msg">
+      const ilist_iterator<OptionsT, !IsReverse, IsConst> &RHS)<br class="gmail_msg">
+      : ilist_iterator(++RHS.getReverse()) {}<br class="gmail_msg">
+<br class="gmail_msg">
+  /// Get a reverse iterator to the same node.<br class="gmail_msg">
+  ///<br class="gmail_msg">
+  /// Gives a reverse iterator that will dereference (and have a handle) to the<br class="gmail_msg">
+  /// same node.  Converting the endpoint iterators in a range will give a<br class="gmail_msg">
+  /// different range; for range operations, use the explicit conversions.<br class="gmail_msg">
   ilist_iterator<OptionsT, !IsReverse, IsConst> getReverse() const {<br class="gmail_msg">
     if (NodePtr)<br class="gmail_msg">
       return ilist_iterator<OptionsT, !IsReverse, IsConst>(*NodePtr);<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/include/llvm/CodeGen/MachineInstrBundleIterator.h<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstrBundleIterator.h?rev=294349&r1=294348&r2=294349&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstrBundleIterator.h?rev=294349&r1=294348&r2=294349&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/include/llvm/CodeGen/MachineInstrBundleIterator.h (original)<br class="gmail_msg">
+++ llvm/trunk/include/llvm/CodeGen/MachineInstrBundleIterator.h Tue Feb  7 15:03:50 2017<br class="gmail_msg">
@@ -153,6 +153,18 @@ public:<br class="gmail_msg">
       : MII(I.getInstrIterator()) {}<br class="gmail_msg">
   MachineInstrBundleIterator() : MII(nullptr) {}<br class="gmail_msg">
<br class="gmail_msg">
+  /// Explicit conversion between forward/reverse iterators.<br class="gmail_msg">
+  ///<br class="gmail_msg">
+  /// Translate between forward and reverse iterators without changing range<br class="gmail_msg">
+  /// boundaries.  The resulting iterator will dereference (and have a handle)<br class="gmail_msg">
+  /// to the previous node, which is somewhat unexpected; but converting the<br class="gmail_msg">
+  /// two endpoints in a range will give the same range in reverse.<br class="gmail_msg">
+  ///<br class="gmail_msg">
+  /// This matches std::reverse_iterator conversions.<br class="gmail_msg">
+  explicit MachineInstrBundleIterator(<br class="gmail_msg">
+      const MachineInstrBundleIterator<Ty, !IsReverse> &I)<br class="gmail_msg">
+      : MachineInstrBundleIterator(++I.getReverse()) {}<br class="gmail_msg">
+<br class="gmail_msg">
   /// Get the bundle iterator for the given instruction's bundle.<br class="gmail_msg">
   static MachineInstrBundleIterator getAtBundleBegin(instr_iterator MI) {<br class="gmail_msg">
     return MachineInstrBundleIteratorHelper<IsReverse>::getBundleBegin(MI);<br class="gmail_msg">
@@ -258,6 +270,11 @@ public:<br class="gmail_msg">
<br class="gmail_msg">
   nonconst_iterator getNonConstIterator() const { return MII.getNonConst(); }<br class="gmail_msg">
<br class="gmail_msg">
+  /// Get a reverse iterator to the same node.<br class="gmail_msg">
+  ///<br class="gmail_msg">
+  /// Gives a reverse iterator that will dereference (and have a handle) to the<br class="gmail_msg">
+  /// same node.  Converting the endpoint iterators in a range will give a<br class="gmail_msg">
+  /// different range; for range operations, use the explicit conversions.<br class="gmail_msg">
   reverse_iterator getReverse() const { return MII.getReverse(); }<br class="gmail_msg">
 };<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/unittests/ADT/IListIteratorTest.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListIteratorTest.cpp?rev=294349&r1=294348&r2=294349&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/IListIteratorTest.cpp?rev=294349&r1=294348&r2=294349&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/unittests/ADT/IListIteratorTest.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/unittests/ADT/IListIteratorTest.cpp Tue Feb  7 15:03:50 2017<br class="gmail_msg">
@@ -131,4 +131,44 @@ TEST(IListIteratorTest, CheckEraseRevers<br class="gmail_msg">
   EXPECT_EQ(L.rend(), RI);<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+TEST(IListIteratorTest, ReverseConstructor) {<br class="gmail_msg">
+  simple_ilist<Node> L;<br class="gmail_msg">
+  const simple_ilist<Node> &CL = L;<br class="gmail_msg">
+  Node A, B;<br class="gmail_msg">
+  L.insert(L.end(), A);<br class="gmail_msg">
+  L.insert(L.end(), B);<br class="gmail_msg">
+<br class="gmail_msg">
+  // Save typing.<br class="gmail_msg">
+  typedef simple_ilist<Node>::iterator iterator;<br class="gmail_msg">
+  typedef simple_ilist<Node>::reverse_iterator reverse_iterator;<br class="gmail_msg">
+  typedef simple_ilist<Node>::const_iterator const_iterator;<br class="gmail_msg">
+  typedef simple_ilist<Node>::const_reverse_iterator const_reverse_iterator;<br class="gmail_msg">
+<br class="gmail_msg">
+  // Check conversion values.<br class="gmail_msg">
+  EXPECT_EQ(L.begin(), iterator(L.rend()));<br class="gmail_msg">
+  EXPECT_EQ(++L.begin(), iterator(++L.rbegin()));<br class="gmail_msg">
+  EXPECT_EQ(L.end(), iterator(L.rbegin()));<br class="gmail_msg">
+  EXPECT_EQ(L.rbegin(), reverse_iterator(L.end()));<br class="gmail_msg">
+  EXPECT_EQ(++L.rbegin(), reverse_iterator(++L.begin()));<br class="gmail_msg">
+  EXPECT_EQ(L.rend(), reverse_iterator(L.begin()));<br class="gmail_msg">
+<br class="gmail_msg">
+  // Check const iterator constructors.<br class="gmail_msg">
+  EXPECT_EQ(CL.begin(), const_iterator(L.rend()));<br class="gmail_msg">
+  EXPECT_EQ(CL.begin(), const_iterator(CL.rend()));<br class="gmail_msg">
+  EXPECT_EQ(CL.rbegin(), const_reverse_iterator(L.end()));<br class="gmail_msg">
+  EXPECT_EQ(CL.rbegin(), const_reverse_iterator(CL.end()));<br class="gmail_msg">
+<br class="gmail_msg">
+  // Confirm lack of implicit conversions.<br class="gmail_msg">
+  static_assert(std::is_convertible<iterator, reverse_iterator>::value,<br class="gmail_msg">
+                "unexpected implicit conversion");<br class="gmail_msg">
+  static_assert(std::is_convertible<reverse_iterator, iterator>::value,<br class="gmail_msg">
+                "unexpected implicit conversion");<br class="gmail_msg">
+  static_assert(<br class="gmail_msg">
+      std::is_convertible<const_iterator, const_reverse_iterator>::value,<br class="gmail_msg">
+      "unexpected implicit conversion");<br class="gmail_msg">
+  static_assert(<br class="gmail_msg">
+      std::is_convertible<const_reverse_iterator, const_iterator>::value,<br class="gmail_msg">
+      "unexpected implicit conversion");<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 } // end namespace<br class="gmail_msg">
<br class="gmail_msg">
Modified: llvm/trunk/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp<br class="gmail_msg">
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp?rev=294349&r1=294348&r2=294349&view=diff" rel="noreferrer" class="gmail_msg" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp?rev=294349&r1=294348&r2=294349&view=diff</a><br class="gmail_msg">
==============================================================================<br class="gmail_msg">
--- llvm/trunk/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp (original)<br class="gmail_msg">
+++ llvm/trunk/unittests/CodeGen/MachineInstrBundleIteratorTest.cpp Tue Feb  7 15:03:50 2017<br class="gmail_msg">
@@ -130,4 +130,68 @@ TEST(MachineInstrBundleIteratorTest, Com<br class="gmail_msg">
   ASSERT_TRUE(CI != CMBI.getIterator());<br class="gmail_msg">
 }<br class="gmail_msg">
<br class="gmail_msg">
+struct MyUnbundledInstr<br class="gmail_msg">
+    : ilist_node<MyUnbundledInstr, ilist_sentinel_tracking<true>> {<br class="gmail_msg">
+  bool isBundledWithPred() const { return false; }<br class="gmail_msg">
+  bool isBundledWithSucc() const { return false; }<br class="gmail_msg">
+};<br class="gmail_msg">
+typedef MachineInstrBundleIterator<MyUnbundledInstr> unbundled_iterator;<br class="gmail_msg">
+typedef MachineInstrBundleIterator<const MyUnbundledInstr><br class="gmail_msg">
+    const_unbundled_iterator;<br class="gmail_msg">
+typedef MachineInstrBundleIterator<MyUnbundledInstr, true><br class="gmail_msg">
+    reverse_unbundled_iterator;<br class="gmail_msg">
+typedef MachineInstrBundleIterator<const MyUnbundledInstr, true><br class="gmail_msg">
+    const_reverse_unbundled_iterator;<br class="gmail_msg">
+<br class="gmail_msg">
+TEST(MachineInstrBundleIteratorTest, ReverseConstructor) {<br class="gmail_msg">
+  simple_ilist<MyUnbundledInstr, ilist_sentinel_tracking<true>> L;<br class="gmail_msg">
+  const auto &CL = L;<br class="gmail_msg">
+  MyUnbundledInstr A, B;<br class="gmail_msg">
+  L.insert(L.end(), A);<br class="gmail_msg">
+  L.insert(L.end(), B);<br class="gmail_msg">
+<br class="gmail_msg">
+  // Save typing.<br class="gmail_msg">
+  typedef MachineInstrBundleIterator<MyUnbundledInstr> iterator;<br class="gmail_msg">
+  typedef MachineInstrBundleIterator<MyUnbundledInstr, true> reverse_iterator;<br class="gmail_msg">
+  typedef MachineInstrBundleIterator<const MyUnbundledInstr> const_iterator;<br class="gmail_msg">
+  typedef MachineInstrBundleIterator<const MyUnbundledInstr, true><br class="gmail_msg">
+      const_reverse_iterator;<br class="gmail_msg">
+<br class="gmail_msg">
+  // Convert to bundle iterators.<br class="gmail_msg">
+  auto begin = [&]() -> iterator { return L.begin(); };<br class="gmail_msg">
+  auto end = [&]() -> iterator { return L.end(); };<br class="gmail_msg">
+  auto rbegin = [&]() -> reverse_iterator { return L.rbegin(); };<br class="gmail_msg">
+  auto rend = [&]() -> reverse_iterator { return L.rend(); };<br class="gmail_msg">
+  auto cbegin = [&]() -> const_iterator { return CL.begin(); };<br class="gmail_msg">
+  auto cend = [&]() -> const_iterator { return CL.end(); };<br class="gmail_msg">
+  auto crbegin = [&]() -> const_reverse_iterator { return CL.rbegin(); };<br class="gmail_msg">
+  auto crend = [&]() -> const_reverse_iterator { return CL.rend(); };<br class="gmail_msg">
+<br class="gmail_msg">
+  // Check conversion values.<br class="gmail_msg">
+  EXPECT_EQ(begin(), iterator(rend()));<br class="gmail_msg">
+  EXPECT_EQ(++begin(), iterator(++rbegin()));<br class="gmail_msg">
+  EXPECT_EQ(end(), iterator(rbegin()));<br class="gmail_msg">
+  EXPECT_EQ(rbegin(), reverse_iterator(end()));<br class="gmail_msg">
+  EXPECT_EQ(++rbegin(), reverse_iterator(++begin()));<br class="gmail_msg">
+  EXPECT_EQ(rend(), reverse_iterator(begin()));<br class="gmail_msg">
+<br class="gmail_msg">
+  // Check const iterator constructors.<br class="gmail_msg">
+  EXPECT_EQ(cbegin(), const_iterator(rend()));<br class="gmail_msg">
+  EXPECT_EQ(cbegin(), const_iterator(crend()));<br class="gmail_msg">
+  EXPECT_EQ(crbegin(), const_reverse_iterator(end()));<br class="gmail_msg">
+  EXPECT_EQ(crbegin(), const_reverse_iterator(cend()));<br class="gmail_msg">
+<br class="gmail_msg">
+  // Confirm lack of implicit conversions.<br class="gmail_msg">
+  static_assert(!std::is_convertible<iterator, reverse_iterator>::value,<br class="gmail_msg">
+                "unexpected implicit conversion");<br class="gmail_msg">
+  static_assert(!std::is_convertible<reverse_iterator, iterator>::value,<br class="gmail_msg">
+                "unexpected implicit conversion");<br class="gmail_msg">
+  static_assert(<br class="gmail_msg">
+      !std::is_convertible<const_iterator, const_reverse_iterator>::value,<br class="gmail_msg">
+      "unexpected implicit conversion");<br class="gmail_msg">
+  static_assert(<br class="gmail_msg">
+      !std::is_convertible<const_reverse_iterator, const_iterator>::value,<br class="gmail_msg">
+      "unexpected implicit conversion");<br class="gmail_msg">
+}<br class="gmail_msg">
+<br class="gmail_msg">
 } // end namespace<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
_______________________________________________<br class="gmail_msg">
llvm-commits mailing list<br class="gmail_msg">
<a href="mailto:llvm-commits@lists.llvm.org" class="gmail_msg" target="_blank">llvm-commits@lists.llvm.org</a><br class="gmail_msg">
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" class="gmail_msg" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="gmail_msg">
</blockquote></div></div>