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))