From e8d35bb5018fc337902258d9ddd0ad7ac1b65e44 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 30 Apr 2026 11:58:47 -0400 Subject: [PATCH] Simon's changes Change-Id: Ieee3c051b9b4bc949262ecbc44e1db2ad3bebe38 --- gdb/block.h | 97 ++++++++++++++++++-------------------- gdbsupport/next-iterator.h | 77 +++++++++++------------------- 2 files changed, 75 insertions(+), 99 deletions(-) diff --git a/gdb/block.h b/gdb/block.h index 11000b924ef..ae7f710b570 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -108,54 +108,6 @@ struct blockranges struct block : public allocate_on_obstack { - /* Variant of next_iterator using the superblock field instead of next. */ - struct superblock_iterator : base_next_iterator - { - 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 - { - 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; - using function_block_range = iterator_range; - /* Return this block's start address. */ CORE_ADDR start () const { return m_start; } @@ -354,6 +306,20 @@ struct block : public allocate_on_obstack 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; + using superblock_range = iterator_range; + + /* 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 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; + using function_block_range = iterator_range; + + /* 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 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) diff --git a/gdbsupport/next-iterator.h b/gdbsupport/next-iterator.h index 1dee941a252..d5b96ae680a 100644 --- a/gdbsupport/next-iterator.h +++ b/gdbsupport/next-iterator.h @@ -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. - - Instead of factoring out a base class, we could use something like this: - - template - 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 +/* An iterator base class that defines pretty much everything except how to + obtain the next element, given the current element. + + 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 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; + 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. */ - -template -struct next_iterator : base_next_iterator { - typedef next_iterator self_type; - typedef T *value_type; - typedef T *&reference; - typedef T **pointer; - - explicit next_iterator (T *item) - : base_next_iterator (item) - { - } +/* Iterator that follows the `next` field of a type. */ - next_iterator () = default; - - self_type &operator++ () +template +struct next_field_incrementer +{ + T *operator() (T &item) const noexcept { - 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 +using next_iterator = base_next_iterator>; template using next_range = iterator_range>; -- 2.47.3