]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Add block::function_blocks
authorTom de Vries <tdevries@suse.de>
Thu, 23 Apr 2026 06:35:29 +0000 (08:35 +0200)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 30 Apr 2026 15:00:32 +0000 (11:00 -0400)
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.

gdb/block.h

index f4ce2c21c9275ef9747b38f5e70abcdb7dc79e6e..11000b924efda1f7887488e77cd4394d425fd490 100644 (file)
@@ -127,7 +127,34 @@ struct block : public allocate_on_obstack<block>
     }
   };
 
+  /* 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
@@ -334,6 +361,13 @@ struct block : public allocate_on_obstack<block>
     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<block>
     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