Add a variant of DWARFDie::find() and DWARFDie::findRecursively() that takes a llvm::ArrayRef<dwarf::Attribute>.
This allows us efficiently look for more than one attribute, something that is quite common in DWARF consumption.
Differential Revision: https://reviews.llvm.org/D28704
llvm-svn: 291967
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 11fb726..9a05ae8 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -158,6 +158,35 @@
return None;
}
+Optional<DWARFFormValue>
+DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
+ if (!isValid())
+ return None;
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl) {
+ for (auto Attr : Attrs) {
+ if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
+ return Value;
+ }
+ }
+ return None;
+}
+
+Optional<DWARFFormValue>
+DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
+ if (!isValid())
+ return None;
+ if (auto Value = find(Attrs))
+ return Value;
+ if (auto Die = getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
+ if (auto Value = Die.find(Attrs))
+ return Value;
+ if (auto Die = getAttributeValueAsReferencedDie(DW_AT_specification))
+ if (auto Value = Die.find(Attrs))
+ return Value;
+ return None;
+}
+
DWARFDie
DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
auto SpecRef = toReference(find(Attr));
@@ -171,10 +200,7 @@
Optional<uint64_t>
DWARFDie::getRangesBaseAttribute() const {
- auto Result = toSectionOffset(find(DW_AT_rnglists_base));
- if (Result)
- return Result;
- return toSectionOffset(find(DW_AT_GNU_ranges_base));
+ return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
}
Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
@@ -256,11 +282,8 @@
return nullptr;
// Try to get mangled name only if it was asked for.
if (Kind == DINameKind::LinkageName) {
- if (auto Name = dwarf::toString(findRecursively(DW_AT_MIPS_linkage_name),
- nullptr))
- return Name;
- if (auto Name = dwarf::toString(findRecursively(DW_AT_linkage_name),
- nullptr))
+ if (auto Name = dwarf::toString(findRecursively({DW_AT_MIPS_linkage_name,
+ DW_AT_linkage_name}), nullptr))
return Name;
}
if (auto Name = dwarf::toString(findRecursively(DW_AT_name), nullptr))
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index e0dcd9b..84dc904 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -226,9 +226,7 @@
// If CU DIE was just parsed, copy several attribute values from it.
if (!HasCUDie) {
DWARFDie UnitDie = getUnitDIE();
- auto BaseAddr = toAddress(UnitDie.find(DW_AT_low_pc));
- if (!BaseAddr)
- BaseAddr = toAddress(UnitDie.find(DW_AT_entry_pc));
+ auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}));
if (BaseAddr)
setBaseAddress(*BaseAddr);
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);