llvm.org GIT mirror llvm / f849788
[DebugInfo] Make children iterator bidirectional Make the DIE iterator bidirectional so we can move to the previous sibling of a DIE. Differential revision: https://reviews.llvm.org/D49173 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336823 91177308-0d34-0410-b5e6-96231b3b80d8 Jonas Devlieghere 1 year, 3 months ago
5 changed file(s) with 95 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
103103 /// invalid DWARFDie instance if it doesn't.
104104 DWARFDie getSibling() const;
105105
106 /// Get the previous sibling of this DIE object.
107 ///
108 /// \returns a valid DWARFDie instance if this object has a sibling or an
109 /// invalid DWARFDie instance if it doesn't.
110 DWARFDie getPreviousSibling() const;
111
106112 /// Get the first child of this DIE object.
107113 ///
108114 /// \returns a valid DWARFDie instance if this object has children or an
109115 /// invalid DWARFDie instance if it doesn't.
110116 DWARFDie getFirstChild() const;
117
118 /// Get the last child of this DIE object.
119 ///
120 /// \returns a valid null DWARFDie instance if this object has children or an
121 /// invalid DWARFDie instance if it doesn't.
122 DWARFDie getLastChild() const;
111123
112124 /// Dump the DIE and all of its attributes to the supplied stream.
113125 ///
287299 explicit attribute_iterator(DWARFDie D, bool End);
288300
289301 attribute_iterator &operator++();
302 attribute_iterator &operator--();
290303 explicit operator bool() const { return AttrValue.isValid(); }
291304 const DWARFAttribute &operator*() const { return AttrValue; }
292305 bool operator==(const attribute_iterator &X) const { return Index == X.Index; }
305318 return LHS.getOffset() < RHS.getOffset();
306319 }
307320
308 class DWARFDie::iterator : public iterator_facade_base
309 std::forward_iterator_tag,
310 const DWARFDie> {
321 class DWARFDie::iterator
322 : public iterator_facade_base
323 const DWARFDie> {
311324 DWARFDie Die;
312 void skipNull() {
313 if (Die && Die.isNULL())
314 Die = DWARFDie();
315 }
316325 public:
317326 iterator() = default;
318327
319328 explicit iterator(DWARFDie D) : Die(D) {
320 // If we start out with only a Null DIE then invalidate.
321 skipNull();
322329 }
323330
324331 iterator &operator++() {
325332 Die = Die.getSibling();
326 // Don't include the NULL die when iterating.
327 skipNull();
333 return *this;
334 }
335
336 iterator &operator--() {
337 Die = Die.getPreviousSibling();
328338 return *this;
329339 }
330340
340350 }
341351
342352 inline DWARFDie::iterator DWARFDie::end() const {
343 return iterator();
353 return iterator(getLastChild());
344354 }
345355
346356 inline iterator_range DWARFDie::children() const {
507507
508508 DWARFDie getParent(const DWARFDebugInfoEntry *Die);
509509 DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
510 DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
510511 DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
512 DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
511513
512514 /// Return the DIE object for a given offset inside the
513515 /// unit's DIE vector.
554554 return DWARFDie();
555555 }
556556
557 DWARFDie DWARFDie::getPreviousSibling() const {
558 if (isValid())
559 return U->getPreviousSibling(Die);
560 return DWARFDie();
561 }
562
557563 DWARFDie DWARFDie::getFirstChild() const {
558564 if (isValid())
559565 return U->getFirstChild(Die);
566 return DWARFDie();
567 }
568
569 DWARFDie DWARFDie::getLastChild() const {
570 if (isValid())
571 return U->getLastChild(Die);
560572 return DWARFDie();
561573 }
562574
583583 return DWARFDie();
584584 }
585585
586 DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
587 if (!Die)
588 return DWARFDie();
589 uint32_t Depth = Die->getDepth();
590 // Unit DIEs always have a depth of zero and never have siblings.
591 if (Depth == 0)
592 return DWARFDie();
593
594 // Find the previous DIE whose depth is the same as the Die's depth.
595 for (size_t I = getDIEIndex(Die) - 1; I >= 0; --I) {
596 if (DieArray[I].getDepth() == Depth - 1)
597 return DWARFDie();
598 if (DieArray[I].getDepth() == Depth)
599 return DWARFDie(this, &DieArray[I]);
600 }
601 return DWARFDie();
602 }
603
586604 DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
587605 if (!Die->hasChildren())
588606 return DWARFDie();
592610 if (I >= DieArray.size())
593611 return DWARFDie();
594612 return DWARFDie(this, &DieArray[I]);
613 }
614
615 DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
616 if (!Die->hasChildren())
617 return DWARFDie();
618
619 uint32_t Depth = Die->getDepth();
620 for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
621 ++I) {
622 if (DieArray[I].getDepth() == Depth + 1 &&
623 DieArray[I].getTag() == dwarf::DW_TAG_null)
624 return DWARFDie(this, &DieArray[I]);
625 assert(DieArray[I].getDepth() > Depth && "Not processing children?");
626 }
627 return DWARFDie();
595628 }
596629
597630 const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
489489 EXPECT_TRUE(!NullDieDG.getSibling().isValid());
490490 EXPECT_TRUE(!NullDieDG.getFirstChild().isValid());
491491 }
492
493 // Verify the previous sibling of our subprogram is our integer base type.
494 IntDieDG = NullDieDG.getPreviousSibling();
495 EXPECT_TRUE(IntDieDG.isValid());
496 EXPECT_EQ(IntDieDG.getTag(), DW_TAG_base_type);
492497 }
493498
494499 TEST(DWARFDebugInfo, TestDWARF32Version2Addr4Children) {
10711076 // Make sure the parent of all the children of the B are the B.
10721077 EXPECT_EQ(C1.getParent(), C);
10731078 EXPECT_EQ(C2.getParent(), C);
1079
1080 // Make sure bidirectional iterator works as expected.
1081 auto Begin = A.begin();
1082 auto End = A.end();
1083 auto It = A.begin();
1084
1085 EXPECT_EQ(It, Begin);
1086 EXPECT_EQ(*It, B);
1087 ++It;
1088 EXPECT_EQ(*It, C);
1089 ++It;
1090 EXPECT_EQ(*It, D);
1091 ++It;
1092 EXPECT_EQ(It, End);
1093 --It;
1094 EXPECT_EQ(*It, D);
1095 --It;
1096 EXPECT_EQ(*It, C);
1097 --It;
1098 EXPECT_EQ(*It, B);
1099 EXPECT_EQ(It, Begin);
10741100 }
10751101
10761102 TEST(DWARFDebugInfo, TestDWARFDie) {