diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:32:43 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:32:43 +0000 | 
| commit | b7eb8e35e481a74962664b63dfb09483b200209a (patch) | |
| tree | 1937fb4a348458ce2d02ade03ac3bb0aa18d2fcd /include/llvm/DebugInfo/DWARF/DWARFDie.h | |
| parent | eb11fae6d08f479c0799db45860a98af528fa6e7 (diff) | |
Notes
Diffstat (limited to 'include/llvm/DebugInfo/DWARF/DWARFDie.h')
| -rw-r--r-- | include/llvm/DebugInfo/DWARF/DWARFDie.h | 129 | 
1 files changed, 115 insertions, 14 deletions
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h index 6e6b57cbcbd4..c77034f6348f 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -46,7 +46,7 @@ class DWARFDie {  public:    DWARFDie() = default; -  DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry * D) : U(Unit), Die(D) {} +  DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry *D) : U(Unit), Die(D) {}    bool isValid() const { return U && Die; }    explicit operator bool() const { return isValid(); } @@ -82,9 +82,7 @@ public:    }    /// Returns true for a valid DIE that terminates a sibling chain. -  bool isNULL() const { -    return getAbbreviationDeclarationPtr() == nullptr; -  } +  bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; }    /// Returns true if DIE represents a subprogram (not inlined).    bool isSubprogramDIE() const; @@ -129,7 +127,6 @@ public:    void dump(raw_ostream &OS, unsigned indent = 0,              DIDumpOptions DumpOpts = DIDumpOptions()) const; -    /// Convenience zero-argument overload for debugging.    LLVM_DUMP_METHOD void dump() const; @@ -275,12 +272,16 @@ public:    iterator begin() const;    iterator end() const; + +  std::reverse_iterator<iterator> rbegin() const; +  std::reverse_iterator<iterator> rend() const; +    iterator_range<iterator> children() const;  }; -class DWARFDie::attribute_iterator : -    public iterator_facade_base<attribute_iterator, std::forward_iterator_tag, -                                const DWARFAttribute> { +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->(). @@ -288,6 +289,9 @@ class DWARFDie::attribute_iterator :    /// The attribute index within the abbreviation declaration in Die.    uint32_t Index; +  friend bool operator==(const attribute_iterator &LHS, +                         const attribute_iterator &RHS); +    /// 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 @@ -303,12 +307,21 @@ public:    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::attribute_iterator &LHS, +                       const DWARFDie::attribute_iterator &RHS) { +  return LHS.Index == RHS.Index; +} + +inline bool operator!=(const DWARFDie::attribute_iterator &LHS, +                       const DWARFDie::attribute_iterator &RHS) { +  return !(LHS == RHS); +} +  inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) {    return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() && -      LHS.getDwarfUnit() == RHS.getDwarfUnit(); +         LHS.getDwarfUnit() == RHS.getDwarfUnit();  }  inline bool operator!=(const DWARFDie &LHS, const DWARFDie &RHS) { @@ -323,11 +336,15 @@ class DWARFDie::iterator      : public iterator_facade_base<iterator, std::bidirectional_iterator_tag,                                    const DWARFDie> {    DWARFDie Die; + +  friend std::reverse_iterator<llvm::DWARFDie::iterator>; +  friend bool operator==(const DWARFDie::iterator &LHS, +                         const DWARFDie::iterator &RHS); +  public:    iterator() = default; -  explicit iterator(DWARFDie D) : Die(D) { -  } +  explicit iterator(DWARFDie D) : Die(D) {}    iterator &operator++() {      Die = Die.getSibling(); @@ -339,11 +356,19 @@ public:      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; }  }; +inline bool operator==(const DWARFDie::iterator &LHS, +                       const DWARFDie::iterator &RHS) { +  return LHS.Die == RHS.Die; +} + +inline bool operator!=(const DWARFDie::iterator &LHS, +                       const DWARFDie::iterator &RHS) { +  return !(LHS == RHS); +} +  // These inline functions must follow the DWARFDie::iterator definition above  // as they use functions from that class.  inline DWARFDie::iterator DWARFDie::begin() const { @@ -360,4 +385,80 @@ inline iterator_range<DWARFDie::iterator> DWARFDie::children() const {  } // end namespace llvm +namespace std { + +template <> +class reverse_iterator<llvm::DWARFDie::iterator> +    : public llvm::iterator_facade_base< +          reverse_iterator<llvm::DWARFDie::iterator>, +          bidirectional_iterator_tag, const llvm::DWARFDie> { + +private: +  llvm::DWARFDie Die; +  bool AtEnd; + +public: +  reverse_iterator(llvm::DWARFDie::iterator It) +      : Die(It.Die), AtEnd(!It.Die.getPreviousSibling()) { +    if (!AtEnd) +      Die = Die.getPreviousSibling(); +  } + +  reverse_iterator<llvm::DWARFDie::iterator> &operator++() { +    assert(!AtEnd && "Incrementing rend"); +    llvm::DWARFDie D = Die.getPreviousSibling(); +    if (D) +      Die = D; +    else +      AtEnd = true; +    return *this; +  } + +  reverse_iterator<llvm::DWARFDie::iterator> &operator--() { +    if (AtEnd) { +      AtEnd = false; +      return *this; +    } +    Die = Die.getSibling(); +    assert(!Die.isNULL() && "Decrementing rbegin"); +    return *this; +  } + +  const llvm::DWARFDie &operator*() const { +    assert(Die.isValid()); +    return Die; +  } + +  // FIXME: We should be able to specify the equals operator as a friend, but +  //        that causes the compiler to think the operator overload is ambiguous +  //        with the friend declaration and the actual definition as candidates. +  bool equals(const reverse_iterator<llvm::DWARFDie::iterator> &RHS) const { +    return Die == RHS.Die && AtEnd == RHS.AtEnd; +  } +}; + +} // namespace std + +namespace llvm { + +inline bool operator==(const std::reverse_iterator<DWARFDie::iterator> &LHS, +                       const std::reverse_iterator<DWARFDie::iterator> &RHS) { +  return LHS.equals(RHS); +} + +inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS, +                       const std::reverse_iterator<DWARFDie::iterator> &RHS) { +  return !(LHS == RHS); +} + +inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rbegin() const { +  return llvm::make_reverse_iterator(end()); +} + +inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rend() const { +  return llvm::make_reverse_iterator(begin()); +} + +} // end namespace llvm +  #endif // LLVM_DEBUGINFO_DWARFDIE_H  | 
