[llvm] r336823 - [DebugInfo] Make children iterator bidirectional
Jonas Devlieghere via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 11 10:11:11 PDT 2018
Author: jdevlieghere
Date: Wed Jul 11 10:11:11 2018
New Revision: 336823
URL: http://llvm.org/viewvc/llvm-project?rev=336823&view=rev
Log:
[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
Modified:
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h?rev=336823&r1=336822&r2=336823&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDie.h Wed Jul 11 10:11:11 2018
@@ -104,12 +104,24 @@ public:
/// invalid DWARFDie instance if it doesn't.
DWARFDie getSibling() const;
+ /// Get the previous sibling of this DIE object.
+ ///
+ /// \returns a valid DWARFDie instance if this object has a sibling or an
+ /// invalid DWARFDie instance if it doesn't.
+ DWARFDie getPreviousSibling() const;
+
/// Get the first child of this DIE object.
///
/// \returns a valid DWARFDie instance if this object has children or an
/// invalid DWARFDie instance if it doesn't.
DWARFDie getFirstChild() const;
+ /// Get the last child of this DIE object.
+ ///
+ /// \returns a valid null DWARFDie instance if this object has children or an
+ /// invalid DWARFDie instance if it doesn't.
+ DWARFDie getLastChild() const;
+
/// Dump the DIE and all of its attributes to the supplied stream.
///
/// \param OS the stream to use for output.
@@ -288,6 +300,7 @@ public:
explicit attribute_iterator(DWARFDie D, bool End);
attribute_iterator &operator++();
+ attribute_iterator &operator--();
explicit operator bool() const { return AttrValue.isValid(); }
const DWARFAttribute &operator*() const { return AttrValue; }
bool operator==(const attribute_iterator &X) const { return Index == X.Index; }
@@ -306,26 +319,23 @@ inline bool operator<(const DWARFDie &LH
return LHS.getOffset() < RHS.getOffset();
}
-class DWARFDie::iterator : public iterator_facade_base<iterator,
- std::forward_iterator_tag,
- const DWARFDie> {
+class DWARFDie::iterator
+ : public iterator_facade_base<iterator, std::bidirectional_iterator_tag,
+ const DWARFDie> {
DWARFDie Die;
- void skipNull() {
- if (Die && Die.isNULL())
- Die = DWARFDie();
- }
public:
iterator() = default;
explicit iterator(DWARFDie D) : Die(D) {
- // If we start out with only a Null DIE then invalidate.
- skipNull();
}
iterator &operator++() {
Die = Die.getSibling();
- // Don't include the NULL die when iterating.
- skipNull();
+ return *this;
+ }
+
+ iterator &operator--() {
+ Die = Die.getPreviousSibling();
return *this;
}
@@ -341,7 +351,7 @@ inline DWARFDie::iterator DWARFDie::begi
}
inline DWARFDie::iterator DWARFDie::end() const {
- return iterator();
+ return iterator(getLastChild());
}
inline iterator_range<DWARFDie::iterator> DWARFDie::children() const {
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=336823&r1=336822&r2=336823&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Wed Jul 11 10:11:11 2018
@@ -508,7 +508,9 @@ public:
DWARFDie getParent(const DWARFDebugInfoEntry *Die);
DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
+ DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
+ DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
/// Return the DIE object for a given offset inside the
/// unit's DIE vector.
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=336823&r1=336822&r2=336823&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Wed Jul 11 10:11:11 2018
@@ -555,12 +555,24 @@ DWARFDie DWARFDie::getSibling() const {
return DWARFDie();
}
+DWARFDie DWARFDie::getPreviousSibling() const {
+ if (isValid())
+ return U->getPreviousSibling(Die);
+ return DWARFDie();
+}
+
DWARFDie DWARFDie::getFirstChild() const {
if (isValid())
return U->getFirstChild(Die);
return DWARFDie();
}
+DWARFDie DWARFDie::getLastChild() const {
+ if (isValid())
+ return U->getLastChild(Die);
+ return DWARFDie();
+}
+
iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const {
return make_range(attribute_iterator(*this, false),
attribute_iterator(*this, true));
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=336823&r1=336822&r2=336823&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Wed Jul 11 10:11:11 2018
@@ -584,6 +584,24 @@ DWARFDie DWARFUnit::getSibling(const DWA
return DWARFDie();
}
+DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
+ if (!Die)
+ return DWARFDie();
+ uint32_t Depth = Die->getDepth();
+ // Unit DIEs always have a depth of zero and never have siblings.
+ if (Depth == 0)
+ return DWARFDie();
+
+ // Find the previous DIE whose depth is the same as the Die's depth.
+ for (size_t I = getDIEIndex(Die) - 1; I >= 0; --I) {
+ if (DieArray[I].getDepth() == Depth - 1)
+ return DWARFDie();
+ if (DieArray[I].getDepth() == Depth)
+ return DWARFDie(this, &DieArray[I]);
+ }
+ return DWARFDie();
+}
+
DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
if (!Die->hasChildren())
return DWARFDie();
@@ -595,6 +613,21 @@ DWARFDie DWARFUnit::getFirstChild(const
return DWARFDie(this, &DieArray[I]);
}
+DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
+ if (!Die->hasChildren())
+ return DWARFDie();
+
+ uint32_t Depth = Die->getDepth();
+ for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
+ ++I) {
+ if (DieArray[I].getDepth() == Depth + 1 &&
+ DieArray[I].getTag() == dwarf::DW_TAG_null)
+ return DWARFDie(this, &DieArray[I]);
+ assert(DieArray[I].getDepth() > Depth && "Not processing children?");
+ }
+ return DWARFDie();
+}
+
const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
if (!Abbrevs)
Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
Modified: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp?rev=336823&r1=336822&r2=336823&view=diff
==============================================================================
--- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp (original)
+++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp Wed Jul 11 10:11:11 2018
@@ -490,6 +490,11 @@ template <uint16_t Version, class AddrTy
EXPECT_TRUE(!NullDieDG.getSibling().isValid());
EXPECT_TRUE(!NullDieDG.getFirstChild().isValid());
}
+
+ // Verify the previous sibling of our subprogram is our integer base type.
+ IntDieDG = NullDieDG.getPreviousSibling();
+ EXPECT_TRUE(IntDieDG.isValid());
+ EXPECT_EQ(IntDieDG.getTag(), DW_TAG_base_type);
}
TEST(DWARFDebugInfo, TestDWARF32Version2Addr4Children) {
@@ -1072,6 +1077,27 @@ TEST(DWARFDebugInfo, TestRelations) {
// Make sure the parent of all the children of the B are the B.
EXPECT_EQ(C1.getParent(), C);
EXPECT_EQ(C2.getParent(), C);
+
+ // Make sure bidirectional iterator works as expected.
+ auto Begin = A.begin();
+ auto End = A.end();
+ auto It = A.begin();
+
+ EXPECT_EQ(It, Begin);
+ EXPECT_EQ(*It, B);
+ ++It;
+ EXPECT_EQ(*It, C);
+ ++It;
+ EXPECT_EQ(*It, D);
+ ++It;
+ EXPECT_EQ(It, End);
+ --It;
+ EXPECT_EQ(*It, D);
+ --It;
+ EXPECT_EQ(*It, C);
+ --It;
+ EXPECT_EQ(*It, B);
+ EXPECT_EQ(It, Begin);
}
TEST(DWARFDebugInfo, TestDWARFDie) {
More information about the llvm-commits
mailing list