[PATCH] D49679: [DebugInfo] Have custom DWARFDie:: reverse_iterator

Pavel Labath via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 24 01:55:31 PDT 2018


labath added a comment.

In https://reviews.llvm.org/D49679#1172404, @JDevlieghere wrote:

> In https://reviews.llvm.org/D49679#1172143, @labath wrote:
>
> > What's the reason for not specializing std::reverse_iterator? AFAIK, that is officially permitted by the standard.
>
>
> What exactly would you do difference? I can see a solution where we make the current `__tmp` a class member of the iterator adapter, but maybe you have something more straightforward in mind?
>
> > This way somebody can still construct a `std::reverse_iterator<DWARFDie::iterator>` (via `make_reverse_iterator` or whatever) and get UB.
>
> That's not entirely true because it's no longer a bidirectional iterator. Regardless of the specialization, both `*++iterator` and `*--iterator` will remain UB.


Sorry I wrote the reply without looking at the patch in detail. I did not notice you demoted the iterator back to "forward". In case this is not a bidirectional operator, but a collection of two forward iterators that happen to iterate in the reverse order, the specializing std::reverse_iterator is not the right approach.

I have to admit I haven't thought about the specifics of how the reverse iterator would work until now. However, now that I think about it, I think it could be implemented as a pair of DWARFDie + bool flag. The trick would be that we store the element that we really dereference to, instead of its successor. The bool flag would be used denote the before_begin state, as we cannot represent rend() this way. The implementation would do something like:

  operator++() {
    assert(!AtEnd && "Incrementing rend");
    DWARFDie D = Die.getPreviousSibling();
    if (D)
      Die = D;
    else
      AtEnd = true;
  }
  
  operator--() {
    if (AtEnd) {
      AtEnd = false;
      return;
    }
    Die = Die.getNextSibling();
    assert(!Die.isNULL() && "Decrementing rbegin");
  }

However, if you don't need that extra complexity now, then I suppose this solution is fine too.



================
Comment at: llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp:1081-1116
+  // Make sure iterators work as expected.
+  size_t Idx = 0;
+  for (auto Child : A) {
+    switch (Idx) {
+    case 0:
+      EXPECT_EQ(Child, B);
+      break;
----------------
This will succeed even if the iterator range returns an empty sequence.

Might I suggest a shorter alternative with a more helpful error message?
```
  EXPECT_THAT(std::vector<DWARFDie>(A.begin(), A.end()),
              testing::ElementsAre(B, C, D));
```


https://reviews.llvm.org/D49679





More information about the llvm-commits mailing list