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";
}
Example #2
0
/// 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());
      }
    }

}
Example #3
0
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;
}
Example #4
0
/// 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;
  }
}
Example #5
0
/// 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;
  }
}