Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- DWARFUnit.h ----------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
  10. #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
  11.  
  12. #include "llvm/ADT/DenseSet.h"
  13. #include "llvm/ADT/STLExtras.h"
  14. #include "llvm/ADT/SmallVector.h"
  15. #include "llvm/ADT/StringRef.h"
  16. #include "llvm/ADT/iterator_range.h"
  17. #include "llvm/BinaryFormat/Dwarf.h"
  18. #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
  19. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  20. #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
  21. #include "llvm/DebugInfo/DWARF/DWARFDie.h"
  22. #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
  23. #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
  24. #include "llvm/Support/DataExtractor.h"
  25. #include <cassert>
  26. #include <cstddef>
  27. #include <cstdint>
  28. #include <map>
  29. #include <memory>
  30. #include <set>
  31. #include <utility>
  32. #include <vector>
  33.  
  34. namespace llvm {
  35.  
  36. class DWARFAbbreviationDeclarationSet;
  37. class DWARFContext;
  38. class DWARFDebugAbbrev;
  39. class DWARFUnit;
  40. class DWARFDebugRangeList;
  41. class DWARFLocationTable;
  42. class DWARFObject;
  43. class raw_ostream;
  44. struct DIDumpOptions;
  45. struct DWARFSection;
  46.  
  47. /// Base class describing the header of any kind of "unit."  Some information
  48. /// is specific to certain unit types.  We separate this class out so we can
  49. /// parse the header before deciding what specific kind of unit to construct.
  50. class DWARFUnitHeader {
  51.   // Offset within section.
  52.   uint64_t Offset = 0;
  53.   // Version, address size, and DWARF format.
  54.   dwarf::FormParams FormParams;
  55.   uint64_t Length = 0;
  56.   uint64_t AbbrOffset = 0;
  57.  
  58.   // For DWO units only.
  59.   const DWARFUnitIndex::Entry *IndexEntry = nullptr;
  60.  
  61.   // For type units only.
  62.   uint64_t TypeHash = 0;
  63.   uint64_t TypeOffset = 0;
  64.  
  65.   // For v5 split or skeleton compile units only.
  66.   std::optional<uint64_t> DWOId;
  67.  
  68.   // Unit type as parsed, or derived from the section kind.
  69.   uint8_t UnitType = 0;
  70.  
  71.   // Size as parsed. uint8_t for compactness.
  72.   uint8_t Size = 0;
  73.  
  74. public:
  75.   /// Parse a unit header from \p debug_info starting at \p offset_ptr.
  76.   /// Note that \p SectionKind is used as a hint to guess the unit type
  77.   /// for DWARF formats prior to DWARFv5. In DWARFv5 the unit type is
  78.   /// explicitly defined in the header and the hint is ignored.
  79.   bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
  80.                uint64_t *offset_ptr, DWARFSectionKind SectionKind);
  81.   // For units in DWARF Package File, remember the index entry and update
  82.   // the abbreviation offset read by extract().
  83.   bool applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
  84.   uint64_t getOffset() const { return Offset; }
  85.   const dwarf::FormParams &getFormParams() const { return FormParams; }
  86.   uint16_t getVersion() const { return FormParams.Version; }
  87.   dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
  88.   uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
  89.   uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
  90.   uint8_t getDwarfOffsetByteSize() const {
  91.     return FormParams.getDwarfOffsetByteSize();
  92.   }
  93.   uint64_t getLength() const { return Length; }
  94.   uint64_t getAbbrOffset() const { return AbbrOffset; }
  95.   std::optional<uint64_t> getDWOId() const { return DWOId; }
  96.   void setDWOId(uint64_t Id) {
  97.     assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value");
  98.     DWOId = Id;
  99.   }
  100.   const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
  101.   uint64_t getTypeHash() const { return TypeHash; }
  102.   uint64_t getTypeOffset() const { return TypeOffset; }
  103.   uint8_t getUnitType() const { return UnitType; }
  104.   bool isTypeUnit() const {
  105.     return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
  106.   }
  107.   uint8_t getSize() const { return Size; }
  108.   uint8_t getUnitLengthFieldByteSize() const {
  109.     return dwarf::getUnitLengthFieldByteSize(FormParams.Format);
  110.   }
  111.   uint64_t getNextUnitOffset() const {
  112.     return Offset + Length + getUnitLengthFieldByteSize();
  113.   }
  114. };
  115.  
  116. const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
  117.                                         DWARFSectionKind Kind);
  118.  
  119. bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U);
  120.  
  121. /// Describe a collection of units. Intended to hold all units either from
  122. /// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
  123. class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
  124.   std::function<std::unique_ptr<DWARFUnit>(uint64_t, DWARFSectionKind,
  125.                                            const DWARFSection *,
  126.                                            const DWARFUnitIndex::Entry *)>
  127.       Parser;
  128.   int NumInfoUnits = -1;
  129.  
  130. public:
  131.   using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
  132.   using iterator = typename UnitVector::iterator;
  133.   using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
  134.  
  135.   using compile_unit_range =
  136.       decltype(make_filter_range(std::declval<iterator_range>(), isCompileUnit));
  137.  
  138.   DWARFUnit *getUnitForOffset(uint64_t Offset) const;
  139.   DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
  140.  
  141.   /// Read units from a .debug_info or .debug_types section.  Calls made
  142.   /// before finishedInfoUnits() are assumed to be for .debug_info sections,
  143.   /// calls after finishedInfoUnits() are for .debug_types sections.  Caller
  144.   /// must not mix calls to addUnitsForSection and addUnitsForDWOSection.
  145.   void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
  146.                           DWARFSectionKind SectionKind);
  147.   /// Read units from a .debug_info.dwo or .debug_types.dwo section.  Calls
  148.   /// made before finishedInfoUnits() are assumed to be for .debug_info.dwo
  149.   /// sections, calls after finishedInfoUnits() are for .debug_types.dwo
  150.   /// sections.  Caller must not mix calls to addUnitsForSection and
  151.   /// addUnitsForDWOSection.
  152.   void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
  153.                              DWARFSectionKind SectionKind, bool Lazy = false);
  154.  
  155.   /// Add an existing DWARFUnit to this UnitVector. This is used by the DWARF
  156.   /// verifier to process unit separately.
  157.   DWARFUnit *addUnit(std::unique_ptr<DWARFUnit> Unit);
  158.  
  159.   /// Returns number of all units held by this instance.
  160.   unsigned getNumUnits() const { return size(); }
  161.   /// Returns number of units from all .debug_info[.dwo] sections.
  162.   unsigned getNumInfoUnits() const {
  163.     return NumInfoUnits == -1 ? size() : NumInfoUnits;
  164.   }
  165.   /// Returns number of units from all .debug_types[.dwo] sections.
  166.   unsigned getNumTypesUnits() const { return size() - NumInfoUnits; }
  167.   /// Indicate that parsing .debug_info[.dwo] is done, and remaining units
  168.   /// will be from .debug_types[.dwo].
  169.   void finishedInfoUnits() { NumInfoUnits = size(); }
  170.  
  171. private:
  172.   void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
  173.                     const DWARFSection &Section, const DWARFDebugAbbrev *DA,
  174.                     const DWARFSection *RS, const DWARFSection *LocSection,
  175.                     StringRef SS, const DWARFSection &SOS,
  176.                     const DWARFSection *AOS, const DWARFSection &LS, bool LE,
  177.                     bool IsDWO, bool Lazy, DWARFSectionKind SectionKind);
  178. };
  179.  
  180. /// Represents base address of the CU.
  181. /// Represents a unit's contribution to the string offsets table.
  182. struct StrOffsetsContributionDescriptor {
  183.   uint64_t Base = 0;
  184.   /// The contribution size not including the header.
  185.   uint64_t Size = 0;
  186.   /// Format and version.
  187.   dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32};
  188.  
  189.   StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size,
  190.                                    uint8_t Version, dwarf::DwarfFormat Format)
  191.       : Base(Base), Size(Size), FormParams({Version, 0, Format}) {}
  192.   StrOffsetsContributionDescriptor() = default;
  193.  
  194.   uint8_t getVersion() const { return FormParams.Version; }
  195.   dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
  196.   uint8_t getDwarfOffsetByteSize() const {
  197.     return FormParams.getDwarfOffsetByteSize();
  198.   }
  199.   /// Determine whether a contribution to the string offsets table is
  200.   /// consistent with the relevant section size and that its length is
  201.   /// a multiple of the size of one of its entries.
  202.   Expected<StrOffsetsContributionDescriptor>
  203.   validateContributionSize(DWARFDataExtractor &DA);
  204. };
  205.  
  206. class DWARFUnit {
  207.   DWARFContext &Context;
  208.   /// Section containing this DWARFUnit.
  209.   const DWARFSection &InfoSection;
  210.  
  211.   DWARFUnitHeader Header;
  212.   const DWARFDebugAbbrev *Abbrev;
  213.   const DWARFSection *RangeSection;
  214.   uint64_t RangeSectionBase;
  215.   uint64_t LocSectionBase;
  216.  
  217.   /// Location table of this unit.
  218.   std::unique_ptr<DWARFLocationTable> LocTable;
  219.  
  220.   const DWARFSection &LineSection;
  221.   StringRef StringSection;
  222.   const DWARFSection &StringOffsetSection;
  223.   const DWARFSection *AddrOffsetSection;
  224.   DWARFUnit *SU;
  225.   std::optional<uint64_t> AddrOffsetSectionBase;
  226.   bool IsLittleEndian;
  227.   bool IsDWO;
  228.   const DWARFUnitVector &UnitVector;
  229.  
  230.   /// Start, length, and DWARF format of the unit's contribution to the string
  231.   /// offsets table (DWARF v5).
  232.   std::optional<StrOffsetsContributionDescriptor>
  233.       StringOffsetsTableContribution;
  234.  
  235.   mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
  236.   std::optional<object::SectionedAddress> BaseAddr;
  237.   /// The compile unit debug information entry items.
  238.   std::vector<DWARFDebugInfoEntry> DieArray;
  239.  
  240.   /// Map from range's start address to end address and corresponding DIE.
  241.   /// IntervalMap does not support range removal, as a result, we use the
  242.   /// std::map::upper_bound for address range lookup.
  243.   std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
  244.  
  245.   /// Map from the location (interpreted DW_AT_location) of a DW_TAG_variable,
  246.   /// to the end address and the corresponding DIE.
  247.   std::map<uint64_t, std::pair<uint64_t, DWARFDie>> VariableDieMap;
  248.   DenseSet<uint64_t> RootsParsedForVariables;
  249.  
  250.   using die_iterator_range =
  251.       iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
  252.  
  253.   std::shared_ptr<DWARFUnit> DWO;
  254.  
  255. protected:
  256.   /// Return the index of a \p Die entry inside the unit's DIE vector.
  257.   ///
  258.   /// It is illegal to call this method with a DIE that hasn't be
  259.   /// created by this unit. In other word, it's illegal to call this
  260.   /// method on a DIE that isn't accessible by following
  261.   /// children/sibling links starting from this unit's getUnitDIE().
  262.   uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {
  263.     auto First = DieArray.data();
  264.     assert(Die >= First && Die < First + DieArray.size());
  265.     return Die - First;
  266.   }
  267.  
  268.   /// Return DWARFDebugInfoEntry for the specified index \p Index.
  269.   const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {
  270.     assert(Index < DieArray.size());
  271.     return &DieArray[Index];
  272.   }
  273.  
  274.   const DWARFDebugInfoEntry *
  275.   getParentEntry(const DWARFDebugInfoEntry *Die) const;
  276.   const DWARFDebugInfoEntry *
  277.   getSiblingEntry(const DWARFDebugInfoEntry *Die) const;
  278.   const DWARFDebugInfoEntry *
  279.   getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const;
  280.   const DWARFDebugInfoEntry *
  281.   getFirstChildEntry(const DWARFDebugInfoEntry *Die) const;
  282.   const DWARFDebugInfoEntry *
  283.   getLastChildEntry(const DWARFDebugInfoEntry *Die) const;
  284.  
  285.   const DWARFUnitHeader &getHeader() const { return Header; }
  286.  
  287.   /// Find the unit's contribution to the string offsets table and determine its
  288.   /// length and form. The given offset is expected to be derived from the unit
  289.   /// DIE's DW_AT_str_offsets_base attribute.
  290.   Expected<std::optional<StrOffsetsContributionDescriptor>>
  291.   determineStringOffsetsTableContribution(DWARFDataExtractor &DA);
  292.  
  293.   /// Find the unit's contribution to the string offsets table and determine its
  294.   /// length and form. The given offset is expected to be 0 in a dwo file or,
  295.   /// in a dwp file, the start of the unit's contribution to the string offsets
  296.   /// table section (as determined by the index table).
  297.   Expected<std::optional<StrOffsetsContributionDescriptor>>
  298.   determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA);
  299.  
  300. public:
  301.   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
  302.             const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
  303.             const DWARFSection *RS, const DWARFSection *LocSection,
  304.             StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
  305.             const DWARFSection &LS, bool LE, bool IsDWO,
  306.             const DWARFUnitVector &UnitVector);
  307.  
  308.   virtual ~DWARFUnit();
  309.  
  310.   bool isLittleEndian() const { return IsLittleEndian; }
  311.   bool isDWOUnit() const { return IsDWO; }
  312.   DWARFContext& getContext() const { return Context; }
  313.   const DWARFSection &getInfoSection() const { return InfoSection; }
  314.   uint64_t getOffset() const { return Header.getOffset(); }
  315.   const dwarf::FormParams &getFormParams() const {
  316.     return Header.getFormParams();
  317.   }
  318.   uint16_t getVersion() const { return Header.getVersion(); }
  319.   uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); }
  320.   uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); }
  321.   uint8_t getDwarfOffsetByteSize() const {
  322.     return Header.getDwarfOffsetByteSize();
  323.   }
  324.   /// Size in bytes of the parsed unit header.
  325.   uint32_t getHeaderSize() const { return Header.getSize(); }
  326.   uint64_t getLength() const { return Header.getLength(); }
  327.   dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
  328.   uint8_t getUnitType() const { return Header.getUnitType(); }
  329.   bool isTypeUnit() const { return Header.isTypeUnit(); }
  330.   uint64_t getAbbrOffset() const { return Header.getAbbrOffset(); }
  331.   uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
  332.   const DWARFSection &getLineSection() const { return LineSection; }
  333.   StringRef getStringSection() const { return StringSection; }
  334.   const DWARFSection &getStringOffsetSection() const {
  335.     return StringOffsetSection;
  336.   }
  337.  
  338.   void setSkeletonUnit(DWARFUnit *SU) { this->SU = SU; }
  339.   // Returns itself if not using Split DWARF, or if the unit is a skeleton unit
  340.   // - otherwise returns the split full unit's corresponding skeleton, if
  341.   // available.
  342.   DWARFUnit *getLinkedUnit() { return IsDWO ? SU : this; }
  343.  
  344.   void setAddrOffsetSection(const DWARFSection *AOS, uint64_t Base) {
  345.     AddrOffsetSection = AOS;
  346.     AddrOffsetSectionBase = Base;
  347.   }
  348.  
  349.   std::optional<uint64_t> getAddrOffsetSectionBase() const {
  350.     return AddrOffsetSectionBase;
  351.   }
  352.  
  353.   /// Recursively update address to Die map.
  354.   void updateAddressDieMap(DWARFDie Die);
  355.  
  356.   /// Recursively update address to variable Die map.
  357.   void updateVariableDieMap(DWARFDie Die);
  358.  
  359.   void setRangesSection(const DWARFSection *RS, uint64_t Base) {
  360.     RangeSection = RS;
  361.     RangeSectionBase = Base;
  362.   }
  363.  
  364.   uint64_t getLocSectionBase() const {
  365.     return LocSectionBase;
  366.   }
  367.  
  368.   std::optional<object::SectionedAddress>
  369.   getAddrOffsetSectionItem(uint32_t Index) const;
  370.   Expected<uint64_t> getStringOffsetSectionItem(uint32_t Index) const;
  371.  
  372.   DWARFDataExtractor getDebugInfoExtractor() const;
  373.  
  374.   DataExtractor getStringExtractor() const {
  375.     return DataExtractor(StringSection, false, 0);
  376.   }
  377.  
  378.   const DWARFLocationTable &getLocationTable() { return *LocTable; }
  379.  
  380.   /// Extract the range list referenced by this compile unit from the
  381.   /// .debug_ranges section. If the extraction is unsuccessful, an error
  382.   /// is returned. Successful extraction requires that the compile unit
  383.   /// has already been extracted.
  384.   Error extractRangeList(uint64_t RangeListOffset,
  385.                          DWARFDebugRangeList &RangeList) const;
  386.   void clear();
  387.  
  388.   const std::optional<StrOffsetsContributionDescriptor> &
  389.   getStringOffsetsTableContribution() const {
  390.     return StringOffsetsTableContribution;
  391.   }
  392.  
  393.   uint8_t getDwarfStringOffsetsByteSize() const {
  394.     assert(StringOffsetsTableContribution);
  395.     return StringOffsetsTableContribution->getDwarfOffsetByteSize();
  396.   }
  397.  
  398.   uint64_t getStringOffsetsBase() const {
  399.     assert(StringOffsetsTableContribution);
  400.     return StringOffsetsTableContribution->Base;
  401.   }
  402.  
  403.   uint64_t getAbbreviationsOffset() const { return Header.getAbbrOffset(); }
  404.  
  405.   const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
  406.  
  407.   static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) {
  408.     switch (UnitType) {
  409.     case dwarf::DW_UT_compile:
  410.       return Tag == dwarf::DW_TAG_compile_unit;
  411.     case dwarf::DW_UT_type:
  412.       return Tag == dwarf::DW_TAG_type_unit;
  413.     case dwarf::DW_UT_partial:
  414.       return Tag == dwarf::DW_TAG_partial_unit;
  415.     case dwarf::DW_UT_skeleton:
  416.       return Tag == dwarf::DW_TAG_skeleton_unit;
  417.     case dwarf::DW_UT_split_compile:
  418.     case dwarf::DW_UT_split_type:
  419.       return dwarf::isUnitType(Tag);
  420.     }
  421.     return false;
  422.   }
  423.  
  424.   std::optional<object::SectionedAddress> getBaseAddress();
  425.  
  426.   DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
  427.     extractDIEsIfNeeded(ExtractUnitDIEOnly);
  428.     if (DieArray.empty())
  429.       return DWARFDie();
  430.     return DWARFDie(this, &DieArray[0]);
  431.   }
  432.  
  433.   DWARFDie getNonSkeletonUnitDIE(bool ExtractUnitDIEOnly = true,
  434.                                  StringRef DWOAlternativeLocation = {}) {
  435.     parseDWO(DWOAlternativeLocation);
  436.     return DWO ? DWO->getUnitDIE(ExtractUnitDIEOnly)
  437.                : getUnitDIE(ExtractUnitDIEOnly);
  438.   }
  439.  
  440.   const char *getCompilationDir();
  441.   std::optional<uint64_t> getDWOId() {
  442.     extractDIEsIfNeeded(/*CUDieOnly*/ true);
  443.     return getHeader().getDWOId();
  444.   }
  445.   void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
  446.  
  447.   /// Return a vector of address ranges resulting from a (possibly encoded)
  448.   /// range list starting at a given offset in the appropriate ranges section.
  449.   Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint64_t Offset);
  450.  
  451.   /// Return a vector of address ranges retrieved from an encoded range
  452.   /// list whose offset is found via a table lookup given an index (DWARF v5
  453.   /// and later).
  454.   Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index);
  455.  
  456.   /// Return a rangelist's offset based on an index. The index designates
  457.   /// an entry in the rangelist table's offset array and is supplied by
  458.   /// DW_FORM_rnglistx.
  459.   std::optional<uint64_t> getRnglistOffset(uint32_t Index);
  460.  
  461.   std::optional<uint64_t> getLoclistOffset(uint32_t Index);
  462.  
  463.   Expected<DWARFAddressRangesVector> collectAddressRanges();
  464.  
  465.   Expected<DWARFLocationExpressionsVector>
  466.   findLoclistFromOffset(uint64_t Offset);
  467.  
  468.   /// Returns subprogram DIE with address range encompassing the provided
  469.   /// address. The pointer is alive as long as parsed compile unit DIEs are not
  470.   /// cleared.
  471.   DWARFDie getSubroutineForAddress(uint64_t Address);
  472.  
  473.   /// Returns variable DIE for the address provided. The pointer is alive as
  474.   /// long as parsed compile unit DIEs are not cleared.
  475.   DWARFDie getVariableForAddress(uint64_t Address);
  476.  
  477.   /// getInlinedChainForAddress - fetches inlined chain for a given address.
  478.   /// Returns empty chain if there is no subprogram containing address. The
  479.   /// chain is valid as long as parsed compile unit DIEs are not cleared.
  480.   void getInlinedChainForAddress(uint64_t Address,
  481.                                  SmallVectorImpl<DWARFDie> &InlinedChain);
  482.  
  483.   /// Return the DWARFUnitVector containing this unit.
  484.   const DWARFUnitVector &getUnitVector() const { return UnitVector; }
  485.  
  486.   /// Returns the number of DIEs in the unit. Parses the unit
  487.   /// if necessary.
  488.   unsigned getNumDIEs() {
  489.     extractDIEsIfNeeded(false);
  490.     return DieArray.size();
  491.   }
  492.  
  493.   /// Return the index of a DIE inside the unit's DIE vector.
  494.   ///
  495.   /// It is illegal to call this method with a DIE that hasn't be
  496.   /// created by this unit. In other word, it's illegal to call this
  497.   /// method on a DIE that isn't accessible by following
  498.   /// children/sibling links starting from this unit's getUnitDIE().
  499.   uint32_t getDIEIndex(const DWARFDie &D) const {
  500.     return getDIEIndex(D.getDebugInfoEntry());
  501.   }
  502.  
  503.   /// Return the DIE object at the given index \p Index.
  504.   DWARFDie getDIEAtIndex(unsigned Index) {
  505.     return DWARFDie(this, getDebugInfoEntry(Index));
  506.   }
  507.  
  508.   DWARFDie getParent(const DWARFDebugInfoEntry *Die);
  509.   DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
  510.   DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
  511.   DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
  512.   DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
  513.  
  514.   /// Return the DIE object for a given offset \p Offset inside the
  515.   /// unit's DIE vector.
  516.   DWARFDie getDIEForOffset(uint64_t Offset) {
  517.     if (std::optional<uint32_t> DieIdx = getDIEIndexForOffset(Offset))
  518.       return DWARFDie(this, &DieArray[*DieIdx]);
  519.  
  520.     return DWARFDie();
  521.   }
  522.  
  523.   /// Return the DIE index for a given offset \p Offset inside the
  524.   /// unit's DIE vector.
  525.   std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
  526.     extractDIEsIfNeeded(false);
  527.     auto It =
  528.         llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
  529.           return DIE.getOffset() < Offset;
  530.         });
  531.     if (It != DieArray.end() && It->getOffset() == Offset)
  532.       return It - DieArray.begin();
  533.     return std::nullopt;
  534.   }
  535.  
  536.   uint32_t getLineTableOffset() const {
  537.     if (auto IndexEntry = Header.getIndexEntry())
  538.       if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LINE))
  539.         return Contrib->getOffset32();
  540.     return 0;
  541.   }
  542.  
  543.   die_iterator_range dies() {
  544.     extractDIEsIfNeeded(false);
  545.     return die_iterator_range(DieArray.begin(), DieArray.end());
  546.   }
  547.  
  548.   virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
  549.  
  550.   Error tryExtractDIEsIfNeeded(bool CUDieOnly);
  551.  
  552. private:
  553.   /// Size in bytes of the .debug_info data associated with this compile unit.
  554.   size_t getDebugInfoSize() const {
  555.     return Header.getLength() + Header.getUnitLengthFieldByteSize() -
  556.            getHeaderSize();
  557.   }
  558.  
  559.   /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
  560.   /// hasn't already been done
  561.   void extractDIEsIfNeeded(bool CUDieOnly);
  562.  
  563.   /// extractDIEsToVector - Appends all parsed DIEs to a vector.
  564.   void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
  565.                            std::vector<DWARFDebugInfoEntry> &DIEs) const;
  566.  
  567.   /// clearDIEs - Clear parsed DIEs to keep memory usage low.
  568.   void clearDIEs(bool KeepCUDie);
  569.  
  570.   /// parseDWO - Parses .dwo file for current compile unit. Returns true if
  571.   /// it was actually constructed.
  572.   /// The \p AlternativeLocation specifies an alternative location to get
  573.   /// the DWARF context for the DWO object; this is the case when it has
  574.   /// been moved from its original location.
  575.   bool parseDWO(StringRef AlternativeLocation = {});
  576. };
  577.  
  578. inline bool isCompileUnit(const std::unique_ptr<DWARFUnit> &U) {
  579.   return !U->isTypeUnit();
  580. }
  581.  
  582. } // end namespace llvm
  583.  
  584. #endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
  585.