void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) { DWARFDie TD = getDIEForOffset(TypeOffset + getOffset()); const char *Name = TD.getName(DINameKind::ShortName); if (SummarizeTypes) { OS << "name = '" << Name << "'" << " type_signature = " << format("0x%16" PRIx64, TypeHash) << " length = " << format("0x%08x", getLength()) << '\n'; return; } OS << format("0x%08x", getOffset()) << ": Type Unit:" << " length = " << format("0x%08x", getLength()) << " version = " << format("0x%04x", getVersion()) << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset()) << " addr_size = " << format("0x%02x", getAddressByteSize()) << " name = '" << Name << "'" << " type_signature = " << format("0x%16" PRIx64, TypeHash) << " type_offset = " << format("0x%04x", TypeOffset) << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n"; if (DWARFDie TU = getUnitDIE(false)) TU.dump(OS, -1U); else OS << "<type unit can't be parsed!>\n\n"; }
/// Print only DIEs that have a certain name. static void filterByName(const StringSet<> &Names, DWARFContext::cu_iterator_range CUs, raw_ostream &OS) { for (const auto &CU : CUs) for (const auto &Entry : CU->dies()) { DWARFDie Die = {CU.get(), &Entry}; if (const char *NamePtr = Die.getName(DINameKind::ShortName)) { std::string Name = (IgnoreCase && !UseRegex) ? StringRef(NamePtr).lower() : NamePtr; // Match regular expression. if (UseRegex) for (auto Pattern : Names.keys()) { Regex RE(Pattern, IgnoreCase ? Regex::IgnoreCase : Regex::NoFlags); std::string Error; if (!RE.isValid(Error)) { errs() << "error in regular expression: " << Error << "\n"; exit(1); } if (RE.match(Name)) Die.dump(OS, 0, getDumpOpts()); } // Match full text. else if (Names.count(Name)) Die.dump(OS, 0, getDumpOpts()); } } }
static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE, bool IncludeLinkageName = true) { SmallVector<StringRef, 2> Result; if (const char *Str = DIE.getName(DINameKind::ShortName)) Result.emplace_back(Str); else if (DIE.getTag() == dwarf::DW_TAG_namespace) Result.emplace_back("(anonymous namespace)"); if (IncludeLinkageName) { if (const char *Str = DIE.getName(DINameKind::LinkageName)) { if (Result.empty() || Result[0] != Str) Result.emplace_back(Str); } } return Result; }
/// Recursively dump the DIE type name when applicable. static void dumpTypeName(raw_ostream &OS, const DWARFDie &Die) { DWARFDie D = Die.getAttributeValueAsReferencedDie(DW_AT_type); if (!D.isValid()) return; if (const char *Name = D.getName(DINameKind::LinkageName)) { OS << Name; return; } // FIXME: We should have pretty printers per language. Currently we print // everything as if it was C++ and fall back to the TAG type name. const dwarf::Tag T = D.getTag(); switch (T) { case DW_TAG_array_type: case DW_TAG_pointer_type: case DW_TAG_ptr_to_member_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: break; default: dumpTypeTagName(OS, T); } // Follow the DW_AT_type if possible. dumpTypeName(OS, D); switch (T) { case DW_TAG_array_type: OS << "[]"; break; case DW_TAG_pointer_type: OS << '*'; break; case DW_TAG_ptr_to_member_type: OS << '*'; break; case DW_TAG_reference_type: OS << '&'; break; case DW_TAG_rvalue_reference_type: OS << "&&"; break; default: break; } }
/// Recursively dump the DIE type name when applicable. static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) { if (!D.isValid()) return; if (const char *Name = D.getName(DINameKind::LinkageName)) { OS << Name; return; } // FIXME: We should have pretty printers per language. Currently we print // everything as if it was C++ and fall back to the TAG type name. const dwarf::Tag T = D.getTag(); switch (T) { case DW_TAG_array_type: case DW_TAG_pointer_type: case DW_TAG_ptr_to_member_type: case DW_TAG_reference_type: case DW_TAG_rvalue_reference_type: case DW_TAG_subroutine_type: break; default: dumpTypeTagName(OS, T); } // Follow the DW_AT_type if possible. DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type); dumpTypeName(OS, TypeDie); switch (T) { case DW_TAG_subroutine_type: { if (!TypeDie) OS << "void"; OS << '('; bool First = true; for (const DWARFDie &C : D.children()) { if (C.getTag() == DW_TAG_formal_parameter) { if (!First) OS << ", "; First = false; dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type)); } } OS << ')'; break; } case DW_TAG_array_type: { dumpArrayType(OS, D); break; } case DW_TAG_pointer_type: OS << '*'; break; case DW_TAG_ptr_to_member_type: if (DWARFDie Cont = D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) { dumpTypeName(OS << ' ', Cont); OS << "::"; } OS << '*'; break; case DW_TAG_reference_type: OS << '&'; break; case DW_TAG_rvalue_reference_type: OS << "&&"; break; default: break; } }