From: Tom de Vries Date: Thu, 23 Apr 2026 06:35:29 +0000 (+0200) Subject: Add block::function_blocks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26d33b9b2dbc0d291f405a5d4a61d14c4cae337e;p=thirdparty%2Fbinutils-gdb.git Add block::function_blocks Add a function block::function_blocks that can be used to transform: ... while (block != NULL) { ... if (block->function () != nullptr) break; block = block->superblock (); } ... into: ... for (auto b : block::function_blocks (block)) { ... } ... I'm not sure about the name. It might suggest that it iterates over all function blocks, but that's not the case, it only does so for the inner function. I considered function block::inner_function_blocks instead, but it seems a bit awkward. --- diff --git a/gdb/block.h b/gdb/block.h index f4ce2c21c92..11000b924ef 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -127,7 +127,34 @@ struct block : public allocate_on_obstack } }; + /* 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 @@ -334,6 +361,13 @@ struct block : public allocate_on_obstack return superblock_range (std::move (begin)); } + function_block_range function_blocks () const + { + function_block_range::iterator begin (this); + + return function_block_range (std::move (begin)); + } + static superblock_range super_blocks (const block *b) { if (b == nullptr) @@ -342,6 +376,14 @@ struct block : public allocate_on_obstack return b->super_blocks (); } + static function_block_range function_blocks (const block *b) + { + if (b == nullptr) + return function_block_range (); + + return b->function_blocks (); + } + /* Return true if block A is lexically nested within this block, or if A and this block have the same pc range. Return false otherwise. If ALLOW_NESTED is true, then block A is considered