void DWARFCompileUnit::extractDIEsToVector(
    bool AppendCUDie, bool AppendNonCUDies,
    std::vector<DWARFDebugInfoEntryMinimal> &Dies) const {
  if (!AppendCUDie && !AppendNonCUDies)
    return;

  // Set the offset to that of the first DIE and calculate the start of the
  // next compilation unit header.
  uint32_t Offset = getFirstDIEOffset();
  uint32_t NextCUOffset = getNextCompileUnitOffset();
  DWARFDebugInfoEntryMinimal DIE;
  uint32_t Depth = 0;
  const uint8_t *FixedFormSizes =
    DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion());
  bool IsCUDie = true;

  while (Offset < NextCUOffset &&
         DIE.extractFast(this, FixedFormSizes, &Offset)) {
    if (IsCUDie) {
      if (AppendCUDie)
        Dies.push_back(DIE);
      if (!AppendNonCUDies)
        break;
      // The average bytes per DIE entry has been seen to be
      // around 14-20 so let's pre-reserve the needed memory for
      // our DIE entries accordingly.
      Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
      IsCUDie = false;
    } else {
      Dies.push_back(DIE);
    }

    const DWARFAbbreviationDeclaration *AbbrDecl =
      DIE.getAbbreviationDeclarationPtr();
    if (AbbrDecl) {
      // Normal DIE
      if (AbbrDecl->hasChildren())
        ++Depth;
    } else {
      // NULL DIE.
      if (Depth > 0)
        --Depth;
      if (Depth == 0)
        break;  // We are done with this compile unit!
    }
  }

  // Give a little bit of info if we encounter corrupt DWARF (our offset
  // should always terminate at or before the start of the next compilation
  // unit header).
  if (Offset > NextCUOffset)
    fprintf(stderr, "warning: DWARF compile unit extends beyond its "
                    "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), Offset);
}
size_t DWARFCompileUnit::extractDIEsIfNeeded(bool cu_die_only) {
  const size_t initial_die_array_size = DieArray.size();
  if ((cu_die_only && initial_die_array_size > 0) ||
      initial_die_array_size > 1)
    return 0; // Already parsed

  // Set the offset to that of the first DIE and calculate the start of the
  // next compilation unit header.
  uint32_t offset = getFirstDIEOffset();
  uint32_t next_cu_offset = getNextCompileUnitOffset();

  DWARFDebugInfoEntryMinimal die;
  // Keep a flat array of the DIE for binary lookup by DIE offset
  uint32_t depth = 0;
  // We are in our compile unit, parse starting at the offset
  // we were told to parse

  const uint8_t *fixed_form_sizes =
    DWARFFormValue::getFixedFormSizes(getAddressByteSize(), getVersion());

  while (offset < next_cu_offset &&
         die.extractFast(this, fixed_form_sizes, &offset)) {

    if (depth == 0) {
      uint64_t base_addr =
        die.getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U);
      if (base_addr == -1U)
        base_addr = die.getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0);
      setBaseAddress(base_addr);
    }

    if (cu_die_only) {
      addDIE(die);
      return 1;
    }
    else if (depth == 0 && initial_die_array_size == 1)
      // Don't append the CU die as we already did that
      ;
    else
      addDIE(die);

    const DWARFAbbreviationDeclaration *abbrDecl =
      die.getAbbreviationDeclarationPtr();
    if (abbrDecl) {
      // Normal DIE
      if (abbrDecl->hasChildren())
        ++depth;
    } else {
      // NULL DIE.
      if (depth > 0)
        --depth;
      if (depth == 0)
        break;  // We are done with this compile unit!
    }

  }

  // Give a little bit of info if we encounter corrupt DWARF (our offset
  // should always terminate at or before the start of the next compilation
  // unit header).
  if (offset > next_cu_offset)
    fprintf(stderr, "warning: DWARF compile unit extends beyond its "
                    "bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), offset);

  setDIERelations();
  return DieArray.size();
}