diff options
Diffstat (limited to 'include/llvm/DebugInfo/DWARF/DWARFDie.h')
-rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFDie.h | 163 |
1 files changed, 85 insertions, 78 deletions
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index e335e28b39d7..33e24fe3adc9 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -1,4 +1,4 @@ -//===-- DWARFDie.h --------------------------------------------------------===// +//===- DWARFDie.h -----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,18 +7,25 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_DEBUGINFO_DWARFDIE_H -#define LLVM_LIB_DEBUGINFO_DWARFDIE_H +#ifndef LLVM_DEBUGINFO_DWARFDIE_H +#define LLVM_DEBUGINFO_DWARFDIE_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/DebugInfo/DWARF/DWARFAttribute.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" +#include "llvm/Support/Dwarf.h" +#include <cassert> +#include <cstdint> +#include <iterator> namespace llvm { class DWARFUnit; -class DWARFDebugInfoEntry; class raw_ostream; //===----------------------------------------------------------------------===// @@ -34,10 +41,11 @@ class raw_ostream; /// also simplifies the attribute extraction calls by not having to specify the /// DWARFUnit for each call. class DWARFDie { - DWARFUnit *U; - const DWARFDebugInfoEntry *Die; + DWARFUnit *U = nullptr; + const DWARFDebugInfoEntry *Die = nullptr; + public: - DWARFDie() : U(nullptr), Die(nullptr) {} + DWARFDie() = default; DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {} bool isValid() const { return U && Die; } @@ -45,7 +53,6 @@ public: const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; } DWARFUnit *getDwarfUnit() const { return U; } - /// Get the abbreviation declaration for this DIE. /// /// \returns the abbreviation declaration or NULL for null tags. @@ -78,6 +85,7 @@ public: bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; } + /// Returns true if DIE represents a subprogram (not inlined). bool isSubprogramDIE() const; @@ -123,76 +131,33 @@ public: /// \param Attr the attribute to extract. /// \returns an optional DWARFFormValue that will have the form value if the /// attribute was successfully extracted. - Optional<DWARFFormValue> getAttributeValue(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as a C string. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \param FailValue the value to return if this DIE doesn't have this - /// attribute. - /// \returns the NULL terminated C string value owned by the DWARF section - /// that contains the string or FailValue if the attribute doesn't exist or - /// if the attribute's form isn't a form that describes an string. - const char *getAttributeValueAsString(dwarf::Attribute Attr, - const char *FailValue) const; + Optional<DWARFFormValue> find(dwarf::Attribute Attr) const; - /// Extract the specified attribute from this DIE as an address. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> getAttributeValueAsAddress(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as a signed integer. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<int64_t> - getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as an unsigned integer. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> - getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const; + /// Extract the first value of any attribute in Attrs from this DIE. + /// + /// Extract the first attribute that matches from this DIE only. This call + /// doesn't look for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. The attributes will be searched + /// linearly in the order they are specified within Attrs. + /// + /// \param Attrs an array of DWARF attribute to look for. + /// \returns an optional that has a valid DWARFFormValue for the first + /// matching attribute in Attrs, or None if none of the attributes in Attrs + /// exist in this DIE. + Optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const; + + /// Extract the first value of any attribute in Attrs from this DIE and + /// recurse into any DW_AT_specification or DW_AT_abstract_origin referenced + /// DIEs. + /// + /// \param Attrs an array of DWARF attribute to look for. + /// \returns an optional that has a valid DWARFFormValue for the first + /// matching attribute in Attrs, or None if none of the attributes in Attrs + /// exist in this DIE or in any DW_AT_specification or DW_AT_abstract_origin + /// DIEs. + Optional<DWARFFormValue> + findRecursively(ArrayRef<dwarf::Attribute> Attrs) const; - /// Extract the specified attribute from this DIE as absolute DIE Offset. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> getAttributeValueAsReference(dwarf::Attribute Attr) const; - - /// Extract the specified attribute from this DIE as absolute section offset. - /// - /// Extract an attribute value from this DIE only. This call doesn't look - /// for the attribute value in any DW_AT_specification or - /// DW_AT_abstract_origin referenced DIEs. - /// - /// \param Attr the attribute to extract. - /// \returns an optional value for the attribute. - Optional<uint64_t> - getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const; - /// Extract the specified attribute from this DIE as the referenced DIE. /// /// Regardless of the reference type, return the correct DWARFDie instance if @@ -266,6 +231,12 @@ public: /// references if necessary. Returns null if no name is found. const char *getName(DINameKind Kind) const; + /// Returns the declaration line (start line) for a DIE, assuming it specifies + /// a subprogram. This may be fetched from specification or abstract origin + /// for this subprogram by resolving DW_AT_sepcification or + /// DW_AT_abstract_origin references if necessary. + uint64_t getDeclLine() const; + /// Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column /// from DIE (or zeroes if they are missing). This function looks for /// DW_AT_call attributes in this DIE only, it will not resolve the attribute @@ -286,14 +257,47 @@ public: getInlinedChainForAddress(const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const; + class attribute_iterator; + + /// Get an iterator range to all attributes in the current DIE only. + /// + /// \returns an iterator range for the attributes of the current DIE. + iterator_range<attribute_iterator> attributes() const; + class iterator; iterator begin() const; iterator end() const; iterator_range<iterator> children() const; }; - +class DWARFDie::attribute_iterator : + public iterator_facade_base<attribute_iterator, std::forward_iterator_tag, + const DWARFAttribute> { + /// The DWARF DIE we are extracting attributes from. + DWARFDie Die; + /// The value vended to clients via the operator*() or operator->(). + DWARFAttribute AttrValue; + /// The attribute index within the abbreviation declaration in Die. + uint32_t Index; + + /// Update the attribute index and attempt to read the attribute value. If the + /// attribute is able to be read, update AttrValue and the Index member + /// variable. If the attribute value is not able to be read, an appropriate + /// error will be set if the Err member variable is non-NULL and the iterator + /// will be set to the end value so iteration stops. + void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I); + +public: + attribute_iterator() = delete; + explicit attribute_iterator(DWARFDie D, bool End); + + attribute_iterator &operator++(); + explicit operator bool() const { return AttrValue.isValid(); } + const DWARFAttribute &operator*() const { return AttrValue; } + bool operator==(const attribute_iterator &X) const { return Index == X.Index; } +}; + inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) { return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() && LHS.getDwarfUnit() == RHS.getDwarfUnit(); @@ -313,16 +317,19 @@ class DWARFDie::iterator : public iterator_facade_base<iterator, } public: iterator() = default; + explicit iterator(DWARFDie D) : Die(D) { // If we start out with only a Null DIE then invalidate. skipNull(); } + iterator &operator++() { Die = Die.getSibling(); // Don't include the NULL die when iterating. skipNull(); return *this; } + explicit operator bool() const { return Die.isValid(); } const DWARFDie &operator*() const { return Die; } bool operator==(const iterator &X) const { return Die == X.Die; } @@ -344,4 +351,4 @@ inline iterator_range<DWARFDie::iterator> DWARFDie::children() const { } // end namespace llvm -#endif // LLVM_LIB_DEBUGINFO_DWARFDIE_H +#endif // LLVM_DEBUGINFO_DWARFDIE_H |