[llvm] ece341f - [Debuginfo][DWARF][NFC] Add paired methods working with DWARFDebugInfoEntry.
Alexey Lapshin via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 29 06:41:11 PDT 2022
Author: Alexey Lapshin
Date: 2022-07-29T16:40:17+03:00
New Revision: ece341f598b4d200e89040d84c7cb037e34116be
URL: https://github.com/llvm/llvm-project/commit/ece341f598b4d200e89040d84c7cb037e34116be
DIFF: https://github.com/llvm/llvm-project/commit/ece341f598b4d200e89040d84c7cb037e34116be.diff
LOG: [Debuginfo][DWARF][NFC] Add paired methods working with DWARFDebugInfoEntry.
This review is extracted from D96035.
DWARF Debuginfo classes have two representations for DIEs: DWARFDebugInfoEntry
(short) and DWARFDie(extended). Depending on the task, it might be more convenient
to use DWARFDebugInfoEntry or/and DWARFDie. DWARFUnit class already has methods
working with DWARFDie and DWARFDebugInfoEntry. This patch adds more
methods working with DWARFDebugInfoEntry to have paired functionality.
Reviewed By: aprantl
Differential Revision: https://reviews.llvm.org/D126059
Added:
Modified:
llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 9188865b4d771..fd704b1136839 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -252,13 +252,36 @@ class DWARFUnit {
std::shared_ptr<DWARFUnit> DWO;
- uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
+protected:
+ /// Return the index of a \p Die entry inside the unit's DIE vector.
+ ///
+ /// It is illegal to call this method with a DIE that hasn't be
+ /// created by this unit. In other word, it's illegal to call this
+ /// method on a DIE that isn't accessible by following
+ /// children/sibling links starting from this unit's getUnitDIE().
+ uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {
auto First = DieArray.data();
assert(Die >= First && Die < First + DieArray.size());
return Die - First;
}
-protected:
+ /// Return DWARFDebugInfoEntry for the specified index \p Index.
+ const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {
+ assert(Index < DieArray.size());
+ return &DieArray[Index];
+ }
+
+ const DWARFDebugInfoEntry *
+ getParentEntry(const DWARFDebugInfoEntry *Die) const;
+ const DWARFDebugInfoEntry *
+ getSiblingEntry(const DWARFDebugInfoEntry *Die) const;
+ const DWARFDebugInfoEntry *
+ getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const;
+ const DWARFDebugInfoEntry *
+ getFirstChildEntry(const DWARFDebugInfoEntry *Die) const;
+ const DWARFDebugInfoEntry *
+ getLastChildEntry(const DWARFDebugInfoEntry *Die) const;
+
const DWARFUnitHeader &getHeader() const { return Header; }
/// Find the unit's contribution to the string offsets table and determine its
@@ -472,14 +495,13 @@ class DWARFUnit {
/// created by this unit. In other word, it's illegal to call this
/// method on a DIE that isn't accessible by following
/// children/sibling links starting from this unit's getUnitDIE().
- uint32_t getDIEIndex(const DWARFDie &D) {
+ uint32_t getDIEIndex(const DWARFDie &D) const {
return getDIEIndex(D.getDebugInfoEntry());
}
- /// Return the DIE object at the given index.
+ /// Return the DIE object at the given index \p Index.
DWARFDie getDIEAtIndex(unsigned Index) {
- assert(Index < DieArray.size());
- return DWARFDie(this, &DieArray[Index]);
+ return DWARFDie(this, getDebugInfoEntry(Index));
}
DWARFDie getParent(const DWARFDebugInfoEntry *Die);
@@ -488,19 +510,26 @@ class DWARFUnit {
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
- /// Return the DIE object for a given offset inside the
+ /// Return the DIE object for a given offset \p Offset inside the
/// unit's DIE vector.
- ///
- /// The unit needs to have its DIEs extracted for this method to work.
DWARFDie getDIEForOffset(uint64_t Offset) {
+ if (Optional<uint32_t> DieIdx = getDIEIndexForOffset(Offset))
+ return DWARFDie(this, &DieArray[*DieIdx]);
+
+ return DWARFDie();
+ }
+
+ /// Return the DIE index for a given offset \p Offset inside the
+ /// unit's DIE vector.
+ Optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
extractDIEsIfNeeded(false);
auto It =
llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
return DIE.getOffset() < Offset;
});
if (It != DieArray.end() && It->getOffset() == Offset)
- return DWARFDie(this, &*It);
- return DWARFDie();
+ return It - DieArray.begin();
+ return None;
}
uint32_t getLineTableOffset() const {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 74667fcb92bc4..d80008c45485e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -877,39 +877,66 @@ const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
}
DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
+ if (const DWARFDebugInfoEntry *Entry = getParentEntry(Die))
+ return DWARFDie(this, Entry);
+
+ return DWARFDie();
+}
+
+const DWARFDebugInfoEntry *
+DWARFUnit::getParentEntry(const DWARFDebugInfoEntry *Die) const {
if (!Die)
- return DWARFDie();
+ return nullptr;
+ assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) {
assert(*ParentIdx < DieArray.size() &&
"ParentIdx is out of DieArray boundaries");
- return DWARFDie(this, &DieArray[*ParentIdx]);
+ return getDebugInfoEntry(*ParentIdx);
}
- return DWARFDie();
+ return nullptr;
}
DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
+ if (const DWARFDebugInfoEntry *Sibling = getSiblingEntry(Die))
+ return DWARFDie(this, Sibling);
+
+ return DWARFDie();
+}
+
+const DWARFDebugInfoEntry *
+DWARFUnit::getSiblingEntry(const DWARFDebugInfoEntry *Die) const {
if (!Die)
- return DWARFDie();
+ return nullptr;
+ assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
assert(*SiblingIdx < DieArray.size() &&
"SiblingIdx is out of DieArray boundaries");
- return DWARFDie(this, &DieArray[*SiblingIdx]);
+ return &DieArray[*SiblingIdx];
}
- return DWARFDie();
+ return nullptr;
}
DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
+ if (const DWARFDebugInfoEntry *Sibling = getPreviousSiblingEntry(Die))
+ return DWARFDie(this, Sibling);
+
+ return DWARFDie();
+}
+
+const DWARFDebugInfoEntry *
+DWARFUnit::getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const {
if (!Die)
- return DWARFDie();
+ return nullptr;
+ assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
Optional<uint32_t> ParentIdx = Die->getParentIdx();
if (!ParentIdx)
// Die is a root die, there is no previous sibling.
- return DWARFDie();
+ return nullptr;
assert(*ParentIdx < DieArray.size() &&
"ParentIdx is out of DieArray boundaries");
@@ -918,7 +945,7 @@ DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
uint32_t PrevDieIdx = getDIEIndex(Die) - 1;
if (PrevDieIdx == *ParentIdx)
// Immediately previous node is parent, there is no previous sibling.
- return DWARFDie();
+ return nullptr;
while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) {
PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx();
@@ -929,32 +956,56 @@ DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
"PrevDieIdx is not a child of parent of Die");
}
- return DWARFDie(this, &DieArray[PrevDieIdx]);
+ return &DieArray[PrevDieIdx];
}
DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
+ if (const DWARFDebugInfoEntry *Child = getFirstChildEntry(Die))
+ return DWARFDie(this, Child);
+
+ return DWARFDie();
+}
+
+const DWARFDebugInfoEntry *
+DWARFUnit::getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {
+ if (!Die)
+ return nullptr;
+ assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
+
if (!Die->hasChildren())
- return DWARFDie();
+ return nullptr;
// TODO: Instead of checking here for invalid die we might reject
// invalid dies at parsing stage(DWARFUnit::extractDIEsToVector).
// We do not want access out of bounds when parsing corrupted debug data.
size_t I = getDIEIndex(Die) + 1;
if (I >= DieArray.size())
- return DWARFDie();
- return DWARFDie(this, &DieArray[I]);
+ return nullptr;
+ return &DieArray[I];
}
DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
+ if (const DWARFDebugInfoEntry *Child = getLastChildEntry(Die))
+ return DWARFDie(this, Child);
+
+ return DWARFDie();
+}
+
+const DWARFDebugInfoEntry *
+DWARFUnit::getLastChildEntry(const DWARFDebugInfoEntry *Die) const {
+ if (!Die)
+ return nullptr;
+ assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size());
+
if (!Die->hasChildren())
- return DWARFDie();
+ return nullptr;
if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) {
assert(*SiblingIdx < DieArray.size() &&
"SiblingIdx is out of DieArray boundaries");
assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null &&
"Bad end of children marker");
- return DWARFDie(this, &DieArray[*SiblingIdx - 1]);
+ return &DieArray[*SiblingIdx - 1];
}
// If SiblingIdx is set for non-root dies we could be sure that DWARF is
@@ -969,11 +1020,13 @@ DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
if (getDIEIndex(Die) == 0 && DieArray.size() > 1 &&
DieArray.back().getTag() == dwarf::DW_TAG_null) {
// For the unit die we might take last item from DieArray.
- assert(getDIEIndex(Die) == getDIEIndex(getUnitDIE()) && "Bad unit die");
- return DWARFDie(this, &DieArray.back());
+ assert(getDIEIndex(Die) ==
+ getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) &&
+ "Bad unit die");
+ return &DieArray.back();
}
- return DWARFDie();
+ return nullptr;
}
const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
More information about the llvm-commits
mailing list