mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2026-08-27 00:26:02 -04:00
Simon's changes
Change-Id: Ieee3c051b9b4bc949262ecbc44e1db2ad3bebe38
This commit is contained in:
parent
b22fc8ee9b
commit
e8d35bb501
2 changed files with 73 additions and 97 deletions
97
gdb/block.h
97
gdb/block.h
|
|
@ -108,54 +108,6 @@ struct blockranges
|
|||
|
||||
struct block : public allocate_on_obstack<block>
|
||||
{
|
||||
/* Variant of next_iterator using the superblock field instead of next. */
|
||||
struct superblock_iterator : base_next_iterator<const block>
|
||||
{
|
||||
typedef superblock_iterator self_type;
|
||||
|
||||
explicit superblock_iterator (value_type item)
|
||||
: base_next_iterator (item)
|
||||
{
|
||||
}
|
||||
|
||||
superblock_iterator () = default;
|
||||
|
||||
self_type &operator++ ()
|
||||
{
|
||||
this->m_item = this->m_item->superblock ();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/* Variant of next_iterator using the superblock field instead of next. */
|
||||
struct function_block_iterator : base_next_iterator<const block>
|
||||
{
|
||||
typedef function_block_iterator self_type;
|
||||
|
||||
explicit function_block_iterator (value_type item)
|
||||
: base_next_iterator (item->is_global_block () || item->is_static_block ()
|
||||
? nullptr : item)
|
||||
{
|
||||
}
|
||||
|
||||
function_block_iterator () = default;
|
||||
|
||||
self_type &operator++ ()
|
||||
{
|
||||
if (this->m_item->function () != nullptr)
|
||||
{
|
||||
this->m_item = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
this->m_item = this->m_item->superblock ();
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
using superblock_range = iterator_range<superblock_iterator>;
|
||||
using function_block_range = iterator_range<function_block_iterator>;
|
||||
|
||||
/* Return this block's start address. */
|
||||
CORE_ADDR start () const
|
||||
{ return m_start; }
|
||||
|
|
@ -354,6 +306,20 @@ struct block : public allocate_on_obstack<block>
|
|||
|
||||
struct dynamic_prop *static_link () const;
|
||||
|
||||
/* Iterator and range type to iterate over this block and its superblocks. */
|
||||
|
||||
struct superblock_incrementer
|
||||
{
|
||||
const block *operator() (const block &b) const noexcept
|
||||
{ return b.superblock (); }
|
||||
};
|
||||
|
||||
using superblock_iterator
|
||||
= base_next_iterator<const block, superblock_incrementer>;
|
||||
using superblock_range = iterator_range<superblock_iterator>;
|
||||
|
||||
/* Return a range to iterate over this block and its superblocks. */
|
||||
|
||||
superblock_range super_blocks () const
|
||||
{
|
||||
superblock_range::iterator begin (this);
|
||||
|
|
@ -361,13 +327,41 @@ struct block : public allocate_on_obstack<block>
|
|||
return superblock_range (std::move (begin));
|
||||
}
|
||||
|
||||
/* Iterator and range type to iterate over this block and its superblocks
|
||||
within a function. */
|
||||
|
||||
struct function_block_incrementer
|
||||
{
|
||||
const block *operator() (const block &b) const noexcept
|
||||
{
|
||||
/* If the current item is the function-defining block, we're done. */
|
||||
if (b.function () != nullptr)
|
||||
return nullptr;
|
||||
|
||||
return b.superblock ();
|
||||
}
|
||||
};
|
||||
|
||||
using function_block_iterator
|
||||
= base_next_iterator<const block, function_block_incrementer>;
|
||||
using function_block_range = iterator_range<function_block_iterator>;
|
||||
|
||||
/* Assuming that this is a block within a function, return a range to iterate
|
||||
over this block and its superblocks up to that function's block.
|
||||
|
||||
This method must not be called on global or static blocks. */
|
||||
|
||||
function_block_range function_blocks () const
|
||||
{
|
||||
function_block_range::iterator begin (this);
|
||||
gdb_assert (!this->is_global_block ());
|
||||
gdb_assert (!this->is_static_block ());
|
||||
|
||||
return function_block_range (std::move (begin));
|
||||
return function_block_range (function_block_iterator (this));
|
||||
}
|
||||
|
||||
/* Same as block::super_blocks, except that if B is nullptr, return an empty
|
||||
range. */
|
||||
|
||||
static superblock_range super_blocks (const block *b)
|
||||
{
|
||||
if (b == nullptr)
|
||||
|
|
@ -376,6 +370,9 @@ struct block : public allocate_on_obstack<block>
|
|||
return b->super_blocks ();
|
||||
}
|
||||
|
||||
/* Same as block::function_blocks, except that if B is nullptr, return an
|
||||
empty range. */
|
||||
|
||||
static function_block_range function_blocks (const block *b)
|
||||
{
|
||||
if (b == nullptr)
|
||||
|
|
|
|||
|
|
@ -21,35 +21,21 @@
|
|||
|
||||
#include "gdbsupport/iterator-range.h"
|
||||
|
||||
/* An iterator base class for iterating over a field of a type. In order to
|
||||
form a functioning iterator, classes inheriting this should define an
|
||||
operator++, which determines the actual field that is iterated over.
|
||||
/* An iterator base class that defines pretty much everything except how to
|
||||
obtain the next element, given the current element.
|
||||
|
||||
Instead of factoring out a base class, we could use something like this:
|
||||
Increment is a functor that takes a T& and returns the next T* in the
|
||||
sequence. It shall return nullptr when there are no more elements. */
|
||||
|
||||
template<typename T, auto F = &T::next>
|
||||
struct next_iterator
|
||||
{
|
||||
...
|
||||
self_type &operator++ ()
|
||||
{
|
||||
m_item = m_item->*F;
|
||||
return *this;
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
but that has the drawback that it doesn't work with incomplete T. */
|
||||
|
||||
template<typename T>
|
||||
template<typename T, typename Incrementer>
|
||||
struct base_next_iterator
|
||||
{
|
||||
typedef base_next_iterator self_type;
|
||||
typedef T *value_type;
|
||||
typedef T *&reference;
|
||||
typedef T **pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef int difference_type;
|
||||
using self_type = base_next_iterator<T, Incrementer>;
|
||||
using value_type = T *;
|
||||
using reference = T *&;
|
||||
using pointer = T **;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = int;
|
||||
|
||||
explicit base_next_iterator (T *item)
|
||||
: m_item (item)
|
||||
|
|
@ -77,37 +63,30 @@ struct base_next_iterator
|
|||
return m_item != other.m_item;
|
||||
}
|
||||
|
||||
protected:
|
||||
self_type &operator++ ()
|
||||
{
|
||||
gdb_assert (m_item != nullptr);
|
||||
this->m_item = Incrementer () (*m_item);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
T *m_item;
|
||||
};
|
||||
|
||||
/* An iterator that uses the 'next' field of a type to iterate. This
|
||||
can be used with various GDB types that are stored as linked
|
||||
lists. */
|
||||
/* Iterator that follows the `next` field of a type. */
|
||||
|
||||
template<typename T>
|
||||
struct next_iterator : base_next_iterator<T> {
|
||||
typedef next_iterator self_type;
|
||||
typedef T *value_type;
|
||||
typedef T *&reference;
|
||||
typedef T **pointer;
|
||||
|
||||
explicit next_iterator (T *item)
|
||||
: base_next_iterator<T> (item)
|
||||
template <typename T>
|
||||
struct next_field_incrementer
|
||||
{
|
||||
T *operator() (T &item) const noexcept
|
||||
{
|
||||
}
|
||||
|
||||
next_iterator () = default;
|
||||
|
||||
self_type &operator++ ()
|
||||
{
|
||||
this->m_item = this->m_item->next;
|
||||
return *this;
|
||||
return item.next;
|
||||
}
|
||||
};
|
||||
|
||||
/* A convenience wrapper to make a range type around a next_iterator. */
|
||||
template <typename T>
|
||||
using next_iterator = base_next_iterator<T, next_field_incrementer<T>>;
|
||||
|
||||
template <typename T>
|
||||
using next_range = iterator_range<next_iterator<T>>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue