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;
|
using namespace lldb_private;
|
||||||
|
|
||||||
void DWARFDIE::ElaboratingDIEIterator::Next() {
|
namespace {
|
||||||
assert(!m_worklist.empty() && "Incrementing end iterator?");
|
|
||||||
|
|
||||||
// Pop the current item from the list.
|
/// Iterate through all DIEs elaborating (i.e. reachable by a chain of
|
||||||
DWARFDIE die = m_worklist.back();
|
/// DW_AT_specification and DW_AT_abstract_origin attributes) a given DIE. For
|
||||||
m_worklist.pop_back();
|
/// 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.
|
// The operating invariant is: top of m_worklist contains the "current" item
|
||||||
for (dw_attr_t attr : {DW_AT_specification, DW_AT_abstract_origin}) {
|
// and the rest of the list are items yet to be visited. An empty worklist
|
||||||
if (DWARFDIE d = die.GetReferencedDIE(attr))
|
// means we've reached the end.
|
||||||
if (m_seen.insert(die.GetID()).second)
|
// Infinite recursion is prevented by maintaining a list of seen DIEs.
|
||||||
m_worklist.push_back(d);
|
// 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
|
||||||
DWARFDIE::GetParent() const {
|
DWARFDIE::GetParent() const {
|
||||||
|
@ -229,7 +284,7 @@ bool DWARFDIE::IsStructUnionOrClass() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DWARFDIE::IsMethod() const {
|
bool DWARFDIE::IsMethod() const {
|
||||||
for (DWARFDIE d: elaborating_dies())
|
for (DWARFDIE d : elaborating_dies(*this))
|
||||||
if (d.GetParent().IsStructUnionOrClass())
|
if (d.GetParent().IsStructUnionOrClass())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
|
|
||||||
class DWARFDIE : public DWARFBaseDIE {
|
class DWARFDIE : public DWARFBaseDIE {
|
||||||
public:
|
public:
|
||||||
class ElaboratingDIEIterator;
|
|
||||||
|
|
||||||
using DWARFBaseDIE::DWARFBaseDIE;
|
using DWARFBaseDIE::DWARFBaseDIE;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -33,8 +31,6 @@ public:
|
||||||
DWARFDIE
|
DWARFDIE
|
||||||
GetContainingDWOModuleDIE() const;
|
GetContainingDWOModuleDIE() const;
|
||||||
|
|
||||||
inline llvm::iterator_range<ElaboratingDIEIterator> elaborating_dies() const;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Accessing information about a DIE
|
// Accessing information about a DIE
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
@ -121,58 +117,4 @@ public:
|
||||||
lldb_private::CompilerDeclContext GetContainingDeclContext() const;
|
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_
|
#endif // SymbolFileDWARF_DWARFDIE_h_
|
||||||
|
|
Loading…
Reference in New Issue