forked from OSchip/llvm-project
Move ElaboratingDIEIterator into implementation file.
This is not used outside of the private implementation of the class, so hiding in the implementation file is a nice way of simplifying the external interface. Differential Revision: https://reviews.llvm.org/D59164 llvm-svn: 355973
This commit is contained in:
parent
0c29402eb4
commit
d5364dfa6d
|
@ -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();
|
||||
/// 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<std::input_iterator_tag, DWARFDIE> {
|
||||
|
||||
// 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);
|
||||
// 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<DWARFDIE, 2> m_worklist;
|
||||
llvm::SmallSet<lldb::user_id_t, 3> 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<ElaboratingDIEIterator>
|
||||
elaborating_dies(const DWARFDIE &die) {
|
||||
return llvm::make_range(ElaboratingDIEIterator(die),
|
||||
ElaboratingDIEIterator());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
DWARFDIE
|
||||
DWARFDIE::GetParent() const {
|
||||
|
@ -229,7 +284,7 @@ bool DWARFDIE::IsStructUnionOrClass() const {
|
|||
}
|
||||
|
||||
bool DWARFDIE::IsMethod() const {
|
||||
for (DWARFDIE d: elaborating_dies())
|
||||
for (DWARFDIE d : elaborating_dies(*this))
|
||||
if (d.GetParent().IsStructUnionOrClass())
|
||||
return true;
|
||||
return false;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
class DWARFDIE : public DWARFBaseDIE {
|
||||
public:
|
||||
class ElaboratingDIEIterator;
|
||||
|
||||
using DWARFBaseDIE::DWARFBaseDIE;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -33,8 +31,6 @@ public:
|
|||
DWARFDIE
|
||||
GetContainingDWOModuleDIE() const;
|
||||
|
||||
inline llvm::iterator_range<ElaboratingDIEIterator> elaborating_dies() const;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Accessing information about a DIE
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -121,58 +117,4 @@ public:
|
|||
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<std::input_iterator_tag, DWARFDIE> {
|
||||
|
||||
// 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<DWARFDIE, 2> m_worklist;
|
||||
llvm::SmallSet<lldb::user_id_t, 3> 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::ElaboratingDIEIterator>
|
||||
DWARFDIE::elaborating_dies() const {
|
||||
return llvm::make_range(ElaboratingDIEIterator(*this),
|
||||
ElaboratingDIEIterator());
|
||||
}
|
||||
|
||||
#endif // SymbolFileDWARF_DWARFDIE_h_
|
||||
|
|
Loading…
Reference in New Issue