Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -14,8 +14,6 @@ class DWARFDIE : public DWARFBaseDIE { public: - class ElaboratingDIEIterator; - using DWARFBaseDIE::DWARFBaseDIE; //---------------------------------------------------------------------- @@ -33,8 +31,6 @@ DWARFDIE GetContainingDWOModuleDIE() const; - inline llvm::iterator_range elaborating_dies() const; - //---------------------------------------------------------------------- // Accessing information about a DIE //---------------------------------------------------------------------- @@ -121,58 +117,4 @@ lldb_private::CompilerDeclContext GetContainingDeclContext() const; }; -/// Iterate through all DIEs elaborating (i.e. reachable by a chain of -/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For -/// convenience, the starting die is included in the sequence as the first -/// item. -class DWARFDIE::ElaboratingDIEIterator - : public std::iterator { - - // The operating invariant is: top of m_worklist contains the "current" item - // and the rest of the list are items yet to be visited. An empty worklist - // means we've reached the end. - // Infinite recursion is prevented by maintaining a list of seen DIEs. - // Container sizes are optimized for the case of following DW_AT_specification - // and DW_AT_abstract_origin just once. - llvm::SmallVector m_worklist; - llvm::SmallSet m_seen; - - void Next(); - -public: - /// An iterator starting at die d. - explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {} - - /// End marker - ElaboratingDIEIterator() {} - - const DWARFDIE &operator*() const { return m_worklist.back(); } - ElaboratingDIEIterator &operator++() { - Next(); - return *this; - } - ElaboratingDIEIterator operator++(int) { - ElaboratingDIEIterator I = *this; - Next(); - return I; - } - - friend bool operator==(const ElaboratingDIEIterator &a, - const ElaboratingDIEIterator &b) { - if (a.m_worklist.empty() || b.m_worklist.empty()) - return a.m_worklist.empty() == b.m_worklist.empty(); - return a.m_worklist.back() == b.m_worklist.back(); - } - friend bool operator!=(const ElaboratingDIEIterator &a, - const ElaboratingDIEIterator &b) { - return !(a == b); - } -}; - -llvm::iterator_range -DWARFDIE::elaborating_dies() const { - return llvm::make_range(ElaboratingDIEIterator(*this), - ElaboratingDIEIterator()); -} - #endif // SymbolFileDWARF_DWARFDIE_h_ Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -17,20 +17,75 @@ using namespace lldb_private; -void DWARFDIE::ElaboratingDIEIterator::Next() { - assert(!m_worklist.empty() && "Incrementing end iterator?"); +namespace { - // Pop the current item from the list. - DWARFDIE die = m_worklist.back(); - m_worklist.pop_back(); - - // And add back any items that elaborate it. - for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) { - if (DWARFDIE d = die.GetReferencedDIE(attr)) - if (m_seen.insert(die.GetID()).second) - m_worklist.push_back(d); +/// Iterate through all DIEs elaborating (i.e. reachable by a chain of +/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For +/// convenience, the starting die is included in the sequence as the first +/// item. +class ElaboratingDIEIterator + : public std::iterator { + + // The operating invariant is: top of m_worklist contains the "current" item + // and the rest of the list are items yet to be visited. An empty worklist + // means we've reached the end. + // Infinite recursion is prevented by maintaining a list of seen DIEs. + // Container sizes are optimized for the case of following DW_AT_specification + // and DW_AT_abstract_origin just once. + llvm::SmallVector m_worklist; + llvm::SmallSet m_seen; + + void Next() { + assert(!m_worklist.empty() && "Incrementing end iterator?"); + + // Pop the current item from the list. + DWARFDIE die = m_worklist.back(); + m_worklist.pop_back(); + + // And add back any items that elaborate it. + for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) { + if (DWARFDIE d = die.GetReferencedDIE(attr)) + if (m_seen.insert(die.GetID()).second) + m_worklist.push_back(d); + } + } + +public: + /// An iterator starting at die d. + explicit ElaboratingDIEIterator(DWARFDIE d) : m_worklist(1, d) {} + + /// End marker + ElaboratingDIEIterator() {} + + const DWARFDIE &operator*() const { return m_worklist.back(); } + ElaboratingDIEIterator &operator++() { + Next(); + return *this; + } + ElaboratingDIEIterator operator++(int) { + ElaboratingDIEIterator I = *this; + Next(); + return I; } + + friend bool operator==(const ElaboratingDIEIterator &a, + const ElaboratingDIEIterator &b) { + if (a.m_worklist.empty() || b.m_worklist.empty()) + return a.m_worklist.empty() == b.m_worklist.empty(); + return a.m_worklist.back() == b.m_worklist.back(); + } + friend bool operator!=(const ElaboratingDIEIterator &a, + const ElaboratingDIEIterator &b) { + return !(a == b); + } +}; + +llvm::iterator_range +elaborating_dies(const DWARFDIE &die) { + return llvm::make_range(ElaboratingDIEIterator(die), + ElaboratingDIEIterator()); } +} // namespace DWARFDIE DWARFDIE::GetParent() const { @@ -229,7 +284,7 @@ } bool DWARFDIE::IsMethod() const { - for (DWARFDIE d: elaborating_dies()) + for (DWARFDIE d : elaborating_dies(*this)) if (d.GetParent().IsStructUnionOrClass()) return true; return false;