/* Code dealing with blocks for GDB.

   Copyright (C) 2003-2025 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDB_BLOCK_H
#define GDB_BLOCK_H

#include "dictionary.h"
#include "gdbsupport/array-view.h"
#include "gdbsupport/next-iterator.h"

/* Opaque declarations.  */

struct symbol;
struct compunit_symtab;
struct block_namespace_info;
struct using_direct;
struct obstack;
struct addrmap_fixed;

/* Blocks can occupy non-contiguous address ranges.  When this occurs,
   startaddr and endaddr within struct block (still) specify the lowest
   and highest addresses of all ranges, but each individual range is
   specified by the addresses in struct blockrange.  */

struct blockrange
{
  blockrange (CORE_ADDR start, CORE_ADDR end)
    : m_start (start),
      m_end (end)
  {
  }

  /* Return this blockrange's start address.  */
  CORE_ADDR start () const
  { return m_start; }

  /* Set this blockrange's start address.  */
  void set_start (CORE_ADDR start)
  { m_start = start; }

  /* Return this blockrange's end address.  */
  CORE_ADDR end () const
  { return m_end; }

  /* Set this blockrange's end address.  */
  void set_end (CORE_ADDR end)
  { m_end = end; }

  /* Lowest address in this range.  */

  CORE_ADDR m_start;

  /* One past the highest address in the range.  */

  CORE_ADDR m_end;
};

/* Two or more non-contiguous ranges in the same order as that provided
   via the debug info.  */

struct blockranges
{
  int nranges;
  struct blockrange range[1];
};

/* All of the name-scope contours of the program
   are represented by `struct block' objects.
   All of these objects are pointed to by the blockvector.

   Each block represents one name scope.
   Each lexical context has its own block.

   The blockvector begins with some special blocks.
   The GLOBAL_BLOCK contains all the symbols defined in this compilation
   whose scope is the entire program linked together.
   The STATIC_BLOCK contains all the symbols whose scope is the
   entire compilation excluding other separate compilations.
   Blocks starting with the FIRST_LOCAL_BLOCK are not special.

   Each block records a range of core addresses for the code that
   is in the scope of the block.  The STATIC_BLOCK and GLOBAL_BLOCK
   give, for the range of code, the entire range of code produced
   by the compilation that the symbol segment belongs to.

   The blocks appear in the blockvector
   in order of increasing starting-address,
   and, within that, in order of decreasing ending-address.

   This implies that within the body of one function
   the blocks appear in the order of a depth-first tree walk.  */

struct block : public allocate_on_obstack<block>
{
  /* Return this block's start address.  */
  CORE_ADDR start () const
  { return m_start; }

  /* Set this block's start address.  */
  void set_start (CORE_ADDR start)
  { m_start = start; }

  /* Return this block's end address.  */
  CORE_ADDR end () const
  { return m_end; }

  /* Set this block's end address.  */
  void set_end (CORE_ADDR end)
  { m_end = end; }

  /* Return this block's function symbol.  */
  symbol *function () const
  { return m_function; }

  /* Set this block's function symbol.  */
  void set_function (symbol *function)
  { m_function = function; }

  /* Return this block's superblock.  */
  const block *superblock () const
  { return m_superblock; }

  /* Set this block's superblock.  */
  void set_superblock (const block *superblock)
  { m_superblock = superblock; }

  /* Return this block's multidict.  */
  multidictionary *multidict () const
  { return m_multidict; }

  /* Return an iterator range for this block's multidict.  */
  iterator_range<mdict_iterator_wrapper> multidict_symbols () const
  {
    mdict_iterator_wrapper begin (m_multidict);

    return iterator_range<mdict_iterator_wrapper> (std::move (begin));
  }

  /* Set this block's multidict.  */
  void set_multidict (multidictionary *multidict)
  { m_multidict = multidict; }

  /* Return a view on this block's ranges.  */
  gdb::array_view<blockrange> ranges ()
  {
    if (m_ranges == nullptr)
      return {};
    else
      return gdb::make_array_view (m_ranges->range, m_ranges->nranges);
  }

  /* Const version of the above.  */
  gdb::array_view<const blockrange> ranges () const
  {
    if (m_ranges == nullptr)
      return {};
    else
      return gdb::make_array_view (m_ranges->range, m_ranges->nranges);
  }

  /* Set this block's ranges array.  */
  void set_ranges (blockranges *ranges)
  { m_ranges = ranges; }

  /* Return true if all addresses within this block are contiguous.  */
  bool is_contiguous () const
  { return this->ranges ().size () <= 1; }

  /* Return the entry-pc of this block.

     If the entry PC has been set to a specific value then this is
     returned.  Otherwise, the default_entry_pc() address is returned.  */

  CORE_ADDR entry_pc () const
  {
    return default_entry_pc () + m_entry_pc_offset;
  }

  /* Set this block's entry-pc to ADDR, which must lie between start() and
     end().  The entry-pc is stored as the signed offset from the
     default_entry_pc() address.

     Note that block sub-ranges can be out of order, as such the offset of
     the entry-pc might be negative.  */

  void set_entry_pc (CORE_ADDR addr)
  {
    CORE_ADDR start = default_entry_pc ();

    gdb_assert (addr >= this->start () && addr < this->end ());
    gdb_assert (start >= this->start () && start < this->end ());

    m_entry_pc_offset = addr - start;
  }

  /* Return the objfile of this block.  */

  struct objfile *objfile () const;

  /* Return the architecture of this block.  */

  struct gdbarch *gdbarch () const;

  /* Return true if BL represents an inlined function.  */

  bool inlined_p () const;

  /* This returns the namespace that this block is enclosed in, or ""
     if it isn't enclosed in a namespace at all.  This travels the
     chain of superblocks looking for a scope, if necessary.  */

  const char *scope () const;

  /* Set this block's scope member to SCOPE; if needed, allocate
     memory via OBSTACK.  (It won't make a copy of SCOPE, however, so
     that already has to be allocated correctly.)  */

  void set_scope (const char *scope, struct obstack *obstack);

  /* This returns the using directives list associated with this
     block, if any.  */

  next_range<using_direct> get_using () const;

  /* Set this block's using member to USING; if needed, allocate
     memory via OBSTACK.  (It won't make a copy of USING, however, so
     that already has to be allocated correctly.)  */

  void set_using (struct using_direct *using_decl, struct obstack *obstack);

  /* Return the symbol for the function which contains a specified
     lexical block, described by a struct block.  The return value
     will not be an inlined function; the containing function will be
     returned instead.  */

  struct symbol *linkage_function () const;

  /* Return the symbol for the function which contains a specified
     block, described by a struct block.  The return value will be the
     closest enclosing function, which might be an inline
     function.  */

  struct symbol *containing_function () const;

  /* Return the static block associated with this block.  Return NULL
     if block is a global block.  */

  const struct block *static_block () const;

  /* Return true if this block is a static block.  */

  bool is_static_block () const
  {
    const block *sup = superblock ();
    if (sup == nullptr)
      return false;
    return sup->is_global_block ();
  }

  /* Return the global block associated with block.  */

  const struct global_block *global_block () const;

  /* Return true if this block is a global block.  */

  bool is_global_block () const
  { return superblock () == nullptr; }

  /* Return this block as a global_block.  This block must be a global
     block.  */
  struct global_block *as_global_block ();
  const struct global_block *as_global_block () const;

  /* Return the function block for this block.  Returns nullptr if
     there is no enclosing function, i.e., if this block is a static
     or global block.  */

  const struct block *function_block () const;

  /* Return a property to evaluate the static link associated to this
     block.

     In the context of nested functions (available in Pascal, Ada and
     GNU C, for instance), a static link (as in DWARF's
     DW_AT_static_link attribute) for a function is a way to get the
     frame corresponding to the enclosing function.

     Note that only objfile-owned and function-level blocks can have a
     static link.  Return NULL if there is no such property.  */

  struct dynamic_prop *static_link () const;

  /* 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
     to be in this block if A is in a nested function in this block's
     function.  If ALLOW_NESTED is false (the default), then blocks in
     nested functions are not considered to be contained.  */

  bool contains (const struct block *a, bool allow_nested = false) const;

private:

  /* Return the default entry-pc of this block.  The default is the address
     we use if the debug information hasn't specifically set a different
     entry-pc value.  This is the lowest address for the block when all
     addresses within the block are contiguous.  If non-contiguous, then
     use the start address for the first range in the block.

     This almost matches what DWARF specifies as the entry pc, except that
     the final case, using the first address of the first range, is a GDB
     extension.  However, the DWARF reader sets the specific entry-pc
     wherever possible, so this non-standard fallback case is only used as
     a last resort.  */

  CORE_ADDR default_entry_pc () const
  {
    if (this->is_contiguous ())
      return this->start ();
    else
      return this->ranges ()[0].start ();
  }

  /* If the namespace_info is NULL, allocate it via OBSTACK and
     initialize its members to zero.  */
  void initialize_namespace (struct obstack *obstack);

  /* Addresses in the executable code that are in this block.  */

  CORE_ADDR m_start = 0;
  CORE_ADDR m_end = 0;

  /* The symbol that names this block, if the block is the body of a
     function (real or inlined); otherwise, zero.  */

  struct symbol *m_function = nullptr;

  /* The `struct block' for the containing block, or 0 if none.

     The superblock of a top-level local block (i.e. a function in the
     case of C) is the STATIC_BLOCK.  The superblock of the
     STATIC_BLOCK is the GLOBAL_BLOCK.  */

  const struct block *m_superblock = nullptr;

  /* This is used to store the symbols in the block.  */

  struct multidictionary *m_multidict = nullptr;

  /* Contains information about namespace-related info relevant to this block:
     using directives and the current namespace scope.  */

  struct block_namespace_info *m_namespace_info = nullptr;

  /* Address ranges for blocks with non-contiguous ranges.  If this
     is NULL, then there is only one range which is specified by
     startaddr and endaddr above.  */

  struct blockranges *m_ranges = nullptr;

  /* The offset of the actual entry-pc value from the default entry-pc
     value.  If space was no object then we'd store an actual address along
     with a flag to indicate if the address has been set or not.  But we'd
     like to keep the size of block low, so we'd like to use a single
     member variable.

     We would also like to avoid using 0 as a special address; some targets
     do allow for accesses to address 0.

     So instead we store the offset of the defined entry-pc from the
     default entry-pc.  See default_entry_pc() for the definition of the
     default entry-pc.  See entry_pc() for how this offset is used.  */

  LONGEST m_entry_pc_offset = 0;
};

/* The global block is singled out so that we can provide a back-link
   to the compunit.  */

struct global_block : public block
{
  /* Set the compunit of this global block.

     The compunit must not have been set previously.  */
  void set_compunit (compunit_symtab *cu)
  {
    gdb_assert (m_compunit == nullptr);
    m_compunit = cu;
  }

  /* Return the compunit of this global block.

     The compunit must have been set previously.  */
  compunit_symtab *compunit () const
  {
    gdb_assert (m_compunit != nullptr);
    return m_compunit;
  }

private:
  /* This holds a pointer to the compunit holding this block.  */
  compunit_symtab *m_compunit = nullptr;
};

struct blockvector
{
  /* Return a view on the blocks of this blockvector.  */
  gdb::array_view<struct block *> blocks ()
  {
    return gdb::array_view<struct block *> (m_blocks, m_num_blocks);
  }

  /* Const version of the above.  */
  gdb::array_view<const struct block *const> blocks () const
  {
    const struct block **blocks = (const struct block **) m_blocks;
    return gdb::array_view<const struct block *const> (blocks, m_num_blocks);
  }

  /* Return the block at index I.  */
  struct block *block (size_t i)
  { return this->blocks ()[i]; }

  /* Const version of the above.  */
  const struct block *block (size_t i) const
  { return this->blocks ()[i]; }

  /* Set the block at index I.  */
  void set_block (int i, struct block *block)
  { m_blocks[i] = block; }

  /* Set the number of blocks of this blockvector.

     The storage of blocks is done using a flexible array member, so the number
     of blocks set here must agree with what was effectively allocated.  */
  void set_num_blocks (int num_blocks)
  { m_num_blocks = num_blocks; }

  /* Return the number of blocks in this blockvector.  */
  int num_blocks () const
  { return m_num_blocks; }

  /* Return the global block of this blockvector.  */
  struct global_block *global_block ()
  { return static_cast<struct global_block *> (this->block (GLOBAL_BLOCK)); }

  /* Const version of the above.  */
  const struct global_block *global_block () const
  {
    return static_cast<const struct global_block *>
      (this->block (GLOBAL_BLOCK));
  }

  /* Return the static block of this blockvector.  */
  struct block *static_block ()
  { return this->block (STATIC_BLOCK); }

  /* Const version of the above.  */
  const struct block *static_block () const
  { return this->block (STATIC_BLOCK); }

  /* Return the address -> block map of this blockvector.  */
  addrmap_fixed *map ()
  { return m_map; }

  /* Const version of the above.  */
  const addrmap_fixed *map () const
  { return m_map; }

  /* Set this blockvector's address -> block map.  */
  void set_map (addrmap_fixed *map)
  { m_map = map; }

private:
  /* An address map mapping addresses to blocks in this blockvector.
     This pointer is zero if the blocks' start and end addresses are
     enough.  */
  addrmap_fixed *m_map;

  /* Number of blocks in the list.  */
  int m_num_blocks;

  /* The blocks themselves.  */
  struct block *m_blocks[1];
};

extern const struct blockvector *blockvector_for_pc (CORE_ADDR,
					       const struct block **);

extern const struct blockvector *
  blockvector_for_pc_sect (CORE_ADDR, struct obj_section *,
			   const struct block **, struct compunit_symtab *);

extern int blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc);

extern struct call_site *call_site_for_pc (struct gdbarch *gdbarch,
					   CORE_ADDR pc);

extern const struct block *block_for_pc (CORE_ADDR);

extern const struct block *block_for_pc_sect (CORE_ADDR, struct obj_section *);

/* A block iterator.  This structure should be treated as though it
   were opaque; it is only defined here because we want to support
   stack allocation of iterators.  */

struct block_iterator
{
  /* If we're iterating over a single block, this holds the block.
     Otherwise, it holds the canonical compunit.  */

  union
  {
    struct compunit_symtab *compunit_symtab;
    const struct block *block;
  } d;

  /* If we're trying to match a name, this will be non-NULL.  */
  const lookup_name_info *name;

  /* If we're iterating over a single block, this is always -1.
     Otherwise, it holds the index of the current "included" symtab in
     the canonical symtab (that is, d.symtab->includes[idx]), with -1
     meaning the canonical symtab itself.  */

  int idx;

  /* Which block, either static or global, to iterate over.  If this
     is FIRST_LOCAL_BLOCK, then we are iterating over a single block.
     This is used to select which field of 'd' is in use.  */

  enum block_enum which;

  /* The underlying multidictionary iterator.  */

  struct mdict_iterator mdict_iter;
};

/* Initialize ITERATOR to point at the first symbol in BLOCK, and
   return that first symbol, or NULL if BLOCK is empty.  If NAME is
   not NULL, only return symbols matching that name.  */

extern struct symbol *block_iterator_first
     (const struct block *block,
      struct block_iterator *iterator,
      const lookup_name_info *name = nullptr);

/* Advance ITERATOR, and return the next symbol, or NULL if there are
   no more symbols.  Don't call this if you've previously received
   NULL from block_iterator_first or block_iterator_next on this
   iteration.  */

extern struct symbol *block_iterator_next (struct block_iterator *iterator);

/* An iterator that wraps a block_iterator.  The naming here is
   unfortunate, but block_iterator was named before gdb switched to
   C++.  */
struct block_iterator_wrapper
{
  typedef block_iterator_wrapper self_type;
  typedef struct symbol *value_type;

  explicit block_iterator_wrapper (const struct block *block,
				   const lookup_name_info *name = nullptr)
    : m_sym (block_iterator_first (block, &m_iter, name))
  {
  }

  block_iterator_wrapper ()
    : m_sym (nullptr)
  {
  }

  value_type operator* () const
  {
    return m_sym;
  }

  bool operator== (const self_type &other) const
  {
    return m_sym == other.m_sym;
  }

  bool operator!= (const self_type &other) const
  {
    return m_sym != other.m_sym;
  }

  self_type &operator++ ()
  {
    m_sym = block_iterator_next (&m_iter);
    return *this;
  }

private:

  struct symbol *m_sym;
  struct block_iterator m_iter;
};

/* Return an iterator range for block_iterator_wrapper.  */

inline iterator_range<block_iterator_wrapper>
block_iterator_range (const block *block,
		      const lookup_name_info *name = nullptr)
{
  block_iterator_wrapper begin (block, name);

  return iterator_range<block_iterator_wrapper> (std::move (begin));
}

/* Return true if symbol A is the best match possible for DOMAIN.  */

extern bool best_symbol (struct symbol *a, const domain_search_flags domain);

/* Return symbol B if it is a better match than symbol A for DOMAIN.
   Otherwise return A.  */

extern struct symbol *better_symbol (struct symbol *a, struct symbol *b,
				     const domain_search_flags domain);

/* Search BLOCK for symbol NAME in DOMAIN.  */

extern struct symbol *block_lookup_symbol (const struct block *block,
					   const lookup_name_info &name,
					   const domain_search_flags domain);

/* When searching for a symbol, the "best" symbol is preferred over
   one that is merely acceptable.  See 'best_symbol'.  This class
   keeps track of this distinction while searching.  */

struct best_symbol_tracker
{
  /* The symtab in which the currently best symbol appears.  */
  compunit_symtab *best_symtab = nullptr;

  /* The currently best (really "better") symbol.  */
  block_symbol currently_best {};

  /* Search BLOCK (which must have come from SYMTAB) for a symbol
     matching NAME and DOMAIN.  When a symbol is found, update
     'currently_best'.  If a best symbol is found, return true.
     Otherwise, return false.  SYMTAB can be nullptr if the caller
     does not care about this tracking.  */
  bool search (compunit_symtab *symtab,
	       const block *block, const lookup_name_info &name,
	       domain_search_flags domain);
};

/* Find symbol NAME in BLOCK and in DOMAIN.  This will return a
   matching symbol whose type is not a "opaque", see TYPE_IS_OPAQUE.
   If STUB is non-NULL, an otherwise matching symbol whose type is a
   opaque will be stored here.  */

extern struct symbol *block_find_symbol (const struct block *block,
					 const lookup_name_info &name,
					 const domain_search_flags domain,
					 struct symbol **stub);

/* Given a vector of pairs, allocate and build an obstack allocated
   blockranges struct for a block.  */
struct blockranges *make_blockranges (struct objfile *objfile,
				      const std::vector<blockrange> &rangevec);

#endif /* GDB_BLOCK_H */
