/* Symbol table lookup for the GNU debugger, GDB.

   Copyright (C) 1986-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/>.  */

#include "dwarf2/call-site.h"
#include "exceptions.h"
#include "symtab.h"
#include "event-top.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "frame.h"
#include "target.h"
#include "value.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbsupport/gdb_regex.h"
#include "expression.h"
#include "language.h"
#include "demangle.h"
#include "inferior.h"
#include "source.h"
#include "filenames.h"
#include "objc-lang.h"
#include "d-lang.h"
#include "ada-lang.h"
#include "go-lang.h"
#include "p-lang.h"
#include "addrmap.h"
#include "cli/cli-utils.h"
#include "cli/cli-style.h"
#include "cli/cli-cmds.h"
#include "fnmatch.h"
#include "hashtab.h"
#include "typeprint.h"
#include "exceptions.h"

#include "gdbsupport/gdb_obstack.h"
#include "block.h"
#include "dictionary.h"

#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <ctype.h>
#include "cp-abi.h"
#include "cp-support.h"
#include "observable.h"
#include "solist.h"
#include "macrotab.h"
#include "macroscope.h"

#include "parser-defs.h"
#include "completer.h"
#include "progspace-and-thread.h"
#include <optional>
#include "filename-seen-cache.h"
#include "arch-utils.h"
#include <algorithm>
#include <string_view>
#include "gdbsupport/pathstuff.h"
#include "gdbsupport/common-utils.h"
#include <optional>
#include "gdbsupport/unordered_set.h"

/* Forward declarations for local functions.  */

static void rbreak_command (const char *, int);

static int find_line_common (const linetable *, int, int *, int);

static struct block_symbol
  lookup_symbol_aux (const char *name,
		     symbol_name_match_type match_type,
		     const struct block *block,
		     const domain_search_flags domain,
		     enum language language,
		     struct field_of_this_result *);

static
struct block_symbol lookup_local_symbol (const char *name,
					 symbol_name_match_type match_type,
					 const struct block *block,
					 const domain_search_flags domain,
					 const struct language_defn *langdef);

static struct block_symbol
  lookup_symbol_in_objfile (struct objfile *objfile,
			    enum block_enum block_index,
			    const char *name,
			    const domain_search_flags domain);

static void set_main_name (program_space *pspace, const char *name,
			   language lang);

/* Type of the data stored on the program space.  */

struct main_info
{
  /* Name of "main".  */

  std::string name_of_main;

  /* Language of "main".  */

  enum language language_of_main = language_unknown;
};

/* Program space key for finding name and language of "main".  */

static const registry<program_space>::key<main_info> main_progspace_key;

/* Symbol lookup is not reentrant (though this is not an intrinsic
   restriction).  Keep track of whether a symbol lookup is active, to be able
   to detect reentrancy.  */
static bool in_symbol_lookup;

/* Struct to mark that a symbol lookup is active for the duration of its
   lifetime.  */

struct enter_symbol_lookup
{
  enter_symbol_lookup ()
  {
    /* Ensure that the current language has been set.  Normally the
       language is set lazily.  However, when performing a symbol lookup,
       this could result in a recursive call into the lookup code in some
       cases.  Set it now to ensure that this does not happen.  */
    get_current_language ();

    /* Detect symbol lookup reentrance.  */
    gdb_assert (!in_symbol_lookup);

    in_symbol_lookup = true;
  }

  ~enter_symbol_lookup ()
  {
    /* Sanity check.  */
    gdb_assert (in_symbol_lookup);

    in_symbol_lookup = false;
  }

  DISABLE_COPY_AND_ASSIGN (enter_symbol_lookup);
};

/* The default symbol cache size.
   There is no extra cpu cost for large N (except when flushing the cache,
   which is rare).  The value here is just a first attempt.  A better default
   value may be higher or lower.  A prime number can make up for a bad hash
   computation, so that's why the number is what it is.  */
#define DEFAULT_SYMBOL_CACHE_SIZE 1021

/* The maximum symbol cache size.
   There's no method to the decision of what value to use here, other than
   there's no point in allowing a user typo to make gdb consume all memory.  */
#define MAX_SYMBOL_CACHE_SIZE (1024*1024)

/* symbol_cache_lookup returns this if a previous lookup failed to find the
   symbol in any objfile.  */
#define SYMBOL_LOOKUP_FAILED \
 ((struct block_symbol) {(struct symbol *) 1, NULL})
#define SYMBOL_LOOKUP_FAILED_P(SIB) (SIB.symbol == (struct symbol *) 1)

/* Recording lookups that don't find the symbol is just as important, if not
   more so, than recording found symbols.  */

enum symbol_cache_slot_state
{
  SYMBOL_SLOT_UNUSED,
  SYMBOL_SLOT_NOT_FOUND,
  SYMBOL_SLOT_FOUND
};

struct symbol_cache_slot
{
  enum symbol_cache_slot_state state;

  /* The objfile that was current when the symbol was looked up.
     This is only needed for global blocks, but for simplicity's sake
     we allocate the space for both.  If data shows the extra space used
     for static blocks is a problem, we can split things up then.

     Global blocks need cache lookup to include the objfile context because
     we need to account for gdbarch_iterate_over_objfiles_in_search_order
     which can traverse objfiles in, effectively, any order, depending on
     the current objfile, thus affecting which symbol is found.  Normally,
     only the current objfile is searched first, and then the rest are
     searched in recorded order; but putting cache lookup inside
     gdbarch_iterate_over_objfiles_in_search_order would be awkward.
     Instead we just make the current objfile part of the context of
     cache lookup.  This means we can record the same symbol multiple times,
     each with a different "current objfile" that was in effect when the
     lookup was saved in the cache, but cache space is pretty cheap.  */
  const struct objfile *objfile_context;

  /* The domain that was searched for initially.  This must exactly
     match.  */
  domain_search_flags domain;

  union
  {
    struct block_symbol found;
    char *name;
  } value;
};

/* Clear out SLOT.  */

static void
symbol_cache_clear_slot (struct symbol_cache_slot *slot)
{
  if (slot->state == SYMBOL_SLOT_NOT_FOUND)
    xfree (slot->value.name);
  slot->state = SYMBOL_SLOT_UNUSED;
}

/* Symbols don't specify global vs static block.
   So keep them in separate caches.  */

struct block_symbol_cache
{
  unsigned int hits;
  unsigned int misses;
  unsigned int collisions;

  /* SYMBOLS is a variable length array of this size.
     One can imagine that in general one cache (global/static) should be a
     fraction of the size of the other, but there's no data at the moment
     on which to decide.  */
  unsigned int size;

  struct symbol_cache_slot symbols[1];
};

/* Clear all slots of BSC and free BSC.  */

static void
destroy_block_symbol_cache (struct block_symbol_cache *bsc)
{
  if (bsc != nullptr)
    {
      for (unsigned int i = 0; i < bsc->size; i++)
	symbol_cache_clear_slot (&bsc->symbols[i]);
      xfree (bsc);
    }
}

/* The symbol cache.

   Searching for symbols in the static and global blocks over multiple objfiles
   again and again can be slow, as can searching very big objfiles.  This is a
   simple cache to improve symbol lookup performance, which is critical to
   overall gdb performance.

   Symbols are hashed on the name, its domain, and block.
   They are also hashed on their objfile for objfile-specific lookups.  */

struct symbol_cache
{
  symbol_cache () = default;

  ~symbol_cache ()
  {
    destroy_block_symbol_cache (global_symbols);
    destroy_block_symbol_cache (static_symbols);
  }

  struct block_symbol_cache *global_symbols = nullptr;
  struct block_symbol_cache *static_symbols = nullptr;
};

/* Program space key for finding its symbol cache.  */

static const registry<program_space>::key<symbol_cache> symbol_cache_key;

/* When non-zero, print debugging messages related to symtab creation.  */
unsigned int symtab_create_debug = 0;

/* When non-zero, print debugging messages related to symbol lookup.  */
unsigned int symbol_lookup_debug = 0;

/* The size of the cache is staged here.  */
static unsigned int new_symbol_cache_size = DEFAULT_SYMBOL_CACHE_SIZE;

/* The current value of the symbol cache size.
   This is saved so that if the user enters a value too big we can restore
   the original value from here.  */
static unsigned int symbol_cache_size = DEFAULT_SYMBOL_CACHE_SIZE;

/* True if a file may be known by two different basenames.
   This is the uncommon case, and significantly slows down gdb.
   Default set to "off" to not slow down the common case.  */
bool basenames_may_differ = false;

/* Allow the user to configure the debugger behavior with respect
   to multiple-choice menus when more than one symbol matches during
   a symbol lookup.  */

const char multiple_symbols_ask[] = "ask";
const char multiple_symbols_all[] = "all";
const char multiple_symbols_cancel[] = "cancel";
static const char *const multiple_symbols_modes[] =
{
  multiple_symbols_ask,
  multiple_symbols_all,
  multiple_symbols_cancel,
  NULL
};
static const char *multiple_symbols_mode = multiple_symbols_all;

/* When TRUE, ignore the prologue-end flag in linetable_entry when searching
   for the SAL past a function prologue.  */
static bool ignore_prologue_end_flag = false;

/* Read-only accessor to AUTO_SELECT_MODE.  */

const char *
multiple_symbols_select_mode (void)
{
  return multiple_symbols_mode;
}

/* Return the name of a domain_enum.  */

const char *
domain_name (domain_enum e)
{
  switch (e)
    {
#define SYM_DOMAIN(X)				\
      case X ## _DOMAIN: return #X "_DOMAIN";
#include "sym-domains.def"
#undef SYM_DOMAIN
    default: gdb_assert_not_reached ("bad domain_enum");
    }
}

/* See symtab.h.  */

std::string
domain_name (domain_search_flags flags)
{
  static constexpr domain_search_flags::string_mapping mapping[] = {
#define SYM_DOMAIN(X) \
    MAP_ENUM_FLAG (SEARCH_ ## X ## _DOMAIN),
#include "sym-domains.def"
#undef SYM_DOMAIN
  };

  return flags.to_string (mapping);
}

/* See symtab.h.  */

domain_search_flags
from_scripting_domain (int val)
{
  if ((val & SCRIPTING_SEARCH_FLAG) == 0)
    {
      /* VAL should be one of the domain constants.  Verify this and
	 convert it to a search constant.  */
      switch (val)
	{
#define SYM_DOMAIN(X)					\
	  case X ## _DOMAIN: break;
#include "sym-domains.def"
#undef SYM_DOMAIN
	default:
	  error (_("unrecognized domain constant"));
	}
      domain_search_flags result = to_search_flags ((domain_enum) val);
      if (val == VAR_DOMAIN)
	{
	  /* This matches the historical practice.  */
	  result |= SEARCH_TYPE_DOMAIN | SEARCH_FUNCTION_DOMAIN;
	}
      return result;
    }
  else
    {
      /* VAL is several search constants or'd together.  Verify
	 this.  */
      val &= ~SCRIPTING_SEARCH_FLAG;
      int check = val;
#define SYM_DOMAIN(X)				\
      check &= ~ (int) SEARCH_ ## X ## _DOMAIN;
#include "sym-domains.def"
#undef SYM_DOMAIN
      if (check != 0)
	error (_("unrecognized domain constant"));
      return (domain_search_flag) val;
    }
}

/* See symtab.h.  */

struct symbol *
search_symbol_list (const char *name, int num, struct symbol **syms)
{
  for (int i = 0; i < num; ++i)
    {
      if (strcmp (name, syms[i]->natural_name ()) == 0)
	return syms[i];
    }
  return nullptr;
}

/* See symtab.h.  */

CORE_ADDR
linetable_entry::pc (const struct objfile *objfile) const
{
  return CORE_ADDR (m_pc) + objfile->text_section_offset ();
}

/* See symtab.h.  */

call_site *
compunit_symtab::find_call_site (CORE_ADDR pc) const
{
  if (m_call_site_htab == nullptr)
    return nullptr;

  CORE_ADDR delta = this->objfile ()->text_section_offset ();

  if (auto it = m_call_site_htab->find (static_cast<unrelocated_addr> (pc - delta));
      it != m_call_site_htab->end ())
    return *it;

  /* See if the arch knows another PC we should try.  On some
     platforms, GCC emits a DWARF call site that is offset from the
     actual return location.  */
  struct gdbarch *arch = objfile ()->arch ();
  CORE_ADDR new_pc = gdbarch_update_call_site_pc (arch, pc);

  if (pc == new_pc)
    return nullptr;

  if (auto it = m_call_site_htab->find (static_cast<unrelocated_addr> (new_pc - delta));
      it != m_call_site_htab->end ())
    return *it;

  return nullptr;
}

/* See symtab.h.  */

void
compunit_symtab::set_call_site_htab (call_site_htab_t &&call_site_htab)
{
  gdb_assert (m_call_site_htab == nullptr);
  m_call_site_htab = new call_site_htab_t (std::move (call_site_htab));
}

/* See symtab.h.  */

void
compunit_symtab::set_primary_filetab (symtab *primary_filetab)
{
  symtab *prev_filetab = nullptr;

  /* Move PRIMARY_FILETAB to the head of the filetab list.  */
  for (symtab *filetab : this->filetabs ())
    {
      if (filetab == primary_filetab)
	{
	  if (prev_filetab != nullptr)
	    {
	      prev_filetab->next = primary_filetab->next;
	      primary_filetab->next = m_filetabs;
	      m_filetabs = primary_filetab;
	    }

	  break;
	}

      prev_filetab = filetab;
    }

  gdb_assert (primary_filetab == m_filetabs);
}

/* See symtab.h.  */

struct symtab *
compunit_symtab::primary_filetab () const
{
  gdb_assert (m_filetabs != nullptr);

  /* The primary file symtab is the first one in the list.  */
  return m_filetabs;
}

/* See symtab.h.  */

enum language
compunit_symtab::language () const
{
  struct symtab *symtab = primary_filetab ();

  /* The language of the compunit symtab is the language of its
     primary source file.  */
  return symtab->language ();
}

/* See symtab.h.  */

void
compunit_symtab::forget_cached_source_info ()
{
  for (symtab *s : filetabs ())
    s->release_fullname ();
}

/* See symtab.h.  */

void
compunit_symtab::finalize ()
{
  this->forget_cached_source_info ();
  delete m_call_site_htab;
}

/* The relocated address of the minimal symbol, using the section
   offsets from OBJFILE.  */

CORE_ADDR
minimal_symbol::value_address (objfile *objfile) const
{
  if (this->maybe_copied (objfile))
    return this->get_maybe_copied_address (objfile);
  else
    return (CORE_ADDR (this->unrelocated_address ())
	    + objfile->section_offsets[this->section_index ()]);
}

/* See symtab.h.  */

bool
minimal_symbol::data_p () const
{
  return m_type == mst_data
    || m_type == mst_bss
    || m_type == mst_abs
    || m_type == mst_file_data
    || m_type == mst_file_bss;
}

/* See symtab.h.  */

bool
minimal_symbol::text_p () const
{
  return m_type == mst_text
    || m_type == mst_text_gnu_ifunc
    || m_type == mst_data_gnu_ifunc
    || m_type == mst_slot_got_plt
    || m_type == mst_solib_trampoline
    || m_type == mst_file_text;
}

/* See symtab.h.  */

bool
minimal_symbol::maybe_copied (objfile *objfile) const
{
  return (objfile->object_format_has_copy_relocs
	  && (objfile->flags & OBJF_MAINLINE) == 0
	  && (m_type == mst_data || m_type == mst_bss));
}

/* See whether FILENAME matches SEARCH_NAME using the rule that we
   advertise to the user.  (The manual's description of linespecs
   describes what we advertise).  Returns true if they match, false
   otherwise.  */

bool
compare_filenames_for_search (const char *filename, const char *search_name)
{
  int len = strlen (filename);
  size_t search_len = strlen (search_name);

  if (len < search_len)
    return false;

  /* The tail of FILENAME must match.  */
  if (FILENAME_CMP (filename + len - search_len, search_name) != 0)
    return false;

  /* Either the names must completely match, or the character
     preceding the trailing SEARCH_NAME segment of FILENAME must be a
     directory separator.

     The check !IS_ABSOLUTE_PATH ensures SEARCH_NAME "/dir/file.c"
     cannot match FILENAME "/path//dir/file.c" - as user has requested
     absolute path.  The sama applies for "c:\file.c" possibly
     incorrectly hypothetically matching "d:\dir\c:\file.c".

     The HAS_DRIVE_SPEC purpose is to make FILENAME "c:file.c"
     compatible with SEARCH_NAME "file.c".  In such case a compiler had
     to put the "c:file.c" name into debug info.  Such compatibility
     works only on GDB built for DOS host.  */
  return (len == search_len
	  || (!IS_ABSOLUTE_PATH (search_name)
	      && IS_DIR_SEPARATOR (filename[len - search_len - 1]))
	  || (HAS_DRIVE_SPEC (filename)
	      && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len]));
}

/* Check for a symtab of a specific name by searching some symtabs.
   This is a helper function for callbacks of iterate_over_symtabs.

   If NAME is not absolute, then REAL_PATH is NULL
   If NAME is absolute, then REAL_PATH is the gdb_realpath form of NAME.

   The return value, NAME, REAL_PATH and CALLBACK are identical to the
   `map_symtabs_matching_filename' method of quick_symbol_functions.

   FIRST and AFTER_LAST indicate the range of compunit symtabs to search.
   Each symtab within the specified compunit symtab is also searched.
   AFTER_LAST is one past the last compunit symtab to search; NULL means to
   search until the end of the list.  */

bool
iterate_over_some_symtabs (const char *name,
			   const char *real_path,
			   struct compunit_symtab *first,
			   struct compunit_symtab *after_last,
			   gdb::function_view<bool (symtab *)> callback)
{
  struct compunit_symtab *cust;
  const char* base_name = lbasename (name);

  for (cust = first; cust != NULL && cust != after_last; cust = cust->next)
    {
      /* Skip included compunits.  */
      if (cust->user != nullptr)
	continue;

      for (symtab *s : cust->filetabs ())
	{
	  if (compare_filenames_for_search (s->filename, name))
	    {
	      if (callback (s))
		return true;
	      continue;
	    }

	  /* Before we invoke realpath, which can get expensive when many
	     files are involved, do a quick comparison of the basenames.  */
	  if (! basenames_may_differ
	      && FILENAME_CMP (base_name, lbasename (s->filename)) != 0)
	    continue;

	  if (compare_filenames_for_search (symtab_to_fullname (s), name))
	    {
	      if (callback (s))
		return true;
	      continue;
	    }

	  /* If the user gave us an absolute path, try to find the file in
	     this symtab and use its absolute path.  */
	  if (real_path != NULL)
	    {
	      const char *fullname = symtab_to_fullname (s);

	      gdb_assert (IS_ABSOLUTE_PATH (real_path));
	      gdb_assert (IS_ABSOLUTE_PATH (name));
	      gdb::unique_xmalloc_ptr<char> fullname_real_path
		= gdb_realpath (fullname);
	      fullname = fullname_real_path.get ();
	      if (FILENAME_CMP (real_path, fullname) == 0)
		{
		  if (callback (s))
		    return true;
		  continue;
		}
	    }
	}
    }

  return false;
}

/* See symtab.h.  */

void
iterate_over_symtabs (program_space *pspace, const char *name,
		      gdb::function_view<bool (symtab *)> callback)
{
  gdb::unique_xmalloc_ptr<char> real_path;

  /* Here we are interested in canonicalizing an absolute path, not
     absolutizing a relative path.  */
  if (IS_ABSOLUTE_PATH (name))
    {
      real_path = gdb_realpath (name);
      gdb_assert (IS_ABSOLUTE_PATH (real_path.get ()));
    }

  for (objfile *objfile : pspace->objfiles ())
    if (iterate_over_some_symtabs (name, real_path.get (),
				   objfile->compunit_symtabs, nullptr,
				   callback))
	return;

  /* Same search rules as above apply here, but now we look through the
     psymtabs.  */
  for (objfile *objfile : pspace->objfiles ())
    if (objfile->map_symtabs_matching_filename (name, real_path.get (),
						callback))
      return;
}

/* See symtab.h.  */

symtab *
lookup_symtab (program_space *pspace, const char *name)
{
  struct symtab *result = NULL;

  iterate_over_symtabs (pspace, name, [&] (symtab *symtab)
    {
      result = symtab;
      return true;
    });

  return result;
}


/* Mangle a GDB method stub type.  This actually reassembles the pieces of the
   full method name, which consist of the class name (from T), the unadorned
   method name from METHOD_ID, and the signature for the specific overload,
   specified by SIGNATURE_ID.  Note that this function is g++ specific.  */

char *
gdb_mangle_name (struct type *type, int method_id, int signature_id)
{
  int mangled_name_len;
  char *mangled_name;
  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, method_id);
  struct fn_field *method = &f[signature_id];
  const char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id);
  const char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id);
  const char *newname = type->name ();

  /* Does the form of physname indicate that it is the full mangled name
     of a constructor (not just the args)?  */
  int is_full_physname_constructor;

  int is_constructor;
  int is_destructor = is_destructor_name (physname);
  /* Need a new type prefix.  */
  const char *const_prefix = method->is_const ? "C" : "";
  const char *volatile_prefix = method->is_volatile ? "V" : "";
  char buf[20];
  int len = (newname == NULL ? 0 : strlen (newname));

  /* Nothing to do if physname already contains a fully mangled v3 abi name
     or an operator name.  */
  if ((physname[0] == '_' && physname[1] == 'Z')
      || is_operator_name (field_name))
    return xstrdup (physname);

  is_full_physname_constructor = is_constructor_name (physname);

  is_constructor = is_full_physname_constructor 
    || (newname && strcmp (field_name, newname) == 0);

  if (!is_destructor)
    is_destructor = (startswith (physname, "__dt"));

  if (is_destructor || is_full_physname_constructor)
    {
      mangled_name = (char *) xmalloc (strlen (physname) + 1);
      strcpy (mangled_name, physname);
      return mangled_name;
    }

  if (len == 0)
    {
      xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
    }
  else if (physname[0] == 't' || physname[0] == 'Q')
    {
      /* The physname for template and qualified methods already includes
	 the class name.  */
      xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
      newname = NULL;
      len = 0;
    }
  else
    {
      xsnprintf (buf, sizeof (buf), "__%s%s%d", const_prefix,
		 volatile_prefix, len);
    }
  mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
		      + strlen (buf) + len + strlen (physname) + 1);

  mangled_name = (char *) xmalloc (mangled_name_len);
  if (is_constructor)
    mangled_name[0] = '\0';
  else
    strcpy (mangled_name, field_name);

  strcat (mangled_name, buf);
  /* If the class doesn't have a name, i.e. newname NULL, then we just
     mangle it using 0 for the length of the class.  Thus it gets mangled
     as something starting with `::' rather than `classname::'.  */
  if (newname != NULL)
    strcat (mangled_name, newname);

  strcat (mangled_name, physname);
  return (mangled_name);
}

/* See symtab.h.  */

void
general_symbol_info::set_demangled_name (const char *name,
					 struct obstack *obstack)
{
  if (language () == language_ada)
    {
      if (name == NULL)
	{
	  ada_mangled = 0;
	  language_specific.obstack = obstack;
	}
      else
	{
	  ada_mangled = 1;
	  language_specific.demangled_name = name;
	}
    }
  else
    language_specific.demangled_name = name;
}


/* Initialize the language dependent portion of a symbol
   depending upon the language for the symbol.  */

void
general_symbol_info::set_language (enum language language,
				   struct obstack *obstack)
{
  m_language = language;
  if (language == language_cplus
      || language == language_d
      || language == language_go
      || language == language_objc
      || language == language_fortran)
    {
      set_demangled_name (NULL, obstack);
    }
  else if (language == language_ada)
    {
      gdb_assert (ada_mangled == 0);
      language_specific.obstack = obstack;
    }
  else
    {
      memset (&language_specific, 0, sizeof (language_specific));
    }
}

/* Functions to initialize a symbol's mangled name.  */

/* Objects of this type are stored in the demangled name hash table.  */
struct demangled_name_entry
{
  demangled_name_entry (std::string_view mangled_name)
    : mangled (mangled_name) {}

  std::string_view mangled;
  enum language language;
  gdb::unique_xmalloc_ptr<char> demangled;
};

/* Hash function for the demangled name hash.  */

static hashval_t
hash_demangled_name_entry (const void *data)
{
  const struct demangled_name_entry *e
    = (const struct demangled_name_entry *) data;

  return gdb::string_view_hash () (e->mangled);
}

/* Equality function for the demangled name hash.  */

static int
eq_demangled_name_entry (const void *a, const void *b)
{
  const struct demangled_name_entry *da
    = (const struct demangled_name_entry *) a;
  const struct demangled_name_entry *db
    = (const struct demangled_name_entry *) b;

  return da->mangled == db->mangled;
}

static void
free_demangled_name_entry (void *data)
{
  struct demangled_name_entry *e
    = (struct demangled_name_entry *) data;

  e->~demangled_name_entry();
}

/* Create the hash table used for demangled names.  Each hash entry is
   a pair of strings; one for the mangled name and one for the demangled
   name.  The entry is hashed via just the mangled name.  */

static void
create_demangled_names_hash (struct objfile_per_bfd_storage *per_bfd)
{
  /* Choose 256 as the starting size of the hash table, somewhat arbitrarily.
     The hash table code will round this up to the next prime number.
     Choosing a much larger table size wastes memory, and saves only about
     1% in symbol reading.  However, if the minsym count is already
     initialized (e.g. because symbol name setting was deferred to
     a background thread) we can initialize the hashtable with a count
     based on that, because we will almost certainly have at least that
     many entries.  If we have a nonzero number but less than 256,
     we still stay with 256 to have some space for psymbols, etc.  */

  /* htab will expand the table when it is 3/4th full, so we account for that
     here.  +2 to round up.  */
  int minsym_based_count = (per_bfd->minimal_symbol_count + 2) / 3 * 4;
  int count = std::max (per_bfd->minimal_symbol_count, minsym_based_count);

  per_bfd->demangled_names_hash.reset (htab_create_alloc
    (count, hash_demangled_name_entry, eq_demangled_name_entry,
     free_demangled_name_entry, xcalloc, xfree));
}

/* See symtab.h  */

gdb::unique_xmalloc_ptr<char>
symbol_find_demangled_name (struct general_symbol_info *gsymbol,
			    const char *mangled)
{
  gdb::unique_xmalloc_ptr<char> demangled;
  int i;

  if (gsymbol->language () != language_unknown)
    {
      const struct language_defn *lang = language_def (gsymbol->language ());

      lang->sniff_from_mangled_name (mangled, &demangled);
      return demangled;
    }

  for (i = language_unknown; i < nr_languages; ++i)
    {
      enum language l = (enum language) i;
      const struct language_defn *lang = language_def (l);

      if (lang->sniff_from_mangled_name (mangled, &demangled))
	{
	  gsymbol->m_language = l;
	  return demangled;
	}
    }

  return NULL;
}

/* Set both the mangled and demangled (if any) names for GSYMBOL based
   on LINKAGE_NAME and LEN.  Ordinarily, NAME is copied onto the
   objfile's obstack; but if COPY_NAME is 0 and if NAME is
   NUL-terminated, then this function assumes that NAME is already
   correctly saved (either permanently or with a lifetime tied to the
   objfile), and it will not be copied.

   The hash table corresponding to OBJFILE is used, and the memory
   comes from the per-BFD storage_obstack.  LINKAGE_NAME is copied,
   so the pointer can be discarded after calling this function.  */

void
general_symbol_info::compute_and_set_names (std::string_view linkage_name,
					    bool copy_name,
					    objfile_per_bfd_storage *per_bfd,
					    std::optional<hashval_t> hash)
{
  struct demangled_name_entry **slot;

  if (language () == language_ada)
    {
      /* In Ada, we do the symbol lookups using the mangled name, so
	 we can save some space by not storing the demangled name.  */
      if (!copy_name)
	m_name = linkage_name.data ();
      else
	m_name = obstack_strndup (&per_bfd->storage_obstack,
				  linkage_name.data (),
				  linkage_name.length ());
      set_demangled_name (NULL, &per_bfd->storage_obstack);

      return;
    }

  if (per_bfd->demangled_names_hash == NULL)
    create_demangled_names_hash (per_bfd);

  struct demangled_name_entry entry (linkage_name);
  if (!hash.has_value ())
    hash = hash_demangled_name_entry (&entry);
  slot = ((struct demangled_name_entry **)
	  htab_find_slot_with_hash (per_bfd->demangled_names_hash.get (),
				    &entry, *hash, INSERT));

  /* The const_cast is safe because the only reason it is already
     initialized is if we purposefully set it from a background
     thread to avoid doing the work here.  However, it is still
     allocated from the heap and needs to be freed by us, just
     like if we called symbol_find_demangled_name here.  If this is
     nullptr, we call symbol_find_demangled_name below, but we put
     this smart pointer here to be sure that we don't leak this name.  */
  gdb::unique_xmalloc_ptr<char> demangled_name
    (const_cast<char *> (language_specific.demangled_name));

  /* If this name is not in the hash table, add it.  */
  if (*slot == NULL
      /* A C version of the symbol may have already snuck into the table.
	 This happens to, e.g., main.init (__go_init_main).  Cope.  */
      || (language () == language_go && (*slot)->demangled == nullptr))
    {
      /* A 0-terminated copy of the linkage name.  Callers must set COPY_NAME
	 to true if the string might not be nullterminated.  We have to make
	 this copy because demangling needs a nullterminated string.  */
      std::string_view linkage_name_copy;
      if (copy_name)
	{
	  char *alloc_name = (char *) alloca (linkage_name.length () + 1);
	  memcpy (alloc_name, linkage_name.data (), linkage_name.length ());
	  alloc_name[linkage_name.length ()] = '\0';

	  linkage_name_copy = std::string_view (alloc_name,
						linkage_name.length ());
	}
      else
	linkage_name_copy = linkage_name;

      if (demangled_name.get () == nullptr)
	 demangled_name
	   = symbol_find_demangled_name (this, linkage_name_copy.data ());

      /* Suppose we have demangled_name==NULL, copy_name==0, and
	 linkage_name_copy==linkage_name.  In this case, we already have the
	 mangled name saved, and we don't have a demangled name.  So,
	 you might think we could save a little space by not recording
	 this in the hash table at all.

	 It turns out that it is actually important to still save such
	 an entry in the hash table, because storing this name gives
	 us better bcache hit rates for partial symbols.  */
      if (!copy_name)
	{
	  *slot
	    = ((struct demangled_name_entry *)
	       obstack_alloc (&per_bfd->storage_obstack,
			      sizeof (demangled_name_entry)));
	  new (*slot) demangled_name_entry (linkage_name);
	}
      else
	{
	  /* If we must copy the mangled name, put it directly after
	     the struct so we can have a single allocation.  */
	  *slot
	    = ((struct demangled_name_entry *)
	       obstack_alloc (&per_bfd->storage_obstack,
			      sizeof (demangled_name_entry)
			      + linkage_name.length () + 1));
	  char *mangled_ptr = reinterpret_cast<char *> (*slot + 1);
	  memcpy (mangled_ptr, linkage_name.data (), linkage_name.length ());
	  mangled_ptr [linkage_name.length ()] = '\0';
	  new (*slot) demangled_name_entry
	    (std::string_view (mangled_ptr, linkage_name.length ()));
	}
      (*slot)->demangled = std::move (demangled_name);
      (*slot)->language = language ();
    }
  else if (language () == language_unknown)
    m_language = (*slot)->language;

  m_name = (*slot)->mangled.data ();
  set_demangled_name ((*slot)->demangled.get (), &per_bfd->storage_obstack);
}

/* See symtab.h.  */

const char *
general_symbol_info::natural_name () const
{
  switch (language ())
    {
    case language_cplus:
    case language_d:
    case language_go:
    case language_objc:
    case language_fortran:
    case language_rust:
      if (language_specific.demangled_name != nullptr)
	return language_specific.demangled_name;
      break;
    case language_ada:
      return ada_decode_symbol (this);
    default:
      break;
    }
  return linkage_name ();
}

/* See symtab.h.  */

const char *
general_symbol_info::demangled_name () const
{
  const char *dem_name = NULL;

  switch (language ())
    {
    case language_cplus:
    case language_d:
    case language_go:
    case language_objc:
    case language_fortran:
    case language_rust:
      dem_name = language_specific.demangled_name;
      break;
    case language_ada:
      dem_name = ada_decode_symbol (this);
      break;
    default:
      break;
    }
  return dem_name;
}

/* See symtab.h.  */

const char *
general_symbol_info::search_name () const
{
  if (language () == language_ada)
    return linkage_name ();
  else
    return natural_name ();
}

/* See symtab.h.  */

struct obj_section *
general_symbol_info::obj_section (const struct objfile *objfile) const
{
  if (section_index () >= 0)
    return &objfile->sections_start[section_index ()];
  return nullptr;
}

/* See symtab.h.  */

bool
symbol_matches_search_name (const struct general_symbol_info *gsymbol,
			    const lookup_name_info &name)
{
  symbol_name_matcher_ftype *name_match
    = language_def (gsymbol->language ())->get_symbol_name_matcher (name);
  return name_match (gsymbol->search_name (), name, NULL);
}



/* Return true if the two sections are the same, or if they could
   plausibly be copies of each other, one in an original object
   file and another in a separated debug file.  */

bool
matching_obj_sections (struct obj_section *obj_first,
		       struct obj_section *obj_second)
{
  asection *first = obj_first? obj_first->the_bfd_section : NULL;
  asection *second = obj_second? obj_second->the_bfd_section : NULL;

  /* If they're the same section, then they match.  */
  if (first == second)
    return true;

  /* If either is NULL, give up.  */
  if (first == NULL || second == NULL)
    return false;

  /* This doesn't apply to absolute symbols.  */
  if (first->owner == NULL || second->owner == NULL)
    return false;

  /* If they're in the same object file, they must be different sections.  */
  if (first->owner == second->owner)
    return false;

  /* Check whether the two sections are potentially corresponding.  They must
     have the same size, address, and name.  We can't compare section indexes,
     which would be more reliable, because some sections may have been
     stripped.  */
  if (bfd_section_size (first) != bfd_section_size (second))
    return false;

  /* In-memory addresses may start at a different offset, relativize them.  */
  if (bfd_section_vma (first) - bfd_get_start_address (first->owner)
      != bfd_section_vma (second) - bfd_get_start_address (second->owner))
    return false;

  if (bfd_section_name (first) == NULL
      || bfd_section_name (second) == NULL
      || strcmp (bfd_section_name (first), bfd_section_name (second)) != 0)
    return false;

  /* Otherwise check that they are in corresponding objfiles.  */

  struct objfile *obj = NULL;
  for (objfile *objfile : current_program_space->objfiles ())
    if (objfile->obfd == first->owner)
      {
	obj = objfile;
	break;
      }
  gdb_assert (obj != NULL);

  if (obj->separate_debug_objfile != NULL
      && obj->separate_debug_objfile->obfd == second->owner)
    return true;
  if (obj->separate_debug_objfile_backlink != NULL
      && obj->separate_debug_objfile_backlink->obfd == second->owner)
    return true;

  return false;
}

/* Hash function for the symbol cache.  */

static unsigned int
hash_symbol_entry (const struct objfile *objfile_context,
		   const char *name, domain_search_flags domain)
{
  unsigned int hash = (uintptr_t) objfile_context;

  if (name != NULL)
    hash += htab_hash_string (name);

  hash += domain * 7;

  return hash;
}

/* Equality function for the symbol cache.  */

static int
eq_symbol_entry (const struct symbol_cache_slot *slot,
		 const struct objfile *objfile_context,
		 const char *name, domain_search_flags domain)
{
  const char *slot_name;

  if (slot->state == SYMBOL_SLOT_UNUSED)
    return 0;

  if (slot->objfile_context != objfile_context)
    return 0;

  domain_search_flags slot_domain = slot->domain;
  if (slot->state == SYMBOL_SLOT_NOT_FOUND)
    slot_name = slot->value.name;
  else
    slot_name = slot->value.found.symbol->search_name ();

  /* NULL names match.  */
  if (slot_name == NULL && name == NULL)
    {
      /* But there's no point in calling symbol_matches_domain in the
	 SYMBOL_SLOT_FOUND case.  */
      if (slot_domain != domain)
	return 0;
    }
  else if (slot_name != NULL && name != NULL)
    {
      /* It's important that we use the same comparison that was done
	 the first time through.  If the slot records a found symbol,
	 then this means using the symbol name comparison function of
	 the symbol's language with symbol->search_name ().  See
	 dictionary.c.

	 If the slot records a not-found symbol, then require a precise match.
	 We could still be lax with whitespace like strcmp_iw though.  */

      if (slot_domain != domain)
	return 0;

      if (slot->state == SYMBOL_SLOT_NOT_FOUND)
	{
	  if (strcmp (slot_name, name) != 0)
	    return 0;
	}
      else
	{
	  struct symbol *sym = slot->value.found.symbol;
	  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);

	  if (!symbol_matches_search_name (sym, lookup_name))
	    return 0;
	}
    }
  else
    {
      /* Only one name is NULL.  */
      return 0;
    }

  return 1;
}

/* Given a cache of size SIZE, return the size of the struct (with variable
   length array) in bytes.  */

static size_t
symbol_cache_byte_size (unsigned int size)
{
  return (sizeof (struct block_symbol_cache)
	  + ((size - 1) * sizeof (struct symbol_cache_slot)));
}

/* Resize CACHE.  */

static void
resize_symbol_cache (struct symbol_cache *cache, unsigned int new_size)
{
  /* If there's no change in size, don't do anything.
     All caches have the same size, so we can just compare with the size
     of the global symbols cache.  */
  if ((cache->global_symbols != NULL
       && cache->global_symbols->size == new_size)
      || (cache->global_symbols == NULL
	  && new_size == 0))
    return;

  destroy_block_symbol_cache (cache->global_symbols);
  destroy_block_symbol_cache (cache->static_symbols);

  if (new_size == 0)
    {
      cache->global_symbols = NULL;
      cache->static_symbols = NULL;
    }
  else
    {
      size_t total_size = symbol_cache_byte_size (new_size);

      cache->global_symbols
	= (struct block_symbol_cache *) xcalloc (1, total_size);
      cache->static_symbols
	= (struct block_symbol_cache *) xcalloc (1, total_size);
      cache->global_symbols->size = new_size;
      cache->static_symbols->size = new_size;
    }
}

/* Return the symbol cache of PSPACE.
   Create one if it doesn't exist yet.  */

static struct symbol_cache *
get_symbol_cache (struct program_space *pspace)
{
  struct symbol_cache *cache = symbol_cache_key.get (pspace);

  if (cache == NULL)
    {
      cache = symbol_cache_key.emplace (pspace);
      resize_symbol_cache (cache, symbol_cache_size);
    }

  return cache;
}

/* Set the size of the symbol cache in all program spaces.  */

static void
set_symbol_cache_size (unsigned int new_size)
{
  for (struct program_space *pspace : program_spaces)
    {
      struct symbol_cache *cache = symbol_cache_key.get (pspace);

      /* The pspace could have been created but not have a cache yet.  */
      if (cache != NULL)
	resize_symbol_cache (cache, new_size);
    }
}

/* Called when symbol-cache-size is set.  */

static void
set_symbol_cache_size_handler (const char *args, int from_tty,
			       struct cmd_list_element *c)
{
  if (new_symbol_cache_size > MAX_SYMBOL_CACHE_SIZE)
    {
      /* Restore the previous value.
	 This is the value the "show" command prints.  */
      new_symbol_cache_size = symbol_cache_size;

      error (_("Symbol cache size is too large, max is %u."),
	     MAX_SYMBOL_CACHE_SIZE);
    }
  symbol_cache_size = new_symbol_cache_size;

  set_symbol_cache_size (symbol_cache_size);
}

/* Lookup symbol NAME,DOMAIN in BLOCK in the symbol cache of PSPACE.
   OBJFILE_CONTEXT is the current objfile, which may be NULL.
   The result is the symbol if found, SYMBOL_LOOKUP_FAILED if a previous lookup
   failed (and thus this one will too), or NULL if the symbol is not present
   in the cache.
   *BSC_PTR and *SLOT_PTR are set to the cache and slot of the symbol, which
   can be used to save the result of a full lookup attempt.  */

static struct block_symbol
symbol_cache_lookup (struct symbol_cache *cache,
		     struct objfile *objfile_context, enum block_enum block,
		     const char *name, domain_search_flags domain,
		     struct block_symbol_cache **bsc_ptr,
		     struct symbol_cache_slot **slot_ptr)
{
  struct block_symbol_cache *bsc;
  unsigned int hash;
  struct symbol_cache_slot *slot;

  if (block == GLOBAL_BLOCK)
    bsc = cache->global_symbols;
  else
    bsc = cache->static_symbols;
  if (bsc == NULL)
    {
      *bsc_ptr = NULL;
      *slot_ptr = NULL;
      return {};
    }

  hash = hash_symbol_entry (objfile_context, name, domain);
  slot = bsc->symbols + hash % bsc->size;

  *bsc_ptr = bsc;
  *slot_ptr = slot;

  if (eq_symbol_entry (slot, objfile_context, name, domain))
    {
      symbol_lookup_debug_printf ("%s block symbol cache hit%s for %s, %s",
				  block == GLOBAL_BLOCK ? "Global" : "Static",
				  slot->state == SYMBOL_SLOT_NOT_FOUND
				  ? " (not found)" : "", name,
				  domain_name (domain).c_str ());
      ++bsc->hits;
      if (slot->state == SYMBOL_SLOT_NOT_FOUND)
	return SYMBOL_LOOKUP_FAILED;
      return slot->value.found;
    }

  /* Symbol is not present in the cache.  */

  symbol_lookup_debug_printf ("%s block symbol cache miss for %s, %s",
			      block == GLOBAL_BLOCK ? "Global" : "Static",
			      name, domain_name (domain).c_str ());
  ++bsc->misses;
  return {};
}

/* Mark SYMBOL as found in SLOT.
   OBJFILE_CONTEXT is the current objfile when the lookup was done, or NULL
   if it's not needed to distinguish lookups (STATIC_BLOCK).  It is *not*
   necessarily the objfile the symbol was found in.  */

static void
symbol_cache_mark_found (struct block_symbol_cache *bsc,
			 struct symbol_cache_slot *slot,
			 struct objfile *objfile_context,
			 struct symbol *symbol,
			 const struct block *block,
			 domain_search_flags domain)
{
  if (bsc == NULL)
    return;
  if (slot->state != SYMBOL_SLOT_UNUSED)
    {
      ++bsc->collisions;
      symbol_cache_clear_slot (slot);
    }
  slot->state = SYMBOL_SLOT_FOUND;
  slot->objfile_context = objfile_context;
  slot->value.found.symbol = symbol;
  slot->value.found.block = block;
  slot->domain = domain;
}

/* Mark symbol NAME, DOMAIN as not found in SLOT.
   OBJFILE_CONTEXT is the current objfile when the lookup was done, or NULL
   if it's not needed to distinguish lookups (STATIC_BLOCK).  */

static void
symbol_cache_mark_not_found (struct block_symbol_cache *bsc,
			     struct symbol_cache_slot *slot,
			     struct objfile *objfile_context,
			     const char *name, domain_search_flags domain)
{
  if (bsc == NULL)
    return;
  if (slot->state != SYMBOL_SLOT_UNUSED)
    {
      ++bsc->collisions;
      symbol_cache_clear_slot (slot);
    }
  slot->state = SYMBOL_SLOT_NOT_FOUND;
  slot->objfile_context = objfile_context;
  slot->value.name = xstrdup (name);
  slot->domain = domain;
}

/* Flush the symbol cache of PSPACE.  */

static void
symbol_cache_flush (struct program_space *pspace)
{
  ada_clear_symbol_cache (pspace);
  struct symbol_cache *cache = symbol_cache_key.get (pspace);
  int pass;

  if (cache == NULL)
    return;
  if (cache->global_symbols == NULL)
    {
      gdb_assert (symbol_cache_size == 0);
      gdb_assert (cache->static_symbols == NULL);
      return;
    }

  /* If the cache is untouched since the last flush, early exit.
     This is important for performance during the startup of a program linked
     with 100s (or 1000s) of shared libraries.  */
  if (cache->global_symbols->misses == 0
      && cache->static_symbols->misses == 0)
    return;

  gdb_assert (cache->global_symbols->size == symbol_cache_size);
  gdb_assert (cache->static_symbols->size == symbol_cache_size);

  for (pass = 0; pass < 2; ++pass)
    {
      struct block_symbol_cache *bsc
	= pass == 0 ? cache->global_symbols : cache->static_symbols;
      unsigned int i;

      for (i = 0; i < bsc->size; ++i)
	symbol_cache_clear_slot (&bsc->symbols[i]);
    }

  cache->global_symbols->hits = 0;
  cache->global_symbols->misses = 0;
  cache->global_symbols->collisions = 0;
  cache->static_symbols->hits = 0;
  cache->static_symbols->misses = 0;
  cache->static_symbols->collisions = 0;
}

/* Dump CACHE.  */

static void
symbol_cache_dump (const struct symbol_cache *cache)
{
  int pass;

  if (cache->global_symbols == NULL)
    {
      gdb_printf ("  <disabled>\n");
      return;
    }

  for (pass = 0; pass < 2; ++pass)
    {
      const struct block_symbol_cache *bsc
	= pass == 0 ? cache->global_symbols : cache->static_symbols;
      unsigned int i;

      if (pass == 0)
	gdb_printf ("Global symbols:\n");
      else
	gdb_printf ("Static symbols:\n");

      for (i = 0; i < bsc->size; ++i)
	{
	  const struct symbol_cache_slot *slot = &bsc->symbols[i];

	  QUIT;

	  switch (slot->state)
	    {
	    case SYMBOL_SLOT_UNUSED:
	      break;
	    case SYMBOL_SLOT_NOT_FOUND:
	      gdb_printf ("  [%4u] = %s, %s %s (not found)\n", i,
			  host_address_to_string (slot->objfile_context),
			  slot->value.name,
			  domain_name (slot->domain).c_str ());
	      break;
	    case SYMBOL_SLOT_FOUND:
	      {
		struct symbol *found = slot->value.found.symbol;
		const struct objfile *context = slot->objfile_context;

		gdb_printf ("  [%4u] = %s, %s %s\n", i,
			    host_address_to_string (context),
			    found->print_name (),
			    domain_name (found->domain ()));
		break;
	      }
	    }
	}
    }
}

/* The "mt print symbol-cache" command.  */

static void
maintenance_print_symbol_cache (const char *args, int from_tty)
{
  for (struct program_space *pspace : program_spaces)
    {
      struct symbol_cache *cache;

      gdb_printf (_("Symbol cache for pspace %d\n%s:\n"),
		  pspace->num,
		  pspace->symfile_object_file != NULL
		  ? objfile_name (pspace->symfile_object_file)
		  : "(no object file)");

      /* If the cache hasn't been created yet, avoid creating one.  */
      cache = symbol_cache_key.get (pspace);
      if (cache == NULL)
	gdb_printf ("  <empty>\n");
      else
	symbol_cache_dump (cache);
    }
}

/* The "mt flush-symbol-cache" command.  */

static void
maintenance_flush_symbol_cache (const char *args, int from_tty)
{
  for (struct program_space *pspace : program_spaces)
    {
      symbol_cache_flush (pspace);
    }
}

/* Print usage statistics of CACHE.  */

static void
symbol_cache_stats (struct symbol_cache *cache)
{
  int pass;

  if (cache->global_symbols == NULL)
    {
      gdb_printf ("  <disabled>\n");
      return;
    }

  for (pass = 0; pass < 2; ++pass)
    {
      const struct block_symbol_cache *bsc
	= pass == 0 ? cache->global_symbols : cache->static_symbols;

      QUIT;

      if (pass == 0)
	gdb_printf ("Global block cache stats:\n");
      else
	gdb_printf ("Static block cache stats:\n");

      gdb_printf ("  size:       %u\n", bsc->size);
      gdb_printf ("  hits:       %u\n", bsc->hits);
      gdb_printf ("  misses:     %u\n", bsc->misses);
      gdb_printf ("  collisions: %u\n", bsc->collisions);
    }
}

/* The "mt print symbol-cache-statistics" command.  */

static void
maintenance_print_symbol_cache_statistics (const char *args, int from_tty)
{
  for (struct program_space *pspace : program_spaces)
    {
      struct symbol_cache *cache;

      gdb_printf (_("Symbol cache statistics for pspace %d\n%s:\n"),
		  pspace->num,
		  pspace->symfile_object_file != NULL
		  ? objfile_name (pspace->symfile_object_file)
		  : "(no object file)");

      /* If the cache hasn't been created yet, avoid creating one.  */
      cache = symbol_cache_key.get (pspace);
      if (cache == NULL)
	gdb_printf ("  empty, no stats available\n");
      else
	symbol_cache_stats (cache);
    }
}

/* This module's 'new_objfile' observer.  */

static void
symtab_new_objfile_observer (struct objfile *objfile)
{
  symbol_cache_flush (objfile->pspace ());
}

/* This module's 'all_objfiles_removed' observer.  */

static void
symtab_all_objfiles_removed (program_space *pspace)
{
  symbol_cache_flush (pspace);

  /* Forget everything we know about the main function.  */
  main_progspace_key.clear (pspace);
}

/* This module's 'free_objfile' observer.  */

static void
symtab_free_objfile_observer (struct objfile *objfile)
{
  symbol_cache_flush (objfile->pspace ());
}

/* See symtab.h.  */

void
fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
{
  gdb_assert (sym != nullptr);
  gdb_assert (sym->is_objfile_owned ());
  gdb_assert (objfile != nullptr);
  gdb_assert (sym->section_index () == -1);

  /* Note that if this ends up as -1, fixup_section will handle that
     reasonably well.  So, it's fine to use the objfile's section
     index without doing the check that is done by the wrapper macros
     like SECT_OFF_TEXT.  */
  int fallback;
  switch (sym->aclass ())
    {
    case LOC_STATIC:
      fallback = objfile->sect_index_data;
      break;

    case LOC_LABEL:
      fallback = objfile->sect_index_text;
      break;

    default:
      /* Nothing else will be listed in the minsyms -- no use looking
	 it up.  */
      return;
    }

  CORE_ADDR addr = sym->value_address ();

  struct minimal_symbol *msym;

  /* First, check whether a minimal symbol with the same name exists
     and points to the same address.  The address check is required
     e.g. on PowerPC64, where the minimal symbol for a function will
     point to the function descriptor, while the debug symbol will
     point to the actual function code.  */
  msym = lookup_minimal_symbol_by_pc_name (addr, sym->linkage_name (),
					   objfile);
  if (msym)
    sym->set_section_index (msym->section_index ());
  else
    {
      /* Static, function-local variables do appear in the linker
	 (minimal) symbols, but are frequently given names that won't
	 be found via lookup_minimal_symbol().  E.g., it has been
	 observed in frv-uclinux (ELF) executables that a static,
	 function-local variable named "foo" might appear in the
	 linker symbols as "foo.6" or "foo.3".  Thus, there is no
	 point in attempting to extend the lookup-by-name mechanism to
	 handle this case due to the fact that there can be multiple
	 names.

	 So, instead, search the section table when lookup by name has
	 failed.  The ``addr'' and ``endaddr'' fields may have already
	 been relocated.  If so, the relocation offset needs to be
	 subtracted from these values when performing the comparison.
	 We unconditionally subtract it, because, when no relocation
	 has been performed, the value will simply be zero.

	 The address of the symbol whose section we're fixing up HAS
	 NOT BEEN adjusted (relocated) yet.  It can't have been since
	 the section isn't yet known and knowing the section is
	 necessary in order to add the correct relocation value.  In
	 other words, we wouldn't even be in this function (attempting
	 to compute the section) if it were already known.

	 Note that it is possible to search the minimal symbols
	 (subtracting the relocation value if necessary) to find the
	 matching minimal symbol, but this is overkill and much less
	 efficient.  It is not necessary to find the matching minimal
	 symbol, only its section.

	 Note that this technique (of doing a section table search)
	 can fail when unrelocated section addresses overlap.  For
	 this reason, we still attempt a lookup by name prior to doing
	 a search of the section table.  */

      for (obj_section *s : objfile->sections ())
	{
	  if ((bfd_section_flags (s->the_bfd_section) & SEC_ALLOC) == 0)
	    continue;

	  int idx = s - objfile->sections_start;
	  CORE_ADDR offset = objfile->section_offsets[idx];

	  if (fallback == -1)
	    fallback = idx;

	  if (s->addr () - offset <= addr && addr < s->endaddr () - offset)
	    {
	      sym->set_section_index (idx);
	      return;
	    }
	}

      /* If we didn't find the section, assume it is in the first
	 section.  If there is no allocated section, then it hardly
	 matters what we pick, so just pick zero.  */
      if (fallback == -1)
	sym->set_section_index (0);
      else
	sym->set_section_index (fallback);
    }
}

/* See symtab.h.  */

demangle_for_lookup_info::demangle_for_lookup_info
  (const lookup_name_info &lookup_name, language lang)
{
  demangle_result_storage storage;

  if (lookup_name.ignore_parameters () && lang == language_cplus)
    {
      gdb::unique_xmalloc_ptr<char> without_params
	= cp_remove_params_if_any (lookup_name.c_str (),
				   lookup_name.completion_mode ());

      if (without_params != NULL)
	{
	  if (lookup_name.match_type () != symbol_name_match_type::SEARCH_NAME)
	    m_demangled_name = demangle_for_lookup (without_params.get (),
						    lang, storage);
	  return;
	}
    }

  if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME)
    m_demangled_name = lookup_name.c_str ();
  else
    m_demangled_name = demangle_for_lookup (lookup_name.c_str (),
					    lang, storage);
}

/* See symtab.h.  */

const lookup_name_info &
lookup_name_info::match_any ()
{
  /* Lookup any symbol that "" would complete.  I.e., this matches all
     symbol names.  */
  static const lookup_name_info lookup_name ("", symbol_name_match_type::WILD,
					     true);

  return lookup_name;
}

/* See symtab.h.  */

unsigned int
lookup_name_info::search_name_hash (language lang) const
{
  /* This works around an obscure problem.  If currently in Ada mode,
     and the name is wrapped in '<...>' (indicating verbatim mode),
     force the use of the Ada language here so that the '<' and '>'
     will be removed.  */
  if (current_language->la_language == language_ada && ada ().verbatim_p ())
    lang = language_ada;

  /* Only compute each language's hash once.  */
  if (!m_demangled_hashes_p[lang])
    {
      m_demangled_hashes[lang]
	= ::search_name_hash (lang, language_lookup_name (lang));
      m_demangled_hashes_p[lang] = true;
    }
  return m_demangled_hashes[lang];
}

/* Compute the demangled form of NAME as used by the various symbol
   lookup functions.  The result can either be the input NAME
   directly, or a pointer to a buffer owned by the STORAGE object.

   For Ada, this function just returns NAME, unmodified.
   Normally, Ada symbol lookups are performed using the encoded name
   rather than the demangled name, and so it might seem to make sense
   for this function to return an encoded version of NAME.
   Unfortunately, we cannot do this, because this function is used in
   circumstances where it is not appropriate to try to encode NAME.
   For instance, when displaying the frame info, we demangle the name
   of each parameter, and then perform a symbol lookup inside our
   function using that demangled name.  In Ada, certain functions
   have internally-generated parameters whose name contain uppercase
   characters.  Encoding those name would result in those uppercase
   characters to become lowercase, and thus cause the symbol lookup
   to fail.  */

const char *
demangle_for_lookup (const char *name, enum language lang,
		     demangle_result_storage &storage)
{
  /* If we are using C++, D, or Go, demangle the name before doing a
     lookup, so we can always binary search.  */
  if (lang == language_cplus)
    {
      gdb::unique_xmalloc_ptr<char> demangled_name
	= gdb_demangle (name, DMGL_ANSI | DMGL_PARAMS);
      if (demangled_name != NULL)
	return storage.set_malloc_ptr (std::move (demangled_name));

      /* If we were given a non-mangled name, canonicalize it
	 according to the language (so far only for C++).  */
      gdb::unique_xmalloc_ptr<char> canon = cp_canonicalize_string (name);
      if (canon != nullptr)
	return storage.set_malloc_ptr (std::move (canon));
    }
  else if (lang == language_d)
    {
      gdb::unique_xmalloc_ptr<char> demangled_name = d_demangle (name, 0);
      if (demangled_name != NULL)
	return storage.set_malloc_ptr (std::move (demangled_name));
    }
  else if (lang == language_go)
    {
      gdb::unique_xmalloc_ptr<char> demangled_name
	= language_def (language_go)->demangle_symbol (name, 0);
      if (demangled_name != NULL)
	return storage.set_malloc_ptr (std::move (demangled_name));
    }

  return name;
}

/* See symtab.h.  */

unsigned int
search_name_hash (enum language language, const char *search_name)
{
  return language_def (language)->search_name_hash (search_name);
}

/* See symtab.h.

   This function (or rather its subordinates) have a bunch of loops and
   it would seem to be attractive to put in some QUIT's (though I'm not really
   sure whether it can run long enough to be really important).  But there
   are a few calls for which it would appear to be bad news to quit
   out of here: e.g., find_proc_desc in alpha-mdebug-tdep.c.  (Note
   that there is C++ code below which can error(), but that probably
   doesn't affect these calls since they are looking for a known
   variable and thus can probably assume it will never hit the C++
   code).  */

struct block_symbol
lookup_symbol_in_language (const char *name, const struct block *block,
			   const domain_search_flags domain,
			   enum language lang,
			   struct field_of_this_result *is_a_field_of_this)
{
  SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT;

  demangle_result_storage storage;
  const char *modified_name = demangle_for_lookup (name, lang, storage);

  return lookup_symbol_aux (modified_name,
			    symbol_name_match_type::FULL,
			    block, domain, lang,
			    is_a_field_of_this);
}

/* See symtab.h.  */

struct block_symbol
lookup_symbol (const char *name, const struct block *block,
	       domain_search_flags domain,
	       struct field_of_this_result *is_a_field_of_this)
{
  return lookup_symbol_in_language (name, block, domain,
				    current_language->la_language,
				    is_a_field_of_this);
}

/* See symtab.h.  */

struct block_symbol
lookup_symbol_search_name (const char *search_name, const struct block *block,
			   domain_search_flags domain)
{
  return lookup_symbol_aux (search_name, symbol_name_match_type::SEARCH_NAME,
			    block, domain, language_asm, NULL);
}

/* See symtab.h.  */

struct block_symbol
lookup_language_this (const struct language_defn *lang,
		      const struct block *block)
{
  if (lang->name_of_this () == NULL || block == NULL)
    return {};

  symbol_lookup_debug_printf_v ("lookup_language_this (%s, %s (objfile %s))",
				lang->name (), host_address_to_string (block),
				objfile_debug_name (block->objfile ()));

  lookup_name_info this_name (lang->name_of_this (),
			      symbol_name_match_type::SEARCH_NAME);

  while (block)
    {
      struct symbol *sym;

      sym = block_lookup_symbol (block, this_name, SEARCH_VFT);
      if (sym != NULL)
	{
	  symbol_lookup_debug_printf_v
	    ("lookup_language_this (...) = %s (%s, block %s)",
	     sym->print_name (), host_address_to_string (sym),
	     host_address_to_string (block));
	  return (struct block_symbol) {sym, block};
	}
      if (block->function ())
	break;
      block = block->superblock ();
    }

  symbol_lookup_debug_printf_v ("lookup_language_this (...) = NULL");
  return {};
}

/* Given TYPE, a structure/union,
   return 1 if the component named NAME from the ultimate target
   structure/union is defined, otherwise, return 0.  */

static int
check_field (struct type *type, const char *name,
	     struct field_of_this_result *is_a_field_of_this)
{
  int i;

  /* The type may be a stub.  */
  type = check_typedef (type);

  for (i = type->num_fields () - 1; i >= TYPE_N_BASECLASSES (type); i--)
    {
      const char *t_field_name = type->field (i).name ();

      if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
	{
	  is_a_field_of_this->type = type;
	  is_a_field_of_this->field = &type->field (i);
	  return 1;
	}
    }

  /* C++: If it was not found as a data field, then try to return it
     as a pointer to a method.  */

  for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
    {
      if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0)
	{
	  is_a_field_of_this->type = type;
	  is_a_field_of_this->fn_field = &TYPE_FN_FIELDLIST (type, i);
	  return 1;
	}
    }

  for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
    if (check_field (TYPE_BASECLASS (type, i), name, is_a_field_of_this))
      return 1;

  return 0;
}

/* Behave like lookup_symbol except that NAME is the natural name
   (e.g., demangled name) of the symbol that we're looking for.  */

static struct block_symbol
lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
		   const struct block *block,
		   const domain_search_flags domain, enum language language,
		   struct field_of_this_result *is_a_field_of_this)
{
  SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT;

  struct block_symbol result;
  const struct language_defn *langdef;

  if (symbol_lookup_debug)
    {
      struct objfile *objfile = (block == nullptr
				 ? nullptr : block->objfile ());

      symbol_lookup_debug_printf
	("demangled symbol name = \"%s\", block @ %s (objfile %s)",
	 name, host_address_to_string (block),
	 objfile != NULL ? objfile_debug_name (objfile) : "NULL");
      symbol_lookup_debug_printf
	("domain name = \"%s\", language = \"%s\")",
	 domain_name (domain).c_str (), language_str (language));
    }

  langdef = language_def (language);

  /* Search specified block and its superiors.  Don't search
     STATIC_BLOCK or GLOBAL_BLOCK.  */

  result = lookup_local_symbol (name, match_type, block, domain, langdef);
  if (result.symbol != NULL)
    {
      symbol_lookup_debug_printf
	("found symbol @ %s (using lookup_local_symbol)",
	 host_address_to_string (result.symbol));
      return result;
    }

  /* If requested to do so by the caller and if appropriate for LANGUAGE,
     check to see if NAME is a field of `this'.  */

  /* Don't do this check if we are searching for a struct.  It will
     not be found by check_field, but will be found by other
     means.  */
  if (is_a_field_of_this != NULL && (domain & SEARCH_STRUCT_DOMAIN) == 0)
    {
      result = lookup_language_this (langdef, block);

      if (result.symbol)
	{
	  struct type *t = result.symbol->type ();

	  /* I'm not really sure that type of this can ever
	     be typedefed; just be safe.  */
	  t = check_typedef (t);
	  if (t->is_pointer_or_reference ())
	    t = t->target_type ();

	  if (t->code () != TYPE_CODE_STRUCT
	      && t->code () != TYPE_CODE_UNION)
	    error (_("Internal error: `%s' is not an aggregate"),
		   langdef->name_of_this ());

	  if (check_field (t, name, is_a_field_of_this))
	    {
	      symbol_lookup_debug_printf ("no symbol found");
	      return {};
	    }
	}
    }

  /* Now do whatever is appropriate for LANGUAGE to look
     up static and global variables.  */

  result = langdef->lookup_symbol_nonlocal (name, block, domain);
  if (result.symbol != NULL)
    {
      symbol_lookup_debug_printf
	("found symbol @ %s (using language lookup_symbol_nonlocal)",
	 host_address_to_string (result.symbol));
      return result;
    }

  /* Now search all static file-level symbols.  Not strictly correct,
     but more useful than an error.  */

  result = lookup_static_symbol (name, domain);
  symbol_lookup_debug_printf
    ("found symbol @ %s (using lookup_static_symbol)",
     result.symbol != NULL ? host_address_to_string (result.symbol) : "NULL");
  return result;
}

/* Check to see if the symbol is defined in BLOCK or its superiors.
   Don't search STATIC_BLOCK or GLOBAL_BLOCK.  */

static struct block_symbol
lookup_local_symbol (const char *name,
		     symbol_name_match_type match_type,
		     const struct block *block,
		     const domain_search_flags domain,
		     const struct language_defn *langdef)
{
  if (block == nullptr)
    return {};

  const char *scope = block->scope ();
  
  while (!block->is_global_block () && !block->is_static_block ())
    {
      struct symbol *sym = lookup_symbol_in_block (name, match_type,
						   block, domain);
      if (sym != NULL)
	return (struct block_symbol) {sym, block};

      struct symbol *function = block->function ();
      if (function != nullptr && function->is_template_function ())
	{
	  struct template_symbol *templ = (struct template_symbol *) function;
	  sym = search_symbol_list (name,
				    templ->n_template_arguments,
				    templ->template_arguments);
	  if (sym != nullptr)
	    return (struct block_symbol) {sym, block};
	}

      struct block_symbol blocksym
	= langdef->lookup_symbol_local (scope, name, block, domain);
      if (blocksym.symbol != nullptr)
	return blocksym;

      if (block->inlined_p ())
	break;
      block = block->superblock ();
    }

  /* We've reached the end of the function without finding a result.  */

  return {};
}

/* See symtab.h.  */

struct symbol *
lookup_symbol_in_block (const char *name, symbol_name_match_type match_type,
			const struct block *block,
			const domain_search_flags domain)
{
  enter_symbol_lookup tmp;

  struct symbol *sym;

  if (symbol_lookup_debug)
    {
      struct objfile *objfile
	= block == nullptr ? nullptr : block->objfile ();

      symbol_lookup_debug_printf_v
	("lookup_symbol_in_block (%s, %s (objfile %s), %s)",
	 name, host_address_to_string (block),
	 objfile != nullptr ? objfile_debug_name (objfile) : "NULL",
	 domain_name (domain).c_str ());
    }

  lookup_name_info lookup_name (name, match_type);
  sym = block_lookup_symbol (block, lookup_name, domain);
  if (sym)
    {
      symbol_lookup_debug_printf_v ("lookup_symbol_in_block (...) = %s",
				    host_address_to_string (sym));
      return sym;
    }

  symbol_lookup_debug_printf_v ("lookup_symbol_in_block (...) = NULL");
  return NULL;
}

/* See symtab.h.  */

struct block_symbol
lookup_global_symbol_from_objfile (struct objfile *main_objfile,
				   enum block_enum block_index,
				   const char *name,
				   const domain_search_flags domain)
{
  enter_symbol_lookup tmp;

  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);

  for (objfile *objfile : main_objfile->separate_debug_objfiles ())
    {
      struct block_symbol result
	= lookup_symbol_in_objfile (objfile, block_index, name, domain);

      if (result.symbol != nullptr)
	return result;
    }

  return {};
}

/* Check to see if the symbol is defined in one of the OBJFILE's
   symtabs.  BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
   depending on whether or not we want to search global symbols or
   static symbols.  */

static struct block_symbol
lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
				  enum block_enum block_index, const char *name,
				  const domain_search_flags domain)
{
  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);

  symbol_lookup_debug_printf_v
    ("lookup_symbol_in_objfile_symtabs (%s, %s, %s, %s)",
     objfile_debug_name (objfile),
     block_index == GLOBAL_BLOCK ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
     name, domain_name (domain).c_str ());

  struct block_symbol other;
  other.symbol = NULL;
  for (compunit_symtab *cust : objfile->compunits ())
    {
      const struct blockvector *bv;
      const struct block *block;
      struct block_symbol result;

      bv = cust->blockvector ();
      block = bv->block (block_index);
      result.symbol = block_lookup_symbol_primary (block, name, domain);
      result.block = block;
      if (result.symbol == NULL)
	continue;
      if (best_symbol (result.symbol, domain))
	{
	  other = result;
	  break;
	}
      if (result.symbol->matches (domain))
	{
	  struct symbol *better
	    = better_symbol (other.symbol, result.symbol, domain);
	  if (better != other.symbol)
	    {
	      other.symbol = better;
	      other.block = block;
	    }
	}
    }

  if (other.symbol != NULL)
    {
      symbol_lookup_debug_printf_v
	("lookup_symbol_in_objfile_symtabs (...) = %s (block %s)",
	 host_address_to_string (other.symbol),
	 host_address_to_string (other.block));
      return other;
    }

  symbol_lookup_debug_printf_v
    ("lookup_symbol_in_objfile_symtabs (...) = NULL");
  return {};
}

/* Wrapper around lookup_symbol_in_objfile_symtabs for search_symbols.
   Look up LINKAGE_NAME in DOMAIN in the global and static blocks of OBJFILE
   and all associated separate debug objfiles.

   Normally we only look in OBJFILE, and not any separate debug objfiles
   because the outer loop will cause them to be searched too.  This case is
   different.  Here we're called from search_symbols where it will only
   call us for the objfile that contains a matching minsym.  */

static struct block_symbol
lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
					    const char *linkage_name,
					    domain_search_flags domain)
{
  enum language lang = current_language->la_language;
  struct objfile *main_objfile;

  demangle_result_storage storage;
  const char *modified_name = demangle_for_lookup (linkage_name, lang, storage);

  if (objfile->separate_debug_objfile_backlink)
    main_objfile = objfile->separate_debug_objfile_backlink;
  else
    main_objfile = objfile;

  for (::objfile *cur_objfile : main_objfile->separate_debug_objfiles ())
    {
      struct block_symbol result;

      result = lookup_symbol_in_objfile_symtabs (cur_objfile, GLOBAL_BLOCK,
						 modified_name, domain);
      if (result.symbol == NULL)
	result = lookup_symbol_in_objfile_symtabs (cur_objfile, STATIC_BLOCK,
						   modified_name, domain);
      if (result.symbol != NULL)
	return result;
    }

  return {};
}

/* A helper function that throws an exception when a symbol was found
   in a psymtab but not in a symtab.  */

[[noreturn]] static void
error_in_psymtab_expansion (enum block_enum block_index, const char *name,
			    struct compunit_symtab *cust)
{
  error (_("\
Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\
%s may be an inlined function, or may be a template function\n	 \
(if a template, try specifying an instantiation: %s<type>)."),
	 block_index == GLOBAL_BLOCK ? "global" : "static",
	 name,
	 symtab_to_filename_for_display (cust->primary_filetab ()),
	 name, name);
}

/* A helper function for various lookup routines that interfaces with
   the "quick" symbol table functions.  */

static struct block_symbol
lookup_symbol_via_quick_fns (struct objfile *objfile,
			     enum block_enum block_index, const char *name,
			     const domain_search_flags domain)
{
  struct compunit_symtab *cust;
  const struct blockvector *bv;
  const struct block *block;
  struct block_symbol result;

  symbol_lookup_debug_printf_v
    ("lookup_symbol_via_quick_fns (%s, %s, %s, %s)",
     objfile_debug_name (objfile),
     block_index == GLOBAL_BLOCK ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
     name, domain_name (domain).c_str ());

  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
  cust = objfile->lookup_symbol (block_index, lookup_name, domain);
  if (cust == NULL)
    {
      symbol_lookup_debug_printf_v
	("lookup_symbol_via_quick_fns (...) = NULL");
      return {};
    }

  bv = cust->blockvector ();
  block = bv->block (block_index);
  result.symbol = block_lookup_symbol (block, lookup_name, domain);
  if (result.symbol == NULL)
    error_in_psymtab_expansion (block_index, name, cust);

  symbol_lookup_debug_printf_v
    ("lookup_symbol_via_quick_fns (...) = %s (block %s)",
     host_address_to_string (result.symbol),
     host_address_to_string (block));

  result.block = block;
  return result;
}

/* See language.h.  */

struct block_symbol
language_defn::lookup_symbol_nonlocal (const char *name,
				       const struct block *block,
				       const domain_search_flags domain) const
{
  struct block_symbol result;

  /* NOTE: dje/2014-10-26: The lookup in all objfiles search could skip
     the current objfile.  Searching the current objfile first is useful
     for both matching user expectations as well as performance.  */

  result = lookup_symbol_in_static_block (name, block, domain);
  if (result.symbol != NULL)
    return result;

  /* If we didn't find a definition for a builtin type in the static block,
     search for it now.  This is actually the right thing to do and can be
     a massive performance win.  E.g., when debugging a program with lots of
     shared libraries we could search all of them only to find out the
     builtin type isn't defined in any of them.  This is common for types
     like "void".  */
  if ((domain & SEARCH_TYPE_DOMAIN) != 0)
    {
      struct gdbarch *gdbarch;

      if (block == NULL)
	gdbarch = current_inferior ()->arch ();
      else
	gdbarch = block->gdbarch ();
      result.symbol = language_lookup_primitive_type_as_symbol (this,
								gdbarch, name);
      result.block = NULL;
      if (result.symbol != NULL)
	return result;
    }

  return lookup_global_symbol (name, block, domain);
}

/* See symtab.h.  */

struct block_symbol
lookup_symbol_in_static_block (const char *name,
			       const struct block *block,
			       const domain_search_flags domain)
{
  if (block == nullptr)
    return {};

  const struct block *static_block = block->static_block ();
  struct symbol *sym;

  if (static_block == NULL)
    return {};

  if (symbol_lookup_debug)
    {
      struct objfile *objfile = (block == nullptr
				 ? nullptr : block->objfile ());

      symbol_lookup_debug_printf
	("lookup_symbol_in_static_block (%s, %s (objfile %s), %s)",
	 name, host_address_to_string (block),
	 objfile != nullptr ? objfile_debug_name (objfile) : "NULL",
	 domain_name (domain).c_str ());
    }

  sym = lookup_symbol_in_block (name,
				symbol_name_match_type::FULL,
				static_block, domain);
  symbol_lookup_debug_printf ("lookup_symbol_in_static_block (...) = %s",
			      sym != NULL
			      ? host_address_to_string (sym) : "NULL");
  return (struct block_symbol) {sym, static_block};
}

/* Perform the standard symbol lookup of NAME in OBJFILE:
   1) First search expanded symtabs, and if not found
   2) Search the "quick" symtabs (partial or .gdb_index).
   BLOCK_INDEX is one of GLOBAL_BLOCK or STATIC_BLOCK.  */

static struct block_symbol
lookup_symbol_in_objfile (struct objfile *objfile, enum block_enum block_index,
			  const char *name, const domain_search_flags domain)
{
  struct block_symbol result;

  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);

  symbol_lookup_debug_printf ("lookup_symbol_in_objfile (%s, %s, %s, %s)",
			      objfile_debug_name (objfile),
			      block_index == GLOBAL_BLOCK
			      ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
			      name, domain_name (domain).c_str ());

  result = lookup_symbol_in_objfile_symtabs (objfile, block_index,
					     name, domain);
  if (result.symbol != NULL)
    {
      symbol_lookup_debug_printf
	("lookup_symbol_in_objfile (...) = %s (in symtabs)",
	 host_address_to_string (result.symbol));
      return result;
    }

  result = lookup_symbol_via_quick_fns (objfile, block_index,
					name, domain);
  symbol_lookup_debug_printf ("lookup_symbol_in_objfile (...) = %s%s",
			      result.symbol != NULL
			      ? host_address_to_string (result.symbol)
			      : "NULL",
			      result.symbol != NULL ? " (via quick fns)"
			      : "");
  return result;
}

/* This function contains the common code of lookup_{global,static}_symbol.
   OBJFILE is only used if BLOCK_INDEX is GLOBAL_SCOPE, in which case it is
   the objfile to start the lookup in.  */

static struct block_symbol
lookup_global_or_static_symbol (const char *name,
				enum block_enum block_index,
				struct objfile *objfile,
				const domain_search_flags domain)
{
  struct symbol_cache *cache = get_symbol_cache (current_program_space);
  struct block_symbol result;
  struct block_symbol_cache *bsc;
  struct symbol_cache_slot *slot;

  gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
  gdb_assert (objfile == nullptr || block_index == GLOBAL_BLOCK);

  /* First see if we can find the symbol in the cache.
     This works because we use the current objfile to qualify the lookup.  */
  result = symbol_cache_lookup (cache, objfile, block_index, name, domain,
				&bsc, &slot);
  if (result.symbol != NULL)
    {
      if (SYMBOL_LOOKUP_FAILED_P (result))
	return {};
      return result;
    }

  enter_symbol_lookup tmp;

  /* Do a global search (of global blocks, heh).  */
  if (result.symbol == NULL)
    gdbarch_iterate_over_objfiles_in_search_order
      (objfile != NULL ? objfile->arch () : current_inferior ()->arch (),
       [&result, block_index, name, domain] (struct objfile *objfile_iter)
	 {
	   result = lookup_symbol_in_objfile (objfile_iter, block_index,
					      name, domain);
	   return result.symbol != nullptr;
	 },
       objfile);

  if (result.symbol != NULL)
    symbol_cache_mark_found (bsc, slot, objfile, result.symbol, result.block,
			     domain);
  else
    symbol_cache_mark_not_found (bsc, slot, objfile, name, domain);

  return result;
}

/* See symtab.h.  */

struct block_symbol
lookup_static_symbol (const char *name, const domain_search_flags domain)
{
  return lookup_global_or_static_symbol (name, STATIC_BLOCK, nullptr, domain);
}

/* See symtab.h.  */

struct block_symbol
lookup_global_symbol (const char *name,
		      const struct block *block,
		      const domain_search_flags domain)
{
  /* If a block was passed in, we want to search the corresponding
     global block first.  This yields "more expected" behavior, and is
     needed to support 'FILENAME'::VARIABLE lookups.  */
  const struct block *global_block
    = block == nullptr ? nullptr : block->global_block ();
  symbol *sym = NULL;
  if (global_block != nullptr)
    {
      sym = lookup_symbol_in_block (name,
				    symbol_name_match_type::FULL,
				    global_block, domain);
      if (sym != NULL && best_symbol (sym, domain))
	return { sym, global_block };
    }

  struct objfile *objfile = nullptr;
  if (block != nullptr)
    {
      objfile = block->objfile ();
      if (objfile->separate_debug_objfile_backlink != nullptr)
	objfile = objfile->separate_debug_objfile_backlink;
    }

  block_symbol bs
    = lookup_global_or_static_symbol (name, GLOBAL_BLOCK, objfile, domain);
  if (better_symbol (sym, bs.symbol, domain) == sym)
    return { sym, global_block };
  else
    return bs;
}

/* See symtab.h.  */

bool
symbol::matches (domain_search_flags flags) const
{
  /* C++ has a typedef for every tag, and the types are in the struct
     domain.  */
  if (language () == language_cplus && (flags & SEARCH_TYPE_DOMAIN) != 0)
    flags |= SEARCH_STRUCT_DOMAIN;

  return search_flags_matches (flags, m_domain);
}

/* See symtab.h.  */

struct type *
lookup_transparent_type (const char *name, domain_search_flags flags)
{
  return current_language->lookup_transparent_type (name, flags);
}

/* A helper for basic_lookup_transparent_type that interfaces with the
   "quick" symbol table functions.  */

static struct type *
basic_lookup_transparent_type_quick (struct objfile *objfile,
				     enum block_enum block_index,
				     domain_search_flags flags,
				     const lookup_name_info &name)
{
  struct compunit_symtab *cust;
  const struct blockvector *bv;
  const struct block *block;
  struct symbol *sym;

  cust = objfile->lookup_symbol (block_index, name, flags);
  if (cust == NULL)
    return NULL;

  bv = cust->blockvector ();
  block = bv->block (block_index);

  sym = block_find_symbol (block, name, flags, nullptr);
  if (sym == nullptr)
    error_in_psymtab_expansion (block_index, name.c_str (), cust);
  gdb_assert (!TYPE_IS_OPAQUE (sym->type ()));
  return sym->type ();
}

/* Subroutine of basic_lookup_transparent_type to simplify it.
   Look up the non-opaque definition of NAME in BLOCK_INDEX of OBJFILE.
   BLOCK_INDEX is either GLOBAL_BLOCK or STATIC_BLOCK.  */

static struct type *
basic_lookup_transparent_type_1 (struct objfile *objfile,
				 enum block_enum block_index,
				 domain_search_flags flags,
				 const lookup_name_info &name)
{
  const struct blockvector *bv;
  const struct block *block;
  const struct symbol *sym;

  for (compunit_symtab *cust : objfile->compunits ())
    {
      bv = cust->blockvector ();
      block = bv->block (block_index);
      sym = block_find_symbol (block, name, flags, nullptr);
      if (sym != nullptr)
	{
	  gdb_assert (!TYPE_IS_OPAQUE (sym->type ()));
	  return sym->type ();
	}
    }

  return NULL;
}

/* The standard implementation of lookup_transparent_type.  This code
   was modeled on lookup_symbol -- the parts not relevant to looking
   up types were just left out.  In particular it's assumed here that
   types are available in STRUCT_DOMAIN and only in file-static or
   global blocks.  */

struct type *
basic_lookup_transparent_type (const char *name, domain_search_flags flags)
{
  struct type *t;

  lookup_name_info lookup_name (name, symbol_name_match_type::FULL);

  /* Now search all the global symbols.  Do the symtab's first, then
     check the psymtab's.  If a psymtab indicates the existence
     of the desired name as a global, then do psymtab-to-symtab
     conversion on the fly and return the found symbol.  */

  for (objfile *objfile : current_program_space->objfiles ())
    {
      t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK,
					   flags, lookup_name);
      if (t)
	return t;
    }

  for (objfile *objfile : current_program_space->objfiles ())
    {
      t = basic_lookup_transparent_type_quick (objfile, GLOBAL_BLOCK,
					       flags, lookup_name);
      if (t)
	return t;
    }

  /* Now search the static file-level symbols.
     Not strictly correct, but more useful than an error.
     Do the symtab's first, then
     check the psymtab's.  If a psymtab indicates the existence
     of the desired name as a file-level static, then do psymtab-to-symtab
     conversion on the fly and return the found symbol.  */

  for (objfile *objfile : current_program_space->objfiles ())
    {
      t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK,
					   flags, lookup_name);
      if (t)
	return t;
    }

  for (objfile *objfile : current_program_space->objfiles ())
    {
      t = basic_lookup_transparent_type_quick (objfile, STATIC_BLOCK,
					       flags, lookup_name);
      if (t)
	return t;
    }

  return (struct type *) 0;
}

/* See symtab.h.  */

bool
iterate_over_symbols (const struct block *block,
		      const lookup_name_info &name,
		      const domain_search_flags domain,
		      gdb::function_view<symbol_found_callback_ftype> callback)
{
  for (struct symbol *sym : block_iterator_range (block, &name))
    {
      if (sym->matches (domain))
	{
	  struct block_symbol block_sym = {sym, block};

	  if (!callback (&block_sym))
	    return false;
	}
    }
  return true;
}

/* See symtab.h.  */

bool
iterate_over_symbols_terminated
  (const struct block *block,
   const lookup_name_info &name,
   const domain_search_flags domain,
   gdb::function_view<symbol_found_callback_ftype> callback)
{
  if (!iterate_over_symbols (block, name, domain, callback))
    return false;
  struct block_symbol block_sym = {nullptr, block};
  return callback (&block_sym);
}

/* Find the compunit symtab associated with PC and SECTION.
   This will read in debug info as necessary.  */

struct compunit_symtab *
find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
{
  struct compunit_symtab *best_cust = NULL;
  CORE_ADDR best_cust_range = 0;

  /* If we know that this is not a text address, return failure.  This is
     necessary because we loop based on the block's high and low code
     addresses, which do not include the data ranges, and because
     we call find_pc_sect_psymtab which has a similar restriction based
     on the partial_symtab's texthigh and textlow.  */
  bound_minimal_symbol msymbol
    = lookup_minimal_symbol_by_pc_section (pc, section);
  if (msymbol.minsym && msymbol.minsym->data_p ())
    return NULL;

  /* Search all symtabs for the one whose file contains our address, and which
     is the smallest of all the ones containing the address.  This is designed
     to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000
     and symtab b is at 0x2000-0x3000.  So the GLOBAL_BLOCK for a is from
     0x1000-0x4000, but for address 0x2345 we want to return symtab b.

     This happens for native ecoff format, where code from included files
     gets its own symtab.  The symtab for the included file should have
     been read in already via the dependency mechanism.
     It might be swifter to create several symtabs with the same name
     like xcoff does (I'm not sure).

     It also happens for objfiles that have their functions reordered.
     For these, the symtab we are looking for is not necessarily read in.  */

  for (objfile *obj_file : current_program_space->objfiles ())
    {
      for (compunit_symtab *cust : obj_file->compunits ())
	{
	  const struct blockvector *bv = cust->blockvector ();
	  const struct block *global_block = bv->global_block ();
	  CORE_ADDR start = global_block->start ();
	  CORE_ADDR end = global_block->end ();
	  bool in_range_p = start <= pc && pc < end;
	  if (!in_range_p)
	    continue;

	  if (bv->map () != nullptr)
	    {
	      if (bv->map ()->find (pc) == nullptr)
		continue;

	      return cust;
	    }

	  CORE_ADDR range = end - start;
	  if (best_cust != nullptr
	      && range >= best_cust_range)
	    /* Cust doesn't have a smaller range than best_cust, skip it.  */
	    continue;
	
	  /* For an objfile that has its functions reordered,
	     find_pc_psymtab will find the proper partial symbol table
	     and we simply return its corresponding symtab.  */
	  /* In order to better support objfiles that contain both
	     stabs and coff debugging info, we continue on if a psymtab
	     can't be found.  */
	  struct compunit_symtab *result
	    = obj_file->find_pc_sect_compunit_symtab (msymbol, pc,
						      section, 0);
	  if (result != nullptr)
	    return result;

	  if (section != 0)
	    {
	      struct symbol *found_sym = nullptr;

	      for (int b_index = GLOBAL_BLOCK;
		   b_index <= STATIC_BLOCK && found_sym == nullptr;
		   ++b_index)
		{
		  const struct block *b = bv->block (b_index);
		  for (struct symbol *sym : block_iterator_range (b))
		    {
		      if (matching_obj_sections (sym->obj_section (obj_file),
						 section))
			{
			  found_sym = sym;
			  break;
			}
		    }
		}
	      if (found_sym == nullptr)
		continue;		/* No symbol in this symtab matches
					   section.  */
	    }

	  /* Cust is best found so far, save it.  */
	  best_cust = cust;
	  best_cust_range = range;
	}
    }

  if (best_cust != NULL)
    return best_cust;

  /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs).  */

  for (objfile *objf : current_program_space->objfiles ())
    {
      struct compunit_symtab *result
	= objf->find_pc_sect_compunit_symtab (msymbol, pc, section, 1);
      if (result != NULL)
	return result;
    }

  return NULL;
}

/* Find the compunit symtab associated with PC.
   This will read in debug info as necessary.
   Backward compatibility, no section.  */

struct compunit_symtab *
find_pc_compunit_symtab (CORE_ADDR pc)
{
  return find_pc_sect_compunit_symtab (pc, find_pc_mapped_section (pc));
}

/* See symtab.h.  */

struct symbol *
find_symbol_at_address (CORE_ADDR address)
{
  /* A helper function to search a given symtab for a symbol matching
     ADDR.  */
  auto search_symtab = [] (compunit_symtab *symtab, CORE_ADDR addr) -> symbol *
    {
      const struct blockvector *bv = symtab->blockvector ();

      for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
	{
	  const struct block *b = bv->block (i);

	  for (struct symbol *sym : block_iterator_range (b))
	    {
	      if (sym->aclass () == LOC_STATIC
		  && sym->value_address () == addr)
		return sym;
	    }
	}
      return nullptr;
    };

  for (objfile *objfile : current_program_space->objfiles ())
    {
      /* If this objfile was read with -readnow, then we need to
	 search the symtabs directly.  */
      if ((objfile->flags & OBJF_READNOW) != 0)
	{
	  for (compunit_symtab *symtab : objfile->compunits ())
	    {
	      struct symbol *sym = search_symtab (symtab, address);
	      if (sym != nullptr)
		return sym;
	    }
	}
      else
	{
	  struct compunit_symtab *symtab
	    = objfile->find_compunit_symtab_by_address (address);
	  if (symtab != NULL)
	    {
	      struct symbol *sym = search_symtab (symtab, address);
	      if (sym != nullptr)
		return sym;
	    }
	}
    }

  return NULL;
}



/* Find the source file and line number for a given PC value and SECTION.
   Return a structure containing a symtab pointer, a line number,
   and a pc range for the entire source line.
   The value's .pc field is NOT the specified pc.
   NOTCURRENT nonzero means, if specified pc is on a line boundary,
   use the line that ends there.  Otherwise, in that case, the line
   that begins there is used.  */

/* The big complication here is that a line may start in one file, and end just
   before the start of another file.  This usually occurs when you #include
   code in the middle of a subroutine.  To properly find the end of a line's PC
   range, we must search all symtabs associated with this compilation unit, and
   find the one whose first PC is closer than that of the next line in this
   symtab.  */

struct symtab_and_line
find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
{
  struct compunit_symtab *cust;
  const linetable *l;
  int len;
  const linetable_entry *item;
  const struct blockvector *bv;

  /* Info on best line seen so far, and where it starts, and its file.  */

  const linetable_entry *best = NULL;
  CORE_ADDR best_end = 0;
  struct symtab *best_symtab = 0;

  /* Store here the first line number
     of a file which contains the line at the smallest pc after PC.
     If we don't find a line whose range contains PC,
     we will use a line one less than this,
     with a range from the start of that file to the first line's pc.  */
  const linetable_entry *alt = NULL;

  /* Info on best line seen in this file.  */

  const linetable_entry *prev;

  /* If this pc is not from the current frame,
     it is the address of the end of a call instruction.
     Quite likely that is the start of the following statement.
     But what we want is the statement containing the instruction.
     Fudge the pc to make sure we get that.  */

  /* It's tempting to assume that, if we can't find debugging info for
     any function enclosing PC, that we shouldn't search for line
     number info, either.  However, GAS can emit line number info for
     assembly files --- very helpful when debugging hand-written
     assembly code.  In such a case, we'd have no debug info for the
     function, but we would have line info.  */

  if (notcurrent)
    pc -= 1;

  /* elz: added this because this function returned the wrong
     information if the pc belongs to a stub (import/export)
     to call a shlib function.  This stub would be anywhere between
     two functions in the target, and the line info was erroneously
     taken to be the one of the line before the pc.  */

  /* RT: Further explanation:

   * We have stubs (trampolines) inserted between procedures.
   *
   * Example: "shr1" exists in a shared library, and a "shr1" stub also
   * exists in the main image.
   *
   * In the minimal symbol table, we have a bunch of symbols
   * sorted by start address.  The stubs are marked as "trampoline",
   * the others appear as text. E.g.:
   *
   *  Minimal symbol table for main image
   *     main:  code for main (text symbol)
   *     shr1: stub  (trampoline symbol)
   *     foo:   code for foo (text symbol)
   *     ...
   *  Minimal symbol table for "shr1" image:
   *     ...
   *     shr1: code for shr1 (text symbol)
   *     ...
   *
   * So the code below is trying to detect if we are in the stub
   * ("shr1" stub), and if so, find the real code ("shr1" trampoline),
   * and if found,  do the symbolization from the real-code address
   * rather than the stub address.
   *
   * Assumptions being made about the minimal symbol table:
   *   1. lookup_minimal_symbol_by_pc() will return a trampoline only
   *      if we're really in the trampoline.s If we're beyond it (say
   *      we're in "foo" in the above example), it'll have a closer
   *      symbol (the "foo" text symbol for example) and will not
   *      return the trampoline.
   *   2. lookup_minimal_symbol_text() will find a real text symbol
   *      corresponding to the trampoline, and whose address will
   *      be different than the trampoline address.  I put in a sanity
   *      check for the address being the same, to avoid an
   *      infinite recursion.
   */
  bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
  if (msymbol.minsym != NULL)
    if (msymbol.minsym->type () == mst_solib_trampoline)
      {
	bound_minimal_symbol mfunsym
	  = lookup_minimal_symbol_text (current_program_space,
					msymbol.minsym->linkage_name (),
					nullptr);

	if (mfunsym.minsym == NULL)
	  /* I eliminated this warning since it is coming out
	   * in the following situation:
	   * gdb shmain // test program with shared libraries
	   * (gdb) break shr1  // function in shared lib
	   * Warning: In stub for ...
	   * In the above situation, the shared lib is not loaded yet,
	   * so of course we can't find the real func/line info,
	   * but the "break" still works, and the warning is annoying.
	   * So I commented out the warning.  RT */
	  /* warning ("In stub for %s; unable to find real function/line info",
	     msymbol->linkage_name ()); */
	  ;
	/* fall through */
	else if (mfunsym.value_address ()
		 == msymbol.value_address ())
	  /* Avoid infinite recursion */
	  /* See above comment about why warning is commented out.  */
	  /* warning ("In stub for %s; unable to find real function/line info",
	     msymbol->linkage_name ()); */
	  ;
	/* fall through */
	else
	  {
	    /* Detect an obvious case of infinite recursion.  If this
	       should occur, we'd like to know about it, so error out,
	       fatally.  */
	    if (mfunsym.value_address () == pc)
	      internal_error (_("Infinite recursion detected in find_pc_sect_line;"
		  "please file a bug report"));

	    return find_pc_line (mfunsym.value_address (), 0);
	  }
      }

  symtab_and_line val;
  val.pspace = current_program_space;

  cust = find_pc_sect_compunit_symtab (pc, section);
  if (cust == NULL)
    {
      /* If no symbol information, return previous pc.  */
      if (notcurrent)
	pc++;
      val.pc = pc;
      return val;
    }

  bv = cust->blockvector ();
  struct objfile *objfile = cust->objfile ();

  /* Look at all the symtabs that share this blockvector.
     They all have the same apriori range, that we found was right;
     but they have different line tables.  */

  for (symtab *iter_s : cust->filetabs ())
    {
      /* Find the best line in this symtab.  */
      l = iter_s->linetable ();
      if (!l)
	continue;
      len = l->nitems;
      if (len <= 0)
	{
	  /* I think len can be zero if the symtab lacks line numbers
	     (e.g. gcc -g1).  (Either that or the LINETABLE is NULL;
	     I'm not sure which, and maybe it depends on the symbol
	     reader).  */
	  continue;
	}

      prev = NULL;
      item = l->item;		/* Get first line info.  */

      /* Is this file's first line closer than the first lines of other files?
	 If so, record this file, and its first line, as best alternate.  */
      if (item->pc (objfile) > pc
	  && (!alt || item->unrelocated_pc () < alt->unrelocated_pc ()))
	alt = item;

      auto pc_compare = [] (const unrelocated_addr &comp_pc,
			    const struct linetable_entry & lhs)
      {
	return comp_pc < lhs.unrelocated_pc ();
      };

      const linetable_entry *first = item;
      const linetable_entry *last = item + len;
      item = (std::upper_bound
	      (first, last,
	       unrelocated_addr (pc - objfile->text_section_offset ()),
	       pc_compare));
      if (item != first)
	{
	  prev = item - 1;		/* Found a matching item.  */
	  /* At this point, prev is a line whose address is <= pc.  However, we
	     don't know if ITEM is pointing to the same statement or not.  */
	  while (item != last && prev->line == item->line && !item->is_stmt)
	    item++;
	}

      /* At this point, prev points at the line whose start addr is <= pc, and
	 item points at the next statement.  If we ran off the end of the linetable
	 (pc >= start of the last line), then prev == item.  If pc < start of
	 the first line, prev will not be set.  */

      /* Is this file's best line closer than the best in the other files?
	 If so, record this file, and its best line, as best so far.  Don't
	 save prev if it represents the end of a function (i.e. line number
	 0) instead of a real line.  */

      if (prev && prev->line
	  && (!best || prev->unrelocated_pc () > best->unrelocated_pc ()))
	{
	  best = prev;
	  best_symtab = iter_s;

	  /* If during the binary search we land on a non-statement entry,
	     scan backward through entries at the same address to see if
	     there is an entry marked as is-statement.  In theory this
	     duplication should have been removed from the line table
	     during construction, this is just a double check.  If the line
	     table has had the duplication removed then this should be
	     pretty cheap.  */
	  if (!best->is_stmt)
	    {
	      const linetable_entry *tmp = best;
	      while (tmp > first
		     && (tmp - 1)->unrelocated_pc () == tmp->unrelocated_pc ()
		     && (tmp - 1)->line != 0 && !tmp->is_stmt)
		--tmp;
	      if (tmp->is_stmt)
		best = tmp;
	    }

	  /* Discard BEST_END if it's before the PC of the current BEST.  */
	  if (best_end <= best->pc (objfile))
	    best_end = 0;
	}

      /* If another line (denoted by ITEM) is in the linetable and its
	 PC is after BEST's PC, but before the current BEST_END, then
	 use ITEM's PC as the new best_end.  */
      if (best && item < last
	  && item->unrelocated_pc () > best->unrelocated_pc ()
	  && (best_end == 0 || best_end > item->pc (objfile)))
	best_end = item->pc (objfile);
    }

  if (!best_symtab)
    {
      /* If we didn't find any line number info, just return zeros.
	 We used to return alt->line - 1 here, but that could be
	 anywhere; if we don't have line number info for this PC,
	 don't make some up.  */
      val.pc = pc;
    }
  else if (best->line == 0)
    {
      /* If our best fit is in a range of PC's for which no line
	 number info is available (line number is zero) then we didn't
	 find any valid line information.  */
      val.pc = pc;
    }
  else
    {
      val.is_stmt = best->is_stmt;
      val.symtab = best_symtab;
      val.line = best->line;
      val.pc = best->pc (objfile);
      if (best_end && (!alt || best_end < alt->pc (objfile)))
	val.end = best_end;
      else if (alt)
	val.end = alt->pc (objfile);
      else
	val.end = bv->global_block ()->end ();
    }
  val.section = section;
  return val;
}

/* Backward compatibility (no section).  */

struct symtab_and_line
find_pc_line (CORE_ADDR pc, int notcurrent)
{
  struct obj_section *section;

  section = find_pc_overlay (pc);
  if (!pc_in_unmapped_range (pc, section))
    return find_pc_sect_line (pc, section, notcurrent);

  /* If the original PC was an unmapped address then we translate this to a
     mapped address in order to lookup the sal.  However, as the user
     passed us an unmapped address it makes more sense to return a result
     that has the pc and end fields translated to unmapped addresses.  */
  pc = overlay_mapped_address (pc, section);
  symtab_and_line sal = find_pc_sect_line (pc, section, notcurrent);
  sal.pc = overlay_unmapped_address (sal.pc, section);
  sal.end = overlay_unmapped_address (sal.end, section);
  return sal;
}

/* Compare two symtab_and_line entries.  Return true if both have
   the same line number and the same symtab pointer.  That means we
   are dealing with two entries from the same line and from the same
   source file.

   Return false otherwise.  */

static bool
sal_line_symtab_matches_p (const symtab_and_line &sal1,
			   const symtab_and_line &sal2)
{
  return sal1.line == sal2.line && sal1.symtab == sal2.symtab;
}

/* See symtah.h.  */

std::optional<CORE_ADDR>
find_line_range_start (CORE_ADDR pc)
{
  struct symtab_and_line current_sal = find_pc_line (pc, 0);

  if (current_sal.line == 0)
    return {};

  struct symtab_and_line prev_sal = find_pc_line (current_sal.pc - 1, 0);

  /* If the previous entry is for a different line, that means we are already
     at the entry with the start PC for this line.  */
  if (!sal_line_symtab_matches_p (prev_sal, current_sal))
    return current_sal.pc;

  /* Otherwise, keep looking for entries for the same line but with
     smaller PC's.  */
  bool done = false;
  CORE_ADDR prev_pc;
  while (!done)
    {
      prev_pc = prev_sal.pc;

      prev_sal = find_pc_line (prev_pc - 1, 0);

      /* Did we notice a line change?  If so, we are done searching.  */
      if (!sal_line_symtab_matches_p (prev_sal, current_sal))
	done = true;
    }

  return prev_pc;
}

/* See symtab.h.  */

struct symtab *
find_pc_line_symtab (CORE_ADDR pc)
{
  struct symtab_and_line sal;

  /* This always passes zero for NOTCURRENT to find_pc_line.
     There are currently no callers that ever pass non-zero.  */
  sal = find_pc_line (pc, 0);
  return sal.symtab;
}

/* See symtab.h.  */

symtab *
find_line_symtab (symtab *sym_tab, int line, int *index)
{
  int exact = 0;  /* Initialized here to avoid a compiler warning.  */

  /* BEST_INDEX and BEST_LINETABLE identify the smallest linenumber > LINE
     so far seen.  */

  int best_index;
  const struct linetable *best_linetable;
  struct symtab *best_symtab;

  /* First try looking it up in the given symtab.  */
  best_linetable = sym_tab->linetable ();
  best_symtab = sym_tab;
  best_index = find_line_common (best_linetable, line, &exact, 0);
  if (best_index < 0 || !exact)
    {
      /* Didn't find an exact match.  So we better keep looking for
	 another symtab with the same name.  In the case of xcoff,
	 multiple csects for one source file (produced by IBM's FORTRAN
	 compiler) produce multiple symtabs (this is unavoidable
	 assuming csects can be at arbitrary places in memory and that
	 the GLOBAL_BLOCK of a symtab has a begin and end address).  */

      /* BEST is the smallest linenumber > LINE so far seen,
	 or 0 if none has been seen so far.
	 BEST_INDEX and BEST_LINETABLE identify the item for it.  */
      int best;

      if (best_index >= 0)
	best = best_linetable->item[best_index].line;
      else
	best = 0;

      for (objfile *objfile : current_program_space->objfiles ())
	objfile->expand_symtabs_with_fullname (symtab_to_fullname (sym_tab));

      for (objfile *objfile : current_program_space->objfiles ())
	{
	  for (compunit_symtab *cu : objfile->compunits ())
	    {
	      for (symtab *s : cu->filetabs ())
		{
		  const struct linetable *l;
		  int ind;

		  if (FILENAME_CMP (sym_tab->filename, s->filename) != 0)
		    continue;
		  if (FILENAME_CMP (symtab_to_fullname (sym_tab),
				    symtab_to_fullname (s)) != 0)
		    continue;	
		  l = s->linetable ();
		  ind = find_line_common (l, line, &exact, 0);
		  if (ind >= 0)
		    {
		      if (exact)
			{
			  best_index = ind;
			  best_linetable = l;
			  best_symtab = s;
			  goto done;
			}
		      if (best == 0 || l->item[ind].line < best)
			{
			  best = l->item[ind].line;
			  best_index = ind;
			  best_linetable = l;
			  best_symtab = s;
			}
		    }
		}
	    }
	}
    }
done:
  if (best_index < 0)
    return NULL;

  if (index)
    *index = best_index;

  return best_symtab;
}

/* Given SYMTAB, returns all the PCs function in the symtab that
   exactly match LINE.  Returns an empty vector if there are no exact
   matches, but updates BEST_ITEM in this case.  */

std::vector<CORE_ADDR>
find_pcs_for_symtab_line (struct symtab *symtab, int line,
			  const linetable_entry **best_item)
{
  int start = 0;
  std::vector<CORE_ADDR> result;
  struct objfile *objfile = symtab->compunit ()->objfile ();

  /* First, collect all the PCs that are at this line.  */
  while (1)
    {
      int was_exact;
      int idx;

      idx = find_line_common (symtab->linetable (), line, &was_exact,
			      start);
      if (idx < 0)
	break;

      if (!was_exact)
	{
	  const linetable_entry *item = &symtab->linetable ()->item[idx];

	  if (*best_item == NULL
	      || (item->line < (*best_item)->line && item->is_stmt))
	    *best_item = item;

	  break;
	}

      result.push_back (symtab->linetable ()->item[idx].pc (objfile));
      start = idx + 1;
    }

  return result;
}


/* Set the PC value for a given source file and line number and return true.
   Returns false for invalid line number (and sets the PC to 0).
   The source file is specified with a struct symtab.  */

bool
find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
{
  const struct linetable *l;
  int ind;

  *pc = 0;
  if (symtab == 0)
    return false;

  symtab = find_line_symtab (symtab, line, &ind);
  if (symtab != NULL)
    {
      l = symtab->linetable ();
      *pc = l->item[ind].pc (symtab->compunit ()->objfile ());
      return true;
    }
  else
    return false;
}

/* Find the range of pc values in a line.
   Store the starting pc of the line into *STARTPTR
   and the ending pc (start of next line) into *ENDPTR.
   Returns true to indicate success.
   Returns false if could not find the specified line.  */

bool
find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
		    CORE_ADDR *endptr)
{
  CORE_ADDR startaddr;
  struct symtab_and_line found_sal;

  startaddr = sal.pc;
  if (startaddr == 0 && !find_line_pc (sal.symtab, sal.line, &startaddr))
    return false;

  /* This whole function is based on address.  For example, if line 10 has
     two parts, one from 0x100 to 0x200 and one from 0x300 to 0x400, then
     "info line *0x123" should say the line goes from 0x100 to 0x200
     and "info line *0x355" should say the line goes from 0x300 to 0x400.
     This also insures that we never give a range like "starts at 0x134
     and ends at 0x12c".  */

  found_sal = find_pc_sect_line (startaddr, sal.section, 0);
  if (found_sal.line != sal.line)
    {
      /* The specified line (sal) has zero bytes.  */
      *startptr = found_sal.pc;
      *endptr = found_sal.pc;
    }
  else
    {
      *startptr = found_sal.pc;
      *endptr = found_sal.end;
    }
  return true;
}

/* Given a line table and a line number, return the index into the line
   table for the pc of the nearest line whose number is >= the specified one.
   Return -1 if none is found.  The value is >= 0 if it is an index.
   START is the index at which to start searching the line table.

   Set *EXACT_MATCH nonzero if the value returned is an exact match.  */

static int
find_line_common (const linetable *l, int lineno,
		  int *exact_match, int start)
{
  int i;
  int len;

  /* BEST is the smallest linenumber > LINENO so far seen,
     or 0 if none has been seen so far.
     BEST_INDEX identifies the item for it.  */

  int best_index = -1;
  int best = 0;

  *exact_match = 0;

  if (lineno <= 0)
    return -1;
  if (l == 0)
    return -1;

  len = l->nitems;
  for (i = start; i < len; i++)
    {
      const linetable_entry *item = &(l->item[i]);

      /* Ignore non-statements.  */
      if (!item->is_stmt)
	continue;

      if (item->line == lineno)
	{
	  /* Return the first (lowest address) entry which matches.  */
	  *exact_match = 1;
	  return i;
	}

      if (item->line > lineno && (best == 0 || item->line < best))
	{
	  best = item->line;
	  best_index = i;
	}
    }

  /* If we got here, we didn't get an exact match.  */
  return best_index;
}

bool
find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr)
{
  struct symtab_and_line sal;

  sal = find_pc_line (pc, 0);
  *startptr = sal.pc;
  *endptr = sal.end;
  return sal.symtab != 0;
}

/* Helper for find_function_start_sal.  Does most of the work, except
   setting the sal's symbol.  */

static symtab_and_line
find_function_start_sal_1 (CORE_ADDR func_addr, obj_section *section,
			   bool funfirstline)
{
  symtab_and_line sal = find_pc_sect_line (func_addr, section, 0);

  if (funfirstline && sal.symtab != NULL
      && (sal.symtab->compunit ()->locations_valid ()
	  || sal.symtab->language () == language_asm))
    {
      struct gdbarch *gdbarch = sal.symtab->compunit ()->objfile ()->arch ();

      sal.pc = func_addr;
      if (gdbarch_skip_entrypoint_p (gdbarch))
	sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc);
      return sal;
    }

  /* We always should have a line for the function start address.
     If we don't, something is odd.  Create a plain SAL referring
     just the PC and hope that skip_prologue_sal (if requested)
     can find a line number for after the prologue.  */
  if (sal.pc < func_addr)
    {
      sal = {};
      sal.pspace = current_program_space;
      sal.pc = func_addr;
      sal.section = section;
    }

  if (funfirstline)
    skip_prologue_sal (&sal);

  return sal;
}

/* See symtab.h.  */

symtab_and_line
find_function_start_sal (CORE_ADDR func_addr, obj_section *section,
			 bool funfirstline)
{
  symtab_and_line sal
    = find_function_start_sal_1 (func_addr, section, funfirstline);

  /* find_function_start_sal_1 does a linetable search, so it finds
     the symtab and linenumber, but not a symbol.  Fill in the
     function symbol too.  */
  sal.symbol = find_pc_sect_containing_function (sal.pc, sal.section);

  return sal;
}

/* See symtab.h.  */

symtab_and_line
find_function_start_sal (symbol *sym, bool funfirstline)
{
  symtab_and_line sal
    = find_function_start_sal_1 (sym->value_block ()->entry_pc (),
				 sym->obj_section (sym->objfile ()),
				 funfirstline);
  sal.symbol = sym;
  return sal;
}


/* Given a function start address FUNC_ADDR and SYMTAB, find the first
   address for that function that has an entry in SYMTAB's line info
   table.  If such an entry cannot be found, return FUNC_ADDR
   unaltered.  */

static CORE_ADDR
skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
{
  CORE_ADDR func_start, func_end;
  const struct linetable *l;
  int i;

  /* Give up if this symbol has no lineinfo table.  */
  l = symtab->linetable ();
  if (l == NULL)
    return func_addr;

  /* Get the range for the function's PC values, or give up if we
     cannot, for some reason.  */
  if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end))
    return func_addr;

  struct objfile *objfile = symtab->compunit ()->objfile ();

  /* Linetable entries are ordered by PC values, see the commentary in
     symtab.h where `struct linetable' is defined.  Thus, the first
     entry whose PC is in the range [FUNC_START..FUNC_END[ is the
     address we are looking for.  */
  for (i = 0; i < l->nitems; i++)
    {
      const linetable_entry *item = &(l->item[i]);
      CORE_ADDR item_pc = item->pc (objfile);

      /* Don't use line numbers of zero, they mark special entries in
	 the table.  See the commentary on symtab.h before the
	 definition of struct linetable.  */
      if (item->line > 0 && func_start <= item_pc && item_pc < func_end)
	return item_pc;
    }

  return func_addr;
}

/* Try to locate the address where a breakpoint should be placed past the
   prologue of function starting at FUNC_ADDR using the line table.

   Return the address associated with the first entry in the line-table for
   the function starting at FUNC_ADDR which has prologue_end set to true if
   such entry exist, otherwise return an empty optional.  */

static std::optional<CORE_ADDR>
skip_prologue_using_linetable (CORE_ADDR func_addr)
{
  CORE_ADDR start_pc, end_pc;

  if (!find_pc_partial_function (func_addr, nullptr, &start_pc, &end_pc))
    return {};

  const struct symtab_and_line prologue_sal = find_pc_line (start_pc, 0);
  if (prologue_sal.symtab != nullptr
      && prologue_sal.symtab->language () != language_asm)
    {
      const linetable *linetable = prologue_sal.symtab->linetable ();

      struct objfile *objfile = prologue_sal.symtab->compunit ()->objfile ();

      unrelocated_addr unrel_start
	= unrelocated_addr (start_pc - objfile->text_section_offset ());
      unrelocated_addr unrel_end
	= unrelocated_addr (end_pc - objfile->text_section_offset ());

      auto it = std::lower_bound
	(linetable->item, linetable->item + linetable->nitems, unrel_start,
	 [] (const linetable_entry &lte, unrelocated_addr pc)
	 {
	   return lte.unrelocated_pc () < pc;
	 });

      for (;
	   (it < linetable->item + linetable->nitems
	    && it->unrelocated_pc () < unrel_end);
	   it++)
	if (it->prologue_end)
	  return {it->pc (objfile)};
    }

  return {};
}

/* Adjust SAL to the first instruction past the function prologue.
   If the PC was explicitly specified, the SAL is not changed.
   If the line number was explicitly specified then the SAL can still be
   updated, unless the language for SAL is assembler, in which case the SAL
   will be left unchanged.
   If SAL is already past the prologue, then do nothing.  */

void
skip_prologue_sal (struct symtab_and_line *sal)
{
  struct symbol *sym;
  struct symtab_and_line start_sal;
  CORE_ADDR pc, saved_pc;
  struct obj_section *section;
  const char *name;
  struct objfile *objfile;
  struct gdbarch *gdbarch;
  const struct block *b, *function_block;
  int force_skip, skip;

  /* Do not change the SAL if PC was specified explicitly.  */
  if (sal->explicit_pc)
    return;

  /* In assembly code, if the user asks for a specific line then we should
     not adjust the SAL.  The user already has instruction level
     visibility in this case, so selecting a line other than one requested
     is likely to be the wrong choice.  */
  if (sal->symtab != nullptr
      && sal->explicit_line
      && sal->symtab->language () == language_asm)
    return;

  scoped_restore_current_pspace_and_thread restore_pspace_thread;

  switch_to_program_space_and_thread (sal->pspace);

  sym = find_pc_sect_function (sal->pc, sal->section);
  if (sym != NULL)
    {
      objfile = sym->objfile ();
      pc = sym->value_block ()->entry_pc ();
      section = sym->obj_section (objfile);
      name = sym->linkage_name ();
    }
  else
    {
      bound_minimal_symbol msymbol
	= lookup_minimal_symbol_by_pc_section (sal->pc, sal->section);

      if (msymbol.minsym == NULL)
	return;

      objfile = msymbol.objfile;
      pc = msymbol.value_address ();
      section = msymbol.minsym->obj_section (objfile);
      name = msymbol.minsym->linkage_name ();
    }

  gdbarch = objfile->arch ();

  /* Process the prologue in two passes.  In the first pass try to skip the
     prologue (SKIP is true) and verify there is a real need for it (indicated
     by FORCE_SKIP).  If no such reason was found run a second pass where the
     prologue is not skipped (SKIP is false).  */

  skip = 1;
  force_skip = 1;

  /* Be conservative - allow direct PC (without skipping prologue) only if we
     have proven the CU (Compilation Unit) supports it.  sal->SYMTAB does not
     have to be set by the caller so we use SYM instead.  */
  if (sym != NULL
      && sym->symtab ()->compunit ()->locations_valid ())
    force_skip = 0;

  saved_pc = pc;
  do
    {
      pc = saved_pc;

      /* Check if the compiler explicitly indicated where a breakpoint should
	 be placed to skip the prologue.  */
      if (!ignore_prologue_end_flag && skip)
	{
	  std::optional<CORE_ADDR> linetable_pc
	    = skip_prologue_using_linetable (pc);
	  if (linetable_pc)
	    {
	      pc = *linetable_pc;
	      start_sal = find_pc_sect_line (pc, section, 0);
	      force_skip = 1;
	      continue;
	    }
	}

      /* If the function is in an unmapped overlay, use its unmapped LMA address,
	 so that gdbarch_skip_prologue has something unique to work on.  */
      if (section_is_overlay (section) && !section_is_mapped (section))
	pc = overlay_unmapped_address (pc, section);

      /* Skip "first line" of function (which is actually its prologue).  */
      pc += gdbarch_deprecated_function_start_offset (gdbarch);
      if (gdbarch_skip_entrypoint_p (gdbarch))
	pc = gdbarch_skip_entrypoint (gdbarch, pc);
      if (skip)
	pc = gdbarch_skip_prologue_noexcept (gdbarch, pc);

      /* For overlays, map pc back into its mapped VMA range.  */
      pc = overlay_mapped_address (pc, section);

      /* Calculate line number.  */
      start_sal = find_pc_sect_line (pc, section, 0);

      /* Check if gdbarch_skip_prologue left us in mid-line, and the next
	 line is still part of the same function.  */
      if (skip && start_sal.pc != pc
	  && (sym ? (sym->value_block ()->entry_pc () <= start_sal.end
		     && start_sal.end < sym->value_block()->end ())
	      : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym
		 == lookup_minimal_symbol_by_pc_section (pc, section).minsym)))
	{
	  /* First pc of next line */
	  pc = start_sal.end;
	  /* Recalculate the line number (might not be N+1).  */
	  start_sal = find_pc_sect_line (pc, section, 0);
	}

      /* On targets with executable formats that don't have a concept of
	 constructors (ELF with .init has, PE doesn't), gcc emits a call
	 to `__main' in `main' between the prologue and before user
	 code.  */
      if (gdbarch_skip_main_prologue_p (gdbarch)
	  && name && strcmp_iw (name, "main") == 0)
	{
	  pc = gdbarch_skip_main_prologue (gdbarch, pc);
	  /* Recalculate the line number (might not be N+1).  */
	  start_sal = find_pc_sect_line (pc, section, 0);
	  force_skip = 1;
	}
    }
  while (!force_skip && skip--);

  /* If we still don't have a valid source line, try to find the first
     PC in the lineinfo table that belongs to the same function.  This
     happens with COFF debug info, which does not seem to have an
     entry in lineinfo table for the code after the prologue which has
     no direct relation to source.  For example, this was found to be
     the case with the DJGPP target using "gcc -gcoff" when the
     compiler inserted code after the prologue to make sure the stack
     is aligned.  */
  if (!force_skip && sym && start_sal.symtab == NULL)
    {
      pc = skip_prologue_using_lineinfo (pc, sym->symtab ());
      /* Recalculate the line number.  */
      start_sal = find_pc_sect_line (pc, section, 0);
    }

  /* If we're already past the prologue, leave SAL unchanged.  Otherwise
     forward SAL to the end of the prologue.  */
  if (sal->pc >= pc)
    return;

  sal->pc = pc;
  sal->section = section;
  sal->symtab = start_sal.symtab;
  sal->line = start_sal.line;
  sal->end = start_sal.end;

  /* Check if we are now inside an inlined function.  If we can,
     use the call site of the function instead.  */
  b = block_for_pc_sect (sal->pc, sal->section);
  function_block = NULL;
  while (b != NULL)
    {
      if (b->function () != NULL && b->inlined_p ())
	function_block = b;
      else if (b->function () != NULL)
	break;
      b = b->superblock ();
    }
  if (function_block != NULL
      && function_block->function ()->line () != 0)
    {
      sal->line = function_block->function ()->line ();
      sal->symtab = function_block->function ()->symtab ();
    }
}

/* Given PC at the function's start address, attempt to find the
   prologue end using SAL information.  Return zero if the skip fails.

   A non-optimized prologue traditionally has one SAL for the function
   and a second for the function body.  A single line function has
   them both pointing at the same line.

   An optimized prologue is similar but the prologue may contain
   instructions (SALs) from the instruction body.  Need to skip those
   while not getting into the function body.

   The functions end point and an increasing SAL line are used as
   indicators of the prologue's endpoint.

   This code is based on the function refine_prologue_limit
   (found in ia64).  */

CORE_ADDR
skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
{
  struct symtab_and_line prologue_sal;
  CORE_ADDR start_pc;
  CORE_ADDR end_pc;
  const struct block *bl;

  /* Get an initial range for the function.  */
  find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
  start_pc += gdbarch_deprecated_function_start_offset (gdbarch);

  prologue_sal = find_pc_line (start_pc, 0);
  if (prologue_sal.line != 0)
    {
      /* For languages other than assembly, treat two consecutive line
	 entries at the same address as a zero-instruction prologue.
	 The GNU assembler emits separate line notes for each instruction
	 in a multi-instruction macro, but compilers generally will not
	 do this.  */
      if (prologue_sal.symtab->language () != language_asm)
	{
	  struct objfile *objfile
	    = prologue_sal.symtab->compunit ()->objfile ();
	  const linetable *linetable = prologue_sal.symtab->linetable ();
	  gdb_assert (linetable->nitems > 0);
	  int idx = 0;

	  /* Skip any earlier lines, and any end-of-sequence marker
	     from a previous function.  */
	  while (idx + 1 < linetable->nitems
		 && (linetable->item[idx].pc (objfile) != prologue_sal.pc
		     || linetable->item[idx].line == 0))
	    idx++;

	  if (idx + 1 < linetable->nitems
	      && linetable->item[idx+1].line != 0
	      && linetable->item[idx+1].pc (objfile) == start_pc)
	    return start_pc;
	}

      /* If there is only one sal that covers the entire function,
	 then it is probably a single line function, like
	 "foo(){}".  */
      if (prologue_sal.end >= end_pc)
	return 0;

      while (prologue_sal.end < end_pc)
	{
	  struct symtab_and_line sal;

	  sal = find_pc_line (prologue_sal.end, 0);
	  if (sal.line == 0)
	    break;
	  /* Assume that a consecutive SAL for the same (or larger)
	     line mark the prologue -> body transition.  */
	  if (sal.line >= prologue_sal.line)
	    break;
	  /* Likewise if we are in a different symtab altogether
	     (e.g. within a file included via #include).  */
	  if (sal.symtab != prologue_sal.symtab)
	    break;

	  /* The line number is smaller.  Check that it's from the
	     same function, not something inlined.  If it's inlined,
	     then there is no point comparing the line numbers.  */
	  bl = block_for_pc (prologue_sal.end);
	  while (bl)
	    {
	      if (bl->inlined_p ())
		break;
	      if (bl->function ())
		{
		  bl = NULL;
		  break;
		}
	      bl = bl->superblock ();
	    }
	  if (bl != NULL)
	    break;

	  /* The case in which compiler's optimizer/scheduler has
	     moved instructions into the prologue.  We look ahead in
	     the function looking for address ranges whose
	     corresponding line number is less the first one that we
	     found for the function.  This is more conservative then
	     refine_prologue_limit which scans a large number of SALs
	     looking for any in the prologue.  */
	  prologue_sal = sal;
	}
    }

  if (prologue_sal.end < end_pc)
    /* Return the end of this line, or zero if we could not find a
       line.  */
    return prologue_sal.end;
  else
    /* Don't return END_PC, which is past the end of the function.  */
    return prologue_sal.pc;
}

/* See symtab.h.  */

std::optional<CORE_ADDR>
find_epilogue_using_linetable (CORE_ADDR func_addr)
{
  CORE_ADDR start_pc, end_pc;

  if (!find_pc_partial_function (func_addr, nullptr, &start_pc, &end_pc))
    return {};

  /* While the standard allows for multiple points marked with epilogue_begin
     in the same function, for performance reasons, this function will only
     find the last address that sets this flag for a given block.

     The lines of a function can be described by several line tables in case
     there are different files involved.  There's a corner case where a
     function epilogue is in a different file than a function start, and using
     start_pc as argument to find_pc_line will mean we won't find the
     epilogue.  Instead, use "end_pc - 1" to maximize our chances of picking
     the line table containing an epilogue.  */
  const struct symtab_and_line sal = find_pc_line (end_pc - 1, 0);
  if (sal.symtab != nullptr && sal.symtab->language () != language_asm)
    {
      struct objfile *objfile = sal.symtab->compunit ()->objfile ();
      unrelocated_addr unrel_start
	= unrelocated_addr (start_pc - objfile->text_section_offset ());
      unrelocated_addr unrel_end
	= unrelocated_addr (end_pc - objfile->text_section_offset ());

      const linetable *linetable = sal.symtab->linetable ();
      if (linetable == nullptr || linetable->nitems == 0)
	{
	  /* Empty line table.  */
	  return {};
	}

      /* Find the first linetable entry after the current function.  Note that
	 this also may be an end_sequence entry.  */
      auto it = std::lower_bound
	(linetable->item, linetable->item + linetable->nitems, unrel_end,
	 [] (const linetable_entry &lte, unrelocated_addr pc)
	 {
	   return lte.unrelocated_pc () < pc;
	 });
      if (it == linetable->item + linetable->nitems)
	{
	  /* We couldn't find either:
	     - a linetable entry starting the function after the current
	       function, or
	     - an end_sequence entry that terminates the current function
	       at unrel_end.

	     This can happen when the linetable doesn't describe the full
	     extent of the function.  This can be triggered with:
	     - compiler-generated debug info, in the cornercase that the pc
	       with which we call find_pc_line resides in a different file
	       than unrel_end, or
	     - invalid dwarf assembly debug info.
	     In the former case, there's no point in iterating further, simply
	     return "not found".  In the latter case, there's no current
	     incentive to attempt to support this, so handle this
	     conservatively and do the same.  */
	  return {};
	}

      if (unrel_end < it->unrelocated_pc ())
	{
	  /* We found a line entry that starts past the end of the
	     function.  This can happen if the previous entry straddles
	     two functions, which shouldn't happen with compiler-generated
	     debug info.  Handle the corner case conservatively.  */
	  return {};
	}
      gdb_assert (unrel_end == it->unrelocated_pc ());

      /* Move to the last linetable entry of the current function.  */
      if (it == &linetable->item[0])
	{
	  /* Doing it-- would introduce undefined behavior, avoid it by
	     explicitly handling this case.  */
	  return {};
	}
      it--;
      if (it->unrelocated_pc () < unrel_start)
	{
	  /* Not in the current function.  */
	  return {};
	}
      gdb_assert (it->unrelocated_pc () < unrel_end);

      /* We're at the the last linetable entry of the current function.  This
	 is probably where the epilogue begins, but since the DWARF 5 spec
	 doesn't guarantee it, we iterate backwards through the current
	 function until we either find the epilogue beginning, or are sure
	 that it doesn't exist.  */
      for (; it >= &linetable->item[0]; it--)
	{
	  if (it->unrelocated_pc () < unrel_start)
	    {
	      /* No longer in the current function.  */
	      break;
	    }

	  if (it->epilogue_begin)
	    {
	      /* Found the beginning of the epilogue.  */
	      return {it->pc (objfile)};
	    }

	  if (it == &linetable->item[0])
	    {
	      /* No more entries in the current function.
		 Doing it-- would introduce undefined behavior, avoid it by
		 explicitly handling this case.  */
	      break;
	    }
	}
    }

  return {};
}

/* See symtab.h.  */

symbol *
find_function_alias_target (bound_minimal_symbol msymbol)
{
  CORE_ADDR func_addr;
  if (!msymbol_is_function (msymbol.objfile, msymbol.minsym, &func_addr))
    return NULL;

  symbol *sym = find_pc_function (func_addr);
  if (sym != NULL
      && sym->aclass () == LOC_BLOCK
      && sym->value_block ()->entry_pc () == func_addr)
    return sym;

  return NULL;
}


/* If P is of the form "operator[ \t]+..." where `...' is
   some legitimate operator text, return a pointer to the
   beginning of the substring of the operator text.
   Otherwise, return "".  */

static const char *
operator_chars (const char *p, const char **end)
{
  *end = "";
  if (!startswith (p, CP_OPERATOR_STR))
    return *end;
  p += CP_OPERATOR_LEN;

  /* Don't get faked out by `operator' being part of a longer
     identifier.  */
  if (isalpha (*p) || *p == '_' || *p == '$' || *p == '\0')
    return *end;

  /* Allow some whitespace between `operator' and the operator symbol.  */
  while (*p == ' ' || *p == '\t')
    p++;

  /* Recognize 'operator TYPENAME'.  */

  if (isalpha (*p) || *p == '_' || *p == '$')
    {
      const char *q = p + 1;

      while (isalnum (*q) || *q == '_' || *q == '$')
	q++;
      *end = q;
      return p;
    }

  while (*p)
    switch (*p)
      {
      case '\\':			/* regexp quoting */
	if (p[1] == '*')
	  {
	    if (p[2] == '=')		/* 'operator\*=' */
	      *end = p + 3;
	    else			/* 'operator\*'  */
	      *end = p + 2;
	    return p;
	  }
	else if (p[1] == '[')
	  {
	    if (p[2] == ']')
	      error (_("mismatched quoting on brackets, "
		       "try 'operator\\[\\]'"));
	    else if (p[2] == '\\' && p[3] == ']')
	      {
		*end = p + 4;	/* 'operator\[\]' */
		return p;
	      }
	    else
	      error (_("nothing is allowed between '[' and ']'"));
	  }
	else
	  {
	    /* Gratuitous quote: skip it and move on.  */
	    p++;
	    continue;
	  }
	break;
      case '!':
      case '=':
      case '*':
      case '/':
      case '%':
      case '^':
	if (p[1] == '=')
	  *end = p + 2;
	else
	  *end = p + 1;
	return p;
      case '<':
      case '>':
      case '+':
      case '-':
      case '&':
      case '|':
	if (p[0] == '-' && p[1] == '>')
	  {
	    /* Struct pointer member operator 'operator->'.  */
	    if (p[2] == '*')
	      {
		*end = p + 3;	/* 'operator->*' */
		return p;
	      }
	    else if (p[2] == '\\')
	      {
		*end = p + 4;	/* Hopefully 'operator->\*' */
		return p;
	      }
	    else
	      {
		*end = p + 2;	/* 'operator->' */
		return p;
	      }
	  }
	if (p[1] == '=' || p[1] == p[0])
	  *end = p + 2;
	else
	  *end = p + 1;
	return p;
      case '~':
      case ',':
	*end = p + 1;
	return p;
      case '(':
	if (p[1] != ')')
	  error (_("`operator ()' must be specified "
		   "without whitespace in `()'"));
	*end = p + 2;
	return p;
      case '?':
	if (p[1] != ':')
	  error (_("`operator ?:' must be specified "
		   "without whitespace in `?:'"));
	*end = p + 2;
	return p;
      case '[':
	if (p[1] != ']')
	  error (_("`operator []' must be specified "
		   "without whitespace in `[]'"));
	*end = p + 2;
	return p;
      default:
	error (_("`operator %s' not supported"), p);
	break;
      }

  *end = "";
  return *end;
}


/* See class declaration.  */

info_sources_filter::info_sources_filter (match_on match_type,
					  const char *regexp)
  : m_match_type (match_type),
    m_regexp (regexp)
{
  /* Setup the compiled regular expression M_C_REGEXP based on M_REGEXP.  */
  if (m_regexp != nullptr && *m_regexp != '\0')
    {
      gdb_assert (m_regexp != nullptr);

      int cflags = REG_NOSUB;
#ifdef HAVE_CASE_INSENSITIVE_FILE_SYSTEM
      cflags |= REG_ICASE;
#endif
      m_c_regexp.emplace (m_regexp, cflags, _("Invalid regexp"));
    }
}

/* See class declaration.  */

bool
info_sources_filter::matches (const char *fullname) const
{
  /* Does it match regexp?  */
  if (m_c_regexp.has_value ())
    {
      const char *to_match;
      std::string dirname;

      switch (m_match_type)
	{
	case match_on::DIRNAME:
	  dirname = gdb_ldirname (fullname);
	  to_match = dirname.c_str ();
	  break;
	case match_on::BASENAME:
	  to_match = lbasename (fullname);
	  break;
	case match_on::FULLNAME:
	  to_match = fullname;
	  break;
	default:
	  gdb_assert_not_reached ("bad m_match_type");
	}

      if (m_c_regexp->exec (to_match, 0, NULL, 0) != 0)
	return false;
    }

  return true;
}

/* Data structure to maintain the state used for printing the results of
   the 'info sources' command.  */

struct output_source_filename_data
{
  /* Create an object for displaying the results of the 'info sources'
     command to UIOUT.  FILTER must remain valid and unchanged for the
     lifetime of this object as this object retains a reference to FILTER.  */
  output_source_filename_data (struct ui_out *uiout,
			       const info_sources_filter &filter)
    : m_filter (filter),
      m_uiout (uiout)
  { /* Nothing.  */ }

  DISABLE_COPY_AND_ASSIGN (output_source_filename_data);

  /* Reset enough state of this object so we can match against a new set of
     files.  The existing regular expression is retained though.  */
  void reset_output ()
  {
    m_first = true;
    m_filename_seen_cache.clear ();
  }

  /* Worker for sources_info, outputs the file name formatted for either
     cli or mi (based on the current_uiout).  In cli mode displays
     FULLNAME with a comma separating this name from any previously
     printed name (line breaks are added at the comma).  In MI mode
     outputs a tuple containing DISP_NAME (the files display name),
     FULLNAME, and EXPANDED_P (true when this file is from a fully
     expanded symtab, otherwise false).  */
  void output (const char *disp_name, const char *fullname, bool expanded_p);

  /* An overload suitable for use as a callback to
     quick_symbol_functions::map_symbol_filenames.  */
  void operator() (const char *filename, const char *fullname)
  {
    /* The false here indicates that this file is from an unexpanded
       symtab.  */
    output (filename, fullname, false);
  }

  /* Return true if at least one filename has been printed (after a call to
     output) since either this object was created, or the last call to
     reset_output.  */
  bool printed_filename_p () const
  {
    return !m_first;
  }

private:

  /* Flag of whether we're printing the first one.  */
  bool m_first = true;

  /* Cache of what we've seen so far.  */
  filename_seen_cache m_filename_seen_cache;

  /* How source filename should be filtered.  */
  const info_sources_filter &m_filter;

  /* The object to which output is sent.  */
  struct ui_out *m_uiout;
};

/* See comment in class declaration above.  */

void
output_source_filename_data::output (const char *disp_name,
				     const char *fullname,
				     bool expanded_p)
{
  /* Since a single source file can result in several partial symbol
     tables, we need to avoid printing it more than once.  Note: if
     some of the psymtabs are read in and some are not, it gets
     printed both under "Source files for which symbols have been
     read" and "Source files for which symbols will be read in on
     demand".  I consider this a reasonable way to deal with the
     situation.  I'm not sure whether this can also happen for
     symtabs; it doesn't hurt to check.  */

  /* Was NAME already seen?  If so, then don't print it again.  */
  if (m_filename_seen_cache.seen (fullname))
    return;

  /* If the filter rejects this file then don't print it.  */
  if (!m_filter.matches (fullname))
    return;

  ui_out_emit_tuple ui_emitter (m_uiout, nullptr);

  /* Print it and reset *FIRST.  */
  if (!m_first)
    m_uiout->text (", ");
  m_first = false;

  m_uiout->wrap_hint (0);
  if (m_uiout->is_mi_like_p ())
    {
      m_uiout->field_string ("file", disp_name, file_name_style.style ());
      if (fullname != nullptr)
	m_uiout->field_string ("fullname", fullname,
			       file_name_style.style ());
      m_uiout->field_string ("debug-fully-read",
			     (expanded_p ? "true" : "false"));
    }
  else
    {
      if (fullname == nullptr)
	fullname = disp_name;
      m_uiout->field_string ("fullname", fullname,
			     file_name_style.style ());
    }
}

/* For the 'info sources' command, what part of the file names should we be
   matching the user supplied regular expression against?  */

struct filename_partial_match_opts
{
  /* Only match the directory name part.   */
  bool dirname = false;

  /* Only match the basename part.  */
  bool basename = false;
};

using isrc_flag_option_def
  = gdb::option::flag_option_def<filename_partial_match_opts>;

static const gdb::option::option_def info_sources_option_defs[] = {

  isrc_flag_option_def {
    "dirname",
    [] (filename_partial_match_opts *opts) { return &opts->dirname; },
    N_("Show only the files having a dirname matching REGEXP."),
  },

  isrc_flag_option_def {
    "basename",
    [] (filename_partial_match_opts *opts) { return &opts->basename; },
    N_("Show only the files having a basename matching REGEXP."),
  },

};

/* Create an option_def_group for the "info sources" options, with
   ISRC_OPTS as context.  */

static inline gdb::option::option_def_group
make_info_sources_options_def_group (filename_partial_match_opts *isrc_opts)
{
  return {{info_sources_option_defs}, isrc_opts};
}

/* Completer for "info sources".  */

static void
info_sources_command_completer (cmd_list_element *ignore,
				completion_tracker &tracker,
				const char *text, const char *word)
{
  const auto group = make_info_sources_options_def_group (nullptr);
  if (gdb::option::complete_options
      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
    return;
}

/* See symtab.h.  */

void
info_sources_worker (struct ui_out *uiout,
		     bool group_by_objfile,
		     const info_sources_filter &filter)
{
  output_source_filename_data data (uiout, filter);

  ui_out_emit_list results_emitter (uiout, "files");
  std::optional<ui_out_emit_tuple> output_tuple;
  std::optional<ui_out_emit_list> sources_list;

  gdb_assert (group_by_objfile || uiout->is_mi_like_p ());

  for (objfile *objfile : current_program_space->objfiles ())
    {
      if (group_by_objfile)
	{
	  output_tuple.emplace (uiout, nullptr);
	  uiout->field_string ("filename", objfile_name (objfile),
			       file_name_style.style ());
	  uiout->text (":\n");
	  bool debug_fully_readin = !objfile->has_unexpanded_symtabs ();
	  if (uiout->is_mi_like_p ())
	    {
	      const char *debug_info_state;
	      if (objfile_has_symbols (objfile))
		{
		  if (debug_fully_readin)
		    debug_info_state = "fully-read";
		  else
		    debug_info_state = "partially-read";
		}
	      else
		debug_info_state = "none";
	      current_uiout->field_string ("debug-info", debug_info_state);
	    }
	  else
	    {
	      if (!debug_fully_readin)
		uiout->text ("(Full debug information has not yet been read "
			     "for this file.)\n");
	      if (!objfile_has_symbols (objfile))
		uiout->text ("(Objfile has no debug information.)\n");
	      uiout->text ("\n");
	    }
	  sources_list.emplace (uiout, "sources");
	}

      for (compunit_symtab *cu : objfile->compunits ())
	{
	  for (symtab *s : cu->filetabs ())
	    {
	      const char *file = symtab_to_filename_for_display (s);
	      const char *fullname = symtab_to_fullname (s);
	      data.output (file, fullname, true);
	    }
	}

      if (group_by_objfile)
	{
	  objfile->map_symbol_filenames (data, true /* need_fullname */);
	  if (data.printed_filename_p ())
	    uiout->text ("\n\n");
	  data.reset_output ();
	  sources_list.reset ();
	  output_tuple.reset ();
	}
    }

  if (!group_by_objfile)
    {
      data.reset_output ();
      map_symbol_filenames (data, true /*need_fullname*/);
    }
}

/* Implement the 'info sources' command.  */

static void
info_sources_command (const char *args, int from_tty)
{
  if (!have_full_symbols (current_program_space)
      && !have_partial_symbols (current_program_space))
    error (_ ("No symbol table is loaded.  Use the \"file\" command."));

  filename_partial_match_opts match_opts;
  auto group = make_info_sources_options_def_group (&match_opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);

  if (match_opts.dirname && match_opts.basename)
    error (_("You cannot give both -basename and -dirname to 'info sources'."));

  const char *regex = nullptr;
  if (args != NULL && *args != '\000')
    regex = args;

  if ((match_opts.dirname || match_opts.basename) && regex == nullptr)
    error (_("Missing REGEXP for 'info sources'."));

  info_sources_filter::match_on match_type;
  if (match_opts.dirname)
    match_type = info_sources_filter::match_on::DIRNAME;
  else if (match_opts.basename)
    match_type = info_sources_filter::match_on::BASENAME;
  else
    match_type = info_sources_filter::match_on::FULLNAME;

  info_sources_filter filter (match_type, regex);
  info_sources_worker (current_uiout, true, filter);
}

/* Compare FILE against all the entries of FILENAMES.  If BASENAMES is
   true compare only lbasename of FILENAMES.  */

static bool
file_matches (const char *file,
	      const std::vector<gdb::unique_xmalloc_ptr<char>> &filenames,
	      bool basenames)
{
  if (filenames.empty ())
    return true;

  for (const auto &name : filenames)
    {
      const char *lname = (basenames ? lbasename (name.get ()) : name.get ());
      if (compare_filenames_for_search (file, lname))
	return true;
    }

  return false;
}

/* Helper function for std::sort on symbol_search objects.  Can only sort
   symbols, not minimal symbols.  */

int
symbol_search::compare_search_syms (const symbol_search &sym_a,
				    const symbol_search &sym_b)
{
  int c;

  c = FILENAME_CMP (sym_a.symbol->symtab ()->filename,
		    sym_b.symbol->symtab ()->filename);
  if (c != 0)
    return c;

  if (sym_a.block != sym_b.block)
    return sym_a.block - sym_b.block;

  return strcmp (sym_a.symbol->print_name (), sym_b.symbol->print_name ());
}

/* Returns true if the type_name of symbol_type of SYM matches TREG.
   If SYM has no symbol_type or symbol_name, returns false.  */

bool
treg_matches_sym_type_name (const compiled_regex &treg,
			    const struct symbol *sym)
{
  struct type *sym_type;
  std::string printed_sym_type_name;

  symbol_lookup_debug_printf_v ("treg_matches_sym_type_name, sym %s",
				sym->natural_name ());

  sym_type = sym->type ();
  if (sym_type == NULL)
    return false;

  {
    scoped_switch_to_sym_language_if_auto l (sym);

    printed_sym_type_name = type_to_string (sym_type);
  }

  symbol_lookup_debug_printf_v ("sym_type_name %s",
				printed_sym_type_name.c_str ());

  if (printed_sym_type_name.empty ())
    return false;

  return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0;
}

/* See symtab.h.  */

bool
global_symbol_searcher::is_suitable_msymbol
	(const domain_search_flags kind, const minimal_symbol *msymbol)
{
  switch (msymbol->type ())
    {
    case mst_data:
    case mst_bss:
    case mst_file_data:
    case mst_file_bss:
      return (kind & SEARCH_VAR_DOMAIN) != 0;
    case mst_text:
    case mst_file_text:
    case mst_solib_trampoline:
    case mst_text_gnu_ifunc:
      return (kind & SEARCH_FUNCTION_DOMAIN) != 0;
    default:
      return false;
    }
}

/* See symtab.h.  */

bool
global_symbol_searcher::expand_symtabs
	(objfile *objfile, const std::optional<compiled_regex> &preg) const
{
  domain_search_flags kind = m_kind;
  bool found_msymbol = false;

  auto do_file_match = [&] (const char *filename, bool basenames)
    {
      return file_matches (filename, m_filenames, basenames);
    };
  expand_symtabs_file_matcher file_matcher = nullptr;
  if (!m_filenames.empty ())
    file_matcher = do_file_match;

  objfile->expand_symtabs_matching
    (file_matcher,
     &lookup_name_info::match_any (),
     [&] (const char *symname)
     {
       return (!preg.has_value ()
	       || preg->exec (symname, 0, NULL, 0) == 0);
     },
     NULL,
     SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
     kind);

  /* Here, we search through the minimal symbol tables for functions and
     variables that match, and force their symbols to be read.  This is in
     particular necessary for demangled variable names, which are no longer
     put into the partial symbol tables.  The symbol will then be found
     during the scan of symtabs later.

     For functions, find_pc_symtab should succeed if we have debug info for
     the function, for variables we have to call
     lookup_symbol_in_objfile_from_linkage_name to determine if the
     variable has debug info.  If the lookup fails, set found_msymbol so
     that we will rescan to print any matching symbols without debug info.
     We only search the objfile the msymbol came from, we no longer search
     all objfiles.  In large programs (1000s of shared libs) searching all
     objfiles is not worth the pain.  */
  if (m_filenames.empty ()
      && (kind & (SEARCH_VAR_DOMAIN | SEARCH_FUNCTION_DOMAIN)) != 0)
    {
      for (minimal_symbol *msymbol : objfile->msymbols ())
	{
	  QUIT;

	  if (msymbol->created_by_gdb)
	    continue;

	  if (is_suitable_msymbol (kind, msymbol))
	    {
	      if (!preg.has_value ()
		  || preg->exec (msymbol->natural_name (), 0,
				 NULL, 0) == 0)
		{
		  /* An important side-effect of these lookup functions is
		     to expand the symbol table if msymbol is found, later
		     in the process we will add matching symbols or
		     msymbols to the results list, and that requires that
		     the symbols tables are expanded.  */
		  if ((kind & SEARCH_FUNCTION_DOMAIN) != 0
		      ? (find_pc_compunit_symtab
			 (msymbol->value_address (objfile)) == NULL)
		      : (lookup_symbol_in_objfile_from_linkage_name
			 (objfile, msymbol->linkage_name (),
			  SEARCH_VFT)
			 .symbol == NULL))
		    found_msymbol = true;
		}
	    }
	}
    }

  return found_msymbol;
}

/* See symtab.h.  */

bool
global_symbol_searcher::add_matching_symbols
	(objfile *objfile,
	 const std::optional<compiled_regex> &preg,
	 const std::optional<compiled_regex> &treg,
	 std::set<symbol_search> *result_set) const
{
  domain_search_flags kind = m_kind;

  /* Add matching symbols (if not already present).  */
  for (compunit_symtab *cust : objfile->compunits ())
    {
      const struct blockvector *bv  = cust->blockvector ();

      for (block_enum block : { GLOBAL_BLOCK, STATIC_BLOCK })
	{
	  const struct block *b = bv->block (block);

	  for (struct symbol *sym : block_iterator_range (b))
	    {
	      struct symtab *real_symtab = sym->symtab ();

	      QUIT;

	      /* Check first sole REAL_SYMTAB->FILENAME.  It does
		 not need to be a substring of symtab_to_fullname as
		 it may contain "./" etc.  */
	      if (!(file_matches (real_symtab->filename, m_filenames, false)
		    || ((basenames_may_differ
			 || file_matches (lbasename (real_symtab->filename),
					  m_filenames, true))
			&& file_matches (symtab_to_fullname (real_symtab),
					 m_filenames, false))))
		continue;

	      if (!sym->matches (kind))
		continue;

	      if (preg.has_value () && preg->exec (sym->natural_name (), 0,
						   nullptr, 0) != 0)
		continue;

	      if (((sym->domain () == VAR_DOMAIN
		    || sym->domain () == FUNCTION_DOMAIN)
		   && treg.has_value ()
		   && !treg_matches_sym_type_name (*treg, sym)))
		continue;

	      if ((kind & SEARCH_VAR_DOMAIN) != 0)
		{
		  if (sym->aclass () == LOC_UNRESOLVED
		      /* LOC_CONST can be used for more than
			 just enums, e.g., c++ static const
			 members.  We only want to skip enums
			 here.  */
		      || (sym->aclass () == LOC_CONST
			  && (sym->type ()->code () == TYPE_CODE_ENUM)))
		    continue;
		}
	      if (sym->domain () == MODULE_DOMAIN && sym->line () == 0)
		continue;

	      if (result_set->size () < m_max_search_results)
		{
		  /* Match, insert if not already in the results.  */
		  symbol_search ss (block, sym);
		  if (result_set->find (ss) == result_set->end ())
		    result_set->insert (ss);
		}
	      else
		return false;
	    }
	}
    }

  return true;
}

/* See symtab.h.  */

bool
global_symbol_searcher::add_matching_msymbols
	(objfile *objfile, const std::optional<compiled_regex> &preg,
	 std::vector<symbol_search> *results) const
{
  domain_search_flags kind = m_kind;

  for (minimal_symbol *msymbol : objfile->msymbols ())
    {
      QUIT;

      if (msymbol->created_by_gdb)
	continue;

      if (is_suitable_msymbol (kind, msymbol))
	{
	  if (!preg.has_value ()
	      || preg->exec (msymbol->natural_name (), 0,
			     NULL, 0) == 0)
	    {
	      /* For functions we can do a quick check of whether the
		 symbol might be found via find_pc_symtab.  */
	      if ((kind & SEARCH_FUNCTION_DOMAIN) == 0
		  || (find_pc_compunit_symtab
		      (msymbol->value_address (objfile)) == NULL))
		{
		  if (lookup_symbol_in_objfile_from_linkage_name
		      (objfile, msymbol->linkage_name (),
		       SEARCH_VFT).symbol == NULL)
		    {
		      /* Matching msymbol, add it to the results list.  */
		      if (results->size () < m_max_search_results)
			results->emplace_back (GLOBAL_BLOCK, msymbol, objfile);
		      else
			return false;
		    }
		}
	    }
	}
    }

  return true;
}

/* See symtab.h.  */

std::vector<symbol_search>
global_symbol_searcher::search () const
{
  std::optional<compiled_regex> preg;
  std::optional<compiled_regex> treg;

  if (m_symbol_name_regexp != NULL)
    {
      const char *symbol_name_regexp = m_symbol_name_regexp;
      std::string symbol_name_regexp_holder;

      /* Make sure spacing is right for C++ operators.
	 This is just a courtesy to make the matching less sensitive
	 to how many spaces the user leaves between 'operator'
	 and <TYPENAME> or <OPERATOR>.  */
      const char *opend;
      const char *opname = operator_chars (symbol_name_regexp, &opend);

      if (*opname)
	{
	  int fix = -1;		/* -1 means ok; otherwise number of
				    spaces needed.  */

	  if (isalpha (*opname) || *opname == '_' || *opname == '$')
	    {
	      /* There should 1 space between 'operator' and 'TYPENAME'.  */
	      if (opname[-1] != ' ' || opname[-2] == ' ')
		fix = 1;
	    }
	  else
	    {
	      /* There should 0 spaces between 'operator' and 'OPERATOR'.  */
	      if (opname[-1] == ' ')
		fix = 0;
	    }
	  /* If wrong number of spaces, fix it.  */
	  if (fix >= 0)
	    {
	      symbol_name_regexp_holder
		= string_printf ("operator%.*s%s", fix, " ", opname);
	      symbol_name_regexp = symbol_name_regexp_holder.c_str ();
	    }
	}

      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
				? REG_ICASE : 0);
      preg.emplace (symbol_name_regexp, cflags,
		    _("Invalid regexp"));
    }

  if (m_symbol_type_regexp != NULL)
    {
      int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
				? REG_ICASE : 0);
      treg.emplace (m_symbol_type_regexp, cflags,
		    _("Invalid regexp"));
    }

  bool found_msymbol = false;
  std::set<symbol_search> result_set;
  for (objfile *objfile : current_program_space->objfiles ())
    {
      /* Expand symtabs within objfile that possibly contain matching
	 symbols.  */
      found_msymbol |= expand_symtabs (objfile, preg);

      /* Find matching symbols within OBJFILE and add them in to the
	 RESULT_SET set.  Use a set here so that we can easily detect
	 duplicates as we go, and can therefore track how many unique
	 matches we have found so far.  */
      if (!add_matching_symbols (objfile, preg, treg, &result_set))
	break;
    }

  /* Convert the result set into a sorted result list, as std::set is
     defined to be sorted then no explicit call to std::sort is needed.  */
  std::vector<symbol_search> result (result_set.begin (), result_set.end ());

  /* If there are no debug symbols, then add matching minsyms.  But if the
     user wants to see symbols matching a type regexp, then never give a
     minimal symbol, as we assume that a minimal symbol does not have a
     type.  */
  if ((found_msymbol
       || (m_filenames.empty () && (m_kind & SEARCH_VAR_DOMAIN) != 0))
      && !m_exclude_minsyms
      && !treg.has_value ())
    {
      gdb_assert ((m_kind & (SEARCH_VAR_DOMAIN | SEARCH_FUNCTION_DOMAIN))
		  != 0);
      for (objfile *objfile : current_program_space->objfiles ())
	if (!add_matching_msymbols (objfile, preg, &result))
	  break;
    }

  return result;
}

/* See symtab.h.  */

std::string
symbol_to_info_string (struct symbol *sym, int block)
{
  std::string str;

  gdb_assert (block == GLOBAL_BLOCK || block == STATIC_BLOCK);

  if (block == STATIC_BLOCK
      && (sym->domain () == VAR_DOMAIN
	  || sym->domain () == FUNCTION_DOMAIN))
    str += "static ";

  /* Typedef that is not a C++ class.  */
  if (sym->domain () == TYPE_DOMAIN)
    {
      string_file tmp_stream;

      /* FIXME: For C (and C++) we end up with a difference in output here
	 between how a typedef is printed, and non-typedefs are printed.
	 The TYPEDEF_PRINT code places a ";" at the end in an attempt to
	 appear C-like, while TYPE_PRINT doesn't.

	 For the struct printing case below, things are worse, we force
	 printing of the ";" in this function, which is going to be wrong
	 for languages that don't require a ";" between statements.  */
      if (sym->type ()->code () == TYPE_CODE_TYPEDEF)
	typedef_print (sym->type (), sym, &tmp_stream);
      else
	type_print (sym->type (), "", &tmp_stream, -1);
      str += tmp_stream.string ();
    }
  /* variable, func, or typedef-that-is-c++-class.  */
  else if (sym->domain () == VAR_DOMAIN || sym->domain () == STRUCT_DOMAIN
	   || sym->domain () == FUNCTION_DOMAIN)
    {
      string_file tmp_stream;

      type_print (sym->type (),
		  (sym->aclass () == LOC_TYPEDEF
		   ? "" : sym->print_name ()),
		  &tmp_stream, 0);

      str += tmp_stream.string ();
      str += ";";
    }
  /* Printing of modules is currently done here, maybe at some future
     point we might want a language specific method to print the module
     symbol so that we can customise the output more.  */
  else if (sym->domain () == MODULE_DOMAIN)
    str += sym->print_name ();

  return str;
}

/* Helper function for symbol info commands, for example 'info
   functions', 'info variables', etc.  BLOCK is the type of block the
   symbols was found in, either GLOBAL_BLOCK or STATIC_BLOCK.  SYM is
   the symbol we found.  If LAST is not NULL, print file and line
   number information for the symbol as well.  Skip printing the
   filename if it matches LAST.  */

static void
print_symbol_info (struct symbol *sym, int block, const char *last)
{
  scoped_switch_to_sym_language_if_auto l (sym);
  struct symtab *s = sym->symtab ();

  if (last != NULL)
    {
      const char *s_filename = symtab_to_filename_for_display (s);

      if (filename_cmp (last, s_filename) != 0)
	{
	  gdb_printf (_("\nFile %ps:\n"),
		      styled_string (file_name_style.style (),
				     s_filename));
	}

      if (sym->line () != 0)
	gdb_printf ("%d:\t", sym->line ());
      else
	gdb_puts ("\t");
    }

  std::string str = symbol_to_info_string (sym, block);
  gdb_printf ("%s\n", str.c_str ());
}

/* This help function for symtab_symbol_info() prints information
   for non-debugging symbols to gdb_stdout.  */

static void
print_msymbol_info (bound_minimal_symbol msymbol)
{
  struct gdbarch *gdbarch = msymbol.objfile->arch ();
  const char *tmp;

  if (gdbarch_addr_bit (gdbarch) <= 32)
    tmp = hex_string_custom (msymbol.value_address ()
			     & (CORE_ADDR) 0xffffffff,
			     8);
  else
    tmp = hex_string_custom (msymbol.value_address (),
			     16);

  ui_file_style sym_style = (msymbol.minsym->text_p ()
			     ? function_name_style.style ()
			     : ui_file_style ());

  gdb_printf (_("%ps  %ps\n"),
	      styled_string (address_style.style (), tmp),
	      styled_string (sym_style, msymbol.minsym->print_name ()));
}

/* This is the guts of the commands "info functions", "info types", and
   "info variables".  It calls search_symbols to find all matches and then
   print_[m]symbol_info to print out some useful information about the
   matches.  */

static void
symtab_symbol_info (bool quiet, bool exclude_minsyms,
		    const char *regexp, domain_enum kind,
		    const char *t_regexp, int from_tty)
{
  const char *last_filename = "";
  int first = 1;

  if (regexp != nullptr && *regexp == '\0')
    regexp = nullptr;

  domain_search_flags flags = to_search_flags (kind);
  if (kind == TYPE_DOMAIN)
    flags |= SEARCH_STRUCT_DOMAIN;

  global_symbol_searcher spec (flags, regexp);
  spec.set_symbol_type_regexp (t_regexp);
  spec.set_exclude_minsyms (exclude_minsyms);
  std::vector<symbol_search> symbols = spec.search ();

  if (!quiet)
    {
      const char *classname;
      switch (kind)
	{
	case VAR_DOMAIN:
	  classname = "variable";
	  break;
	case FUNCTION_DOMAIN:
	  classname = "function";
	  break;
	case TYPE_DOMAIN:
	  classname = "type";
	  break;
	case MODULE_DOMAIN:
	  classname = "module";
	  break;
	default:
	  gdb_assert_not_reached ("invalid domain enum");
	}

      if (regexp != NULL)
	{
	  if (t_regexp != NULL)
	    gdb_printf
	      (_("All %ss matching regular expression \"%s\""
		 " with type matching regular expression \"%s\":\n"),
	       classname, regexp, t_regexp);
	  else
	    gdb_printf (_("All %ss matching regular expression \"%s\":\n"),
			classname, regexp);
	}
      else
	{
	  if (t_regexp != NULL)
	    gdb_printf
	      (_("All defined %ss"
		 " with type matching regular expression \"%s\" :\n"),
	       classname, t_regexp);
	  else
	    gdb_printf (_("All defined %ss:\n"), classname);
	}
    }

  for (const symbol_search &p : symbols)
    {
      QUIT;

      if (p.msymbol.minsym != NULL)
	{
	  if (first)
	    {
	      if (!quiet)
		gdb_printf (_("\nNon-debugging symbols:\n"));
	      first = 0;
	    }
	  print_msymbol_info (p.msymbol);
	}
      else
	{
	  print_symbol_info (p.symbol, p.block, last_filename);
	  last_filename
	    = symtab_to_filename_for_display (p.symbol->symtab ());
	}
    }
}

/* Structure to hold the values of the options used by the 'info variables'
   and 'info functions' commands.  These correspond to the -q, -t, and -n
   options.  */

struct info_vars_funcs_options
{
  bool quiet = false;
  bool exclude_minsyms = false;
  std::string type_regexp;
};

/* The options used by the 'info variables' and 'info functions'
   commands.  */

static const gdb::option::option_def info_vars_funcs_options_defs[] = {
  gdb::option::boolean_option_def<info_vars_funcs_options> {
    "q",
    [] (info_vars_funcs_options *opt) { return &opt->quiet; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  },

  gdb::option::boolean_option_def<info_vars_funcs_options> {
    "n",
    [] (info_vars_funcs_options *opt) { return &opt->exclude_minsyms; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  },

  gdb::option::string_option_def<info_vars_funcs_options> {
    "t",
    [] (info_vars_funcs_options *opt) { return &opt->type_regexp; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  }
};

/* Returns the option group used by 'info variables' and 'info
   functions'.  */

static gdb::option::option_def_group
make_info_vars_funcs_options_def_group (info_vars_funcs_options *opts)
{
  return {{info_vars_funcs_options_defs}, opts};
}

/* Command completer for 'info variables' and 'info functions'.  */

static void
info_vars_funcs_command_completer (struct cmd_list_element *ignore,
				   completion_tracker &tracker,
				   const char *text, const char * /* word */)
{
  const auto group
    = make_info_vars_funcs_options_def_group (nullptr);
  if (gdb::option::complete_options
      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
    return;

  const char *word = advance_to_expression_complete_word_point (tracker, text);
  symbol_completer (ignore, tracker, text, word);
}

/* Implement the 'info variables' command.  */

static void
info_variables_command (const char *args, int from_tty)
{
  info_vars_funcs_options opts;
  auto grp = make_info_vars_funcs_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
  if (args != nullptr && *args == '\0')
    args = nullptr;

  symtab_symbol_info
    (opts.quiet, opts.exclude_minsyms, args, VAR_DOMAIN,
     opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
     from_tty);
}

/* Implement the 'info functions' command.  */

static void
info_functions_command (const char *args, int from_tty)
{
  info_vars_funcs_options opts;

  auto grp = make_info_vars_funcs_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
  if (args != nullptr && *args == '\0')
    args = nullptr;

  symtab_symbol_info
    (opts.quiet, opts.exclude_minsyms, args, FUNCTION_DOMAIN,
     opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
     from_tty);
}

/* Holds the -q option for the 'info types' command.  */

struct info_types_options
{
  bool quiet = false;
};

/* The options used by the 'info types' command.  */

static const gdb::option::option_def info_types_options_defs[] = {
  gdb::option::boolean_option_def<info_types_options> {
    "q",
    [] (info_types_options *opt) { return &opt->quiet; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  }
};

/* Returns the option group used by 'info types'.  */

static gdb::option::option_def_group
make_info_types_options_def_group (info_types_options *opts)
{
  return {{info_types_options_defs}, opts};
}

/* Implement the 'info types' command.  */

static void
info_types_command (const char *args, int from_tty)
{
  info_types_options opts;

  auto grp = make_info_types_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
  if (args != nullptr && *args == '\0')
    args = nullptr;
  symtab_symbol_info (opts.quiet, false, args, TYPE_DOMAIN, nullptr,
		      from_tty);
}

/* Command completer for 'info types' command.  */

static void
info_types_command_completer (struct cmd_list_element *ignore,
			      completion_tracker &tracker,
			      const char *text, const char * /* word */)
{
  const auto group
    = make_info_types_options_def_group (nullptr);
  if (gdb::option::complete_options
      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
    return;

  const char *word = advance_to_expression_complete_word_point (tracker, text);
  symbol_completer (ignore, tracker, text, word);
}

/* Implement the 'info modules' command.  */

static void
info_modules_command (const char *args, int from_tty)
{
  info_types_options opts;

  auto grp = make_info_types_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
  if (args != nullptr && *args == '\0')
    args = nullptr;
  symtab_symbol_info (opts.quiet, true, args, MODULE_DOMAIN, nullptr,
		      from_tty);
}

/* Implement the 'info main' command.  */

static void
info_main_command (const char *args, int from_tty)
{
  gdb_printf ("%s\n", main_name ());
}

static void
rbreak_command (const char *regexp, int from_tty)
{
  gdb::unique_xmalloc_ptr<char> file_name;

  if (regexp != nullptr)
    {
      const char *colon = strchr (regexp, ':');

      /* Ignore the colon if it is part of a Windows drive.  */
      if (HAS_DRIVE_SPEC (regexp)
	  && (regexp[2] == '/' || regexp[2] == '\\'))
	colon = strchr (STRIP_DRIVE_SPEC (regexp), ':');

      if (colon && *(colon + 1) != ':')
	{
	  int colon_index = colon - regexp;
	  while (colon_index > 0 && isspace (regexp[colon_index - 1]))
	    --colon_index;

	  file_name = make_unique_xstrndup (regexp, colon_index);
	  regexp = skip_spaces (colon + 1);
	}
    }

  global_symbol_searcher spec (SEARCH_FUNCTION_DOMAIN, regexp);
  if (file_name != nullptr)
    spec.add_filename (std::move (file_name));
  std::vector<symbol_search> symbols = spec.search ();

  gdb::unordered_set<std::string> seen_names;
  scoped_rbreak_breakpoints finalize;
  int err_count = 0;

  for (const symbol_search &p : symbols)
    {
      std::string name;
      if (p.msymbol.minsym == nullptr)
	{
	  if (file_name != nullptr)
	    {
	      struct symtab *symtab = p.symbol->symtab ();
	      const char *fullname = symtab_to_fullname (symtab);
	      name = string_printf ("%s:'%s'", fullname,
				    p.symbol->linkage_name ());
	    }
	  else
	    name = p.symbol->linkage_name ();
	}
      else
	name = p.msymbol.minsym->linkage_name ();

      if (!seen_names.insert (name).second)
	continue;

      try
	{
	  break_command (name.c_str (), from_tty);
	}
      catch (const gdb_exception_error &ex)
	{
	  exception_print (gdb_stderr, ex);
	  ++err_count;
	  continue;
	}

      if (p.msymbol.minsym == nullptr)
	print_symbol_info (p.symbol, p.block, nullptr);
      else
	gdb_printf ("<function, no debug info> %s;\n", name.c_str ());
    }

  int first_bp = finalize.first_breakpoint ();
  int last_bp = finalize.last_breakpoint ();

  if (last_bp == -1)
    gdb_printf (_("No breakpoints made.\n"));
  else if (first_bp == last_bp)
    gdb_printf (_("Successfully created breakpoint %d.\n"), first_bp);
  else
    gdb_printf (_("Successfully created breakpoints %d-%d.\n"),
		first_bp, last_bp);

  if (err_count > 0)
    gdb_printf (_("%d breakpoints failed due to errors, see above.\n"),
		err_count);
}


/* Evaluate if SYMNAME matches LOOKUP_NAME.  */

static int
compare_symbol_name (const char *symbol_name, language symbol_language,
		     const lookup_name_info &lookup_name,
		     completion_match_result &match_res)
{
  const language_defn *lang = language_def (symbol_language);

  symbol_name_matcher_ftype *name_match
    = lang->get_symbol_name_matcher (lookup_name);

  return name_match (symbol_name, lookup_name, &match_res);
}

/*  See symtab.h.  */

bool
completion_list_add_name (completion_tracker &tracker,
			  language symbol_language,
			  const char *symname,
			  const lookup_name_info &lookup_name,
			  const char *text, const char *word)
{
  completion_match_result &match_res
    = tracker.reset_completion_match_result ();

  /* Clip symbols that cannot match.  */
  if (!compare_symbol_name (symname, symbol_language, lookup_name, match_res))
    return false;

  /* Refresh SYMNAME from the match string.  It's potentially
     different depending on language.  (E.g., on Ada, the match may be
     the encoded symbol name wrapped in "<>").  */
  symname = match_res.match.match ();
  gdb_assert (symname != NULL);

  /* We have a match for a completion, so add SYMNAME to the current list
     of matches.  Note that the name is moved to freshly malloc'd space.  */

  {
    gdb::unique_xmalloc_ptr<char> completion
      = make_completion_match_str (symname, text, word);

    /* Here we pass the match-for-lcd object to add_completion.  Some
       languages match the user text against substrings of symbol
       names in some cases.  E.g., in C++, "b push_ba" completes to
       "std::vector::push_back", "std::string::push_back", etc., and
       in this case we want the completion lowest common denominator
       to be "push_back" instead of "std::".  */
    tracker.add_completion (std::move (completion),
			    &match_res.match_for_lcd, text, word);
  }

  return true;
}

/* completion_list_add_name wrapper for struct symbol.  */

static void
completion_list_add_symbol (completion_tracker &tracker,
			    symbol *sym,
			    const lookup_name_info &lookup_name,
			    const char *text, const char *word)
{
  if (!completion_list_add_name (tracker, sym->language (),
				 sym->natural_name (),
				 lookup_name, text, word))
    return;

  /* C++ function symbols include the parameters within both the msymbol
     name and the symbol name.  The problem is that the msymbol name will
     describe the parameters in the most basic way, with typedefs stripped
     out, while the symbol name will represent the types as they appear in
     the program.  This means we will see duplicate entries in the
     completion tracker.  The following converts the symbol name back to
     the msymbol name and removes the msymbol name from the completion
     tracker.  */
  if (sym->language () == language_cplus
      && sym->aclass () == LOC_BLOCK)
    {
      /* The call to canonicalize returns the empty string if the input
	 string is already in canonical form, thanks to this we don't
	 remove the symbol we just added above.  */
      gdb::unique_xmalloc_ptr<char> str
	= cp_canonicalize_string_no_typedefs (sym->natural_name ());
      if (str != nullptr)
	tracker.remove_completion (str.get ());
    }
}

/* completion_list_add_name wrapper for struct minimal_symbol.  */

static void
completion_list_add_msymbol (completion_tracker &tracker,
			     minimal_symbol *sym,
			     const lookup_name_info &lookup_name,
			     const char *text, const char *word)
{
  completion_list_add_name (tracker, sym->language (),
			    sym->natural_name (),
			    lookup_name, text, word);
}


/* ObjC: In case we are completing on a selector, look as the msymbol
   again and feed all the selectors into the mill.  */

static void
completion_list_objc_symbol (completion_tracker &tracker,
			     struct minimal_symbol *msymbol,
			     const lookup_name_info &lookup_name,
			     const char *text, const char *word)
{
  static char *tmp = NULL;
  static unsigned int tmplen = 0;

  const char *method, *category, *selector;
  char *tmp2 = NULL;

  method = msymbol->natural_name ();

  /* Is it a method?  */
  if ((method[0] != '-') && (method[0] != '+'))
    return;

  if (text[0] == '[')
    /* Complete on shortened method method.  */
    completion_list_add_name (tracker, language_objc,
			      method + 1,
			      lookup_name,
			      text, word);

  while ((strlen (method) + 1) >= tmplen)
    {
      if (tmplen == 0)
	tmplen = 1024;
      else
	tmplen *= 2;
      tmp = (char *) xrealloc (tmp, tmplen);
    }
  selector = strchr (method, ' ');
  if (selector != NULL)
    selector++;

  category = strchr (method, '(');

  if ((category != NULL) && (selector != NULL))
    {
      memcpy (tmp, method, (category - method));
      tmp[category - method] = ' ';
      memcpy (tmp + (category - method) + 1, selector, strlen (selector) + 1);
      completion_list_add_name (tracker, language_objc, tmp,
				lookup_name, text, word);
      if (text[0] == '[')
	completion_list_add_name (tracker, language_objc, tmp + 1,
				  lookup_name, text, word);
    }

  if (selector != NULL)
    {
      /* Complete on selector only.  */
      strcpy (tmp, selector);
      tmp2 = strchr (tmp, ']');
      if (tmp2 != NULL)
	*tmp2 = '\0';

      completion_list_add_name (tracker, language_objc, tmp,
				lookup_name, text, word);
    }
}

/* Break the non-quoted text based on the characters which are in
   symbols.  FIXME: This should probably be language-specific.  */

static const char *
language_search_unquoted_string (const char *text, const char *p)
{
  for (; p > text; --p)
    {
      if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0')
	continue;
      else
	{
	  if ((current_language->la_language == language_objc))
	    {
	      if (p[-1] == ':')     /* Might be part of a method name.  */
		continue;
	      else if (p[-1] == '[' && (p[-2] == '-' || p[-2] == '+'))
		p -= 2;             /* Beginning of a method name.  */
	      else if (p[-1] == ' ' || p[-1] == '(' || p[-1] == ')')
		{                   /* Might be part of a method name.  */
		  const char *t = p;

		  /* Seeing a ' ' or a '(' is not conclusive evidence
		     that we are in the middle of a method name.  However,
		     finding "-[" or "+[" should be pretty un-ambiguous.
		     Unfortunately we have to find it now to decide.  */

		  while (t > text)
		    if (isalnum (t[-1]) || t[-1] == '_' ||
			t[-1] == ' '    || t[-1] == ':' ||
			t[-1] == '('    || t[-1] == ')')
		      --t;
		    else
		      break;

		  if (t[-1] == '[' && (t[-2] == '-' || t[-2] == '+'))
		    p = t - 2;      /* Method name detected.  */
		  /* Else we leave with p unchanged.  */
		}
	    }
	  break;
	}
    }
  return p;
}

static void
completion_list_add_fields (completion_tracker &tracker,
			    struct symbol *sym,
			    const lookup_name_info &lookup_name,
			    const char *text, const char *word)
{
  if (sym->aclass () == LOC_TYPEDEF)
    {
      struct type *t = sym->type ();
      enum type_code c = t->code ();
      int j;

      if (c == TYPE_CODE_UNION || c == TYPE_CODE_STRUCT)
	for (j = TYPE_N_BASECLASSES (t); j < t->num_fields (); j++)
	  if (t->field (j).name ())
	    completion_list_add_name (tracker, sym->language (),
				      t->field (j).name (),
				      lookup_name, text, word);
    }
}

/* See symtab.h.  */

bool
symbol_is_function_or_method (symbol *sym)
{
  switch (sym->type ()->code ())
    {
    case TYPE_CODE_FUNC:
    case TYPE_CODE_METHOD:
      return true;
    default:
      return false;
    }
}

/* See symtab.h.  */

bool
symbol_is_function_or_method (minimal_symbol *msymbol)
{
  switch (msymbol->type ())
    {
    case mst_text:
    case mst_text_gnu_ifunc:
    case mst_solib_trampoline:
    case mst_file_text:
      return true;
    default:
      return false;
    }
}

/* See symtab.h.  */

bound_minimal_symbol
find_gnu_ifunc (const symbol *sym)
{
  if (sym->aclass () != LOC_BLOCK)
    return {};

  lookup_name_info lookup_name (sym->search_name (),
				symbol_name_match_type::SEARCH_NAME);
  struct objfile *objfile = sym->objfile ();

  CORE_ADDR address = sym->value_block ()->entry_pc ();
  minimal_symbol *ifunc = NULL;

  iterate_over_minimal_symbols (objfile, lookup_name,
				[&] (minimal_symbol *minsym)
    {
      if (minsym->type () == mst_text_gnu_ifunc
	  || minsym->type () == mst_data_gnu_ifunc)
	{
	  CORE_ADDR msym_addr = minsym->value_address (objfile);
	  if (minsym->type () == mst_data_gnu_ifunc)
	    {
	      struct gdbarch *gdbarch = objfile->arch ();
	      msym_addr = gdbarch_convert_from_func_ptr_addr
		(gdbarch, msym_addr, current_inferior ()->top_target ());
	    }
	  if (msym_addr == address)
	    {
	      ifunc = minsym;
	      return true;
	    }
	}
      return false;
    });

  if (ifunc != NULL)
    return {ifunc, objfile};
  return {};
}

/* Add matching symbols from SYMTAB to the current completion list.  */

static void
add_symtab_completions (struct compunit_symtab *cust,
			completion_tracker &tracker,
			complete_symbol_mode mode,
			const lookup_name_info &lookup_name,
			const char *text, const char *word,
			enum type_code code)
{
  int i;

  if (cust == NULL)
    return;

  for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
    {
      QUIT;

      const struct block *b = cust->blockvector ()->block (i);
      for (struct symbol *sym : block_iterator_range (b))
	{
	  if (completion_skip_symbol (mode, sym))
	    continue;

	  if (code == TYPE_CODE_UNDEF
	      || (sym->domain () == STRUCT_DOMAIN
		  && sym->type ()->code () == code))
	    completion_list_add_symbol (tracker, sym,
					lookup_name,
					text, word);
	}
    }
}

void
default_collect_symbol_completion_matches_break_on
  (completion_tracker &tracker, complete_symbol_mode mode,
   symbol_name_match_type name_match_type,
   const char *text, const char *word,
   const char *break_on, enum type_code code)
{
  /* Problem: All of the symbols have to be copied because readline
     frees them.  I'm not going to worry about this; hopefully there
     won't be that many.  */

  const struct block *b;
  const struct block *surrounding_static_block, *surrounding_global_block;
  /* The symbol we are completing on.  Points in same buffer as text.  */
  const char *sym_text;

  /* Now look for the symbol we are supposed to complete on.  */
  if (mode == complete_symbol_mode::LINESPEC)
    sym_text = text;
  else
    {
      const char *p;
      char quote_found;
      const char *quote_pos = NULL;

      /* First see if this is a quoted string.  */
      quote_found = '\0';
      for (p = text; *p != '\0'; ++p)
	{
	  if (quote_found != '\0')
	    {
	      if (*p == quote_found)
		/* Found close quote.  */
		quote_found = '\0';
	      else if (*p == '\\' && p[1] == quote_found)
		/* A backslash followed by the quote character
		   doesn't end the string.  */
		++p;
	    }
	  else if (*p == '\'' || *p == '"')
	    {
	      quote_found = *p;
	      quote_pos = p;
	    }
	}
      if (quote_found == '\'')
	/* A string within single quotes can be a symbol, so complete on it.  */
	sym_text = quote_pos + 1;
      else if (quote_found == '"')
	/* A double-quoted string is never a symbol, nor does it make sense
	   to complete it any other way.  */
	{
	  return;
	}
      else
	{
	  /* It is not a quoted string.  Break it based on the characters
	     which are in symbols.  */
	  while (p > text)
	    {
	      if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
		  || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
		--p;
	      else
		break;
	    }
	  sym_text = p;
	}
    }

  lookup_name_info lookup_name (sym_text, name_match_type, true);

  /* At this point scan through the misc symbol vectors and add each
     symbol you find to the list.  Eventually we want to ignore
     anything that isn't a text symbol (everything else will be
     handled by the psymtab code below).  */

  if (code == TYPE_CODE_UNDEF)
    {
      for (objfile *objfile : current_program_space->objfiles ())
	{
	  for (minimal_symbol *msymbol : objfile->msymbols ())
	    {
	      QUIT;

	      if (completion_skip_symbol (mode, msymbol))
		continue;

	      completion_list_add_msymbol (tracker, msymbol, lookup_name,
					   sym_text, word);

	      completion_list_objc_symbol (tracker, msymbol, lookup_name,
					   sym_text, word);
	    }
	}
    }

  /* Add completions for all currently loaded symbol tables.  */
  for (objfile *objfile : current_program_space->objfiles ())
    {
      for (compunit_symtab *cust : objfile->compunits ())
	add_symtab_completions (cust, tracker, mode, lookup_name,
				sym_text, word, code);
    }

  /* Look through the partial symtabs for all symbols which begin by
     matching SYM_TEXT.  Expand all CUs that you find to the list.  */
  expand_symtabs_matching (NULL,
			   lookup_name,
			   NULL,
			   [&] (compunit_symtab *symtab) /* expansion notify */
			     {
			       add_symtab_completions (symtab,
						       tracker, mode, lookup_name,
						       sym_text, word, code);
			       return true;
			     },
			   SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
			   SEARCH_ALL_DOMAINS);

  /* Search upwards from currently selected frame (so that we can
     complete on local vars).  Also catch fields of types defined in
     this places which match our text string.  Only complete on types
     visible from current context.  */

  b = get_selected_block (0);
  surrounding_static_block = b == nullptr ? nullptr : b->static_block ();
  surrounding_global_block = b == nullptr ? nullptr : b->global_block ();
  if (surrounding_static_block != NULL)
    while (b != surrounding_static_block)
      {
	QUIT;

	for (struct symbol *sym : block_iterator_range (b))
	  {
	    if (code == TYPE_CODE_UNDEF)
	      {
		completion_list_add_symbol (tracker, sym, lookup_name,
					    sym_text, word);
		completion_list_add_fields (tracker, sym, lookup_name,
					    sym_text, word);
	      }
	    else if (sym->domain () == STRUCT_DOMAIN
		     && sym->type ()->code () == code)
	      completion_list_add_symbol (tracker, sym, lookup_name,
					  sym_text, word);
	  }

	/* Stop when we encounter an enclosing function.  Do not stop for
	   non-inlined functions - the locals of the enclosing function
	   are in scope for a nested function.  */
	if (b->function () != NULL && b->inlined_p ())
	  break;
	b = b->superblock ();
      }

  /* Add fields from the file's types; symbols will be added below.  */

  if (code == TYPE_CODE_UNDEF)
    {
      if (surrounding_static_block != NULL)
	for (struct symbol *sym : block_iterator_range (surrounding_static_block))
	  completion_list_add_fields (tracker, sym, lookup_name,
				      sym_text, word);

      if (surrounding_global_block != NULL)
	for (struct symbol *sym : block_iterator_range (surrounding_global_block))
	  completion_list_add_fields (tracker, sym, lookup_name,
				      sym_text, word);
    }

  /* Skip macros if we are completing a struct tag -- arguable but
     usually what is expected.  */
  if (current_language->macro_expansion () == macro_expansion_c
      && code == TYPE_CODE_UNDEF)
    {
      gdb::unique_xmalloc_ptr<struct macro_scope> scope;

      /* This adds a macro's name to the current completion list.  */
      auto add_macro_name = [&] (const char *macro_name,
				 const macro_definition *,
				 macro_source_file *,
				 int)
	{
	  completion_list_add_name (tracker, language_c, macro_name,
				    lookup_name, sym_text, word);
	};

      /* Add any macros visible in the default scope.  Note that this
	 may yield the occasional wrong result, because an expression
	 might be evaluated in a scope other than the default.  For
	 example, if the user types "break file:line if <TAB>", the
	 resulting expression will be evaluated at "file:line" -- but
	 at there does not seem to be a way to detect this at
	 completion time.  */
      scope = default_macro_scope ();
      if (scope)
	macro_for_each_in_scope (scope->file, scope->line,
				 add_macro_name);

      /* User-defined macros are always visible.  */
      macro_for_each (macro_user_macros, add_macro_name);
    }
}

/* Collect all symbols (regardless of class) which begin by matching
   TEXT.  */

void
collect_symbol_completion_matches (completion_tracker &tracker,
				   complete_symbol_mode mode,
				   symbol_name_match_type name_match_type,
				   const char *text, const char *word)
{
  current_language->collect_symbol_completion_matches (tracker, mode,
						       name_match_type,
						       text, word,
						       TYPE_CODE_UNDEF);
}

/* Like collect_symbol_completion_matches, but only collect
   STRUCT_DOMAIN symbols whose type code is CODE.  */

void
collect_symbol_completion_matches_type (completion_tracker &tracker,
					const char *text, const char *word,
					enum type_code code)
{
  complete_symbol_mode mode = complete_symbol_mode::EXPRESSION;
  symbol_name_match_type name_match_type = symbol_name_match_type::EXPRESSION;

  gdb_assert (code == TYPE_CODE_UNION
	      || code == TYPE_CODE_STRUCT
	      || code == TYPE_CODE_ENUM);
  current_language->collect_symbol_completion_matches (tracker, mode,
						       name_match_type,
						       text, word, code);
}

/* Like collect_symbol_completion_matches, but collects a list of
   symbols defined in all source files named SRCFILE.  */

void
collect_file_symbol_completion_matches (completion_tracker &tracker,
					complete_symbol_mode mode,
					symbol_name_match_type name_match_type,
					const char *text, const char *word,
					const char *srcfile)
{
  /* The symbol we are completing on.  Points in same buffer as text.  */
  const char *sym_text;

  /* Now look for the symbol we are supposed to complete on.
     FIXME: This should be language-specific.  */
  if (mode == complete_symbol_mode::LINESPEC)
    sym_text = text;
  else
    {
      const char *p;
      char quote_found;
      const char *quote_pos = NULL;

      /* First see if this is a quoted string.  */
      quote_found = '\0';
      for (p = text; *p != '\0'; ++p)
	{
	  if (quote_found != '\0')
	    {
	      if (*p == quote_found)
		/* Found close quote.  */
		quote_found = '\0';
	      else if (*p == '\\' && p[1] == quote_found)
		/* A backslash followed by the quote character
		   doesn't end the string.  */
		++p;
	    }
	  else if (*p == '\'' || *p == '"')
	    {
	      quote_found = *p;
	      quote_pos = p;
	    }
	}
      if (quote_found == '\'')
	/* A string within single quotes can be a symbol, so complete on it.  */
	sym_text = quote_pos + 1;
      else if (quote_found == '"')
	/* A double-quoted string is never a symbol, nor does it make sense
	   to complete it any other way.  */
	{
	  return;
	}
      else
	{
	  /* Not a quoted string.  */
	  sym_text = language_search_unquoted_string (text, p);
	}
    }

  lookup_name_info lookup_name (sym_text, name_match_type, true);

  /* Go through symtabs for SRCFILE and check the externs and statics
     for symbols which match.  */
  iterate_over_symtabs (current_program_space, srcfile, [&] (symtab *s)
    {
      add_symtab_completions (s->compunit (),
			      tracker, mode, lookup_name,
			      sym_text, word, TYPE_CODE_UNDEF);
      return false;
    });
}

/* A helper function for make_source_files_completion_list.  It adds
   another file name to a list of possible completions, growing the
   list as necessary.  */

static void
add_filename_to_list (const char *fname, const char *text, const char *word,
		      completion_list *list)
{
  list->emplace_back (make_completion_match_str (fname, text, word));
}

static int
not_interesting_fname (const char *fname)
{
  static const char *illegal_aliens[] = {
    "_globals_",	/* inserted by coff_symtab_read */
    NULL
  };
  int i;

  for (i = 0; illegal_aliens[i]; i++)
    {
      if (filename_cmp (fname, illegal_aliens[i]) == 0)
	return 1;
    }
  return 0;
}

/* An object of this type is passed as the callback argument to
   map_partial_symbol_filenames.  */
struct add_partial_filename_data
{
  struct filename_seen_cache *filename_seen_cache;
  const char *text;
  const char *word;
  int text_len;
  completion_list *list;

  void operator() (const char *filename, const char *fullname);
};

/* A callback for map_partial_symbol_filenames.  */

void
add_partial_filename_data::operator() (const char *filename,
				       const char *fullname)
{
  if (not_interesting_fname (filename))
    return;
  if (!filename_seen_cache->seen (filename)
      && filename_ncmp (filename, text, text_len) == 0)
    {
      /* This file matches for a completion; add it to the
	 current list of matches.  */
      add_filename_to_list (filename, text, word, list);
    }
  else
    {
      const char *base_name = lbasename (filename);

      if (base_name != filename
	  && !filename_seen_cache->seen (base_name)
	  && filename_ncmp (base_name, text, text_len) == 0)
	add_filename_to_list (base_name, text, word, list);
    }
}

/* Return a list of all source files whose names begin with matching
   TEXT.  The file names are looked up in the symbol tables of this
   program.  */

completion_list
make_source_files_completion_list (const char *text, const char *word)
{
  size_t text_len = strlen (text);
  completion_list list;
  const char *base_name;
  struct add_partial_filename_data datum;

  if (!have_full_symbols (current_program_space)
      && !have_partial_symbols (current_program_space))
    return list;

  filename_seen_cache filenames_seen;

  for (objfile *objfile : current_program_space->objfiles ())
    {
      for (compunit_symtab *cu : objfile->compunits ())
	{
	  for (symtab *s : cu->filetabs ())
	    {
	      if (not_interesting_fname (s->filename))
		continue;
	      if (!filenames_seen.seen (s->filename)
		  && filename_ncmp (s->filename, text, text_len) == 0)
		{
		  /* This file matches for a completion; add it to the current
		     list of matches.  */
		  add_filename_to_list (s->filename, text, word, &list);
		}
	      else
		{
		  /* NOTE: We allow the user to type a base name when the
		     debug info records leading directories, but not the other
		     way around.  This is what subroutines of breakpoint
		     command do when they parse file names.  */
		  base_name = lbasename (s->filename);
		  if (base_name != s->filename
		      && !filenames_seen.seen (base_name)
		      && filename_ncmp (base_name, text, text_len) == 0)
		    add_filename_to_list (base_name, text, word, &list);
		}
	    }
	}
    }

  datum.filename_seen_cache = &filenames_seen;
  datum.text = text;
  datum.word = word;
  datum.text_len = text_len;
  datum.list = &list;
  map_symbol_filenames (datum, false /*need_fullname*/);

  return list;
}

/* Track MAIN */

/* Return the "main_info" object for the current program space.  If
   the object has not yet been created, create it and fill in some
   default values.  */

static main_info *
get_main_info (program_space *pspace)
{
  main_info *info = main_progspace_key.get (pspace);

  if (info == NULL)
    {
      /* It may seem strange to store the main name in the progspace
	 and also in whatever objfile happens to see a main name in
	 its debug info.  The reason for this is mainly historical:
	 gdb returned "main" as the name even if no function named
	 "main" was defined the program; and this approach lets us
	 keep compatibility.  */
      info = main_progspace_key.emplace (pspace);
    }

  return info;
}

static void
set_main_name (program_space *pspace, const char *name, enum language lang)
{
  main_info *info = get_main_info (pspace);

  if (!info->name_of_main.empty ())
    {
      info->name_of_main.clear ();
      info->language_of_main = language_unknown;
    }
  if (name != NULL)
    {
      info->name_of_main = name;
      info->language_of_main = lang;
    }
}

/* Deduce the name of the main procedure, and set NAME_OF_MAIN
   accordingly.  */

static void
find_main_name (void)
{
  const char *new_main_name;
  program_space *pspace = current_program_space;

  /* First check the objfiles to see whether a debuginfo reader has
     picked up the appropriate main name.  Historically the main name
     was found in a more or less random way; this approach instead
     relies on the order of objfile creation -- which still isn't
     guaranteed to get the correct answer, but is just probably more
     accurate.  */
  for (objfile *objfile : current_program_space->objfiles ())
    {
      objfile->compute_main_name ();

      if (objfile->per_bfd->name_of_main != NULL)
	{
	  set_main_name (pspace,
			 objfile->per_bfd->name_of_main,
			 objfile->per_bfd->language_of_main);
	  return;
	}
    }

  /* Try to see if the main procedure is in Ada.  */
  /* FIXME: brobecker/2005-03-07: Another way of doing this would
     be to add a new method in the language vector, and call this
     method for each language until one of them returns a non-empty
     name.  This would allow us to remove this hard-coded call to
     an Ada function.  It is not clear that this is a better approach
     at this point, because all methods need to be written in a way
     such that false positives never be returned.  For instance, it is
     important that a method does not return a wrong name for the main
     procedure if the main procedure is actually written in a different
     language.  It is easy to guaranty this with Ada, since we use a
     special symbol generated only when the main in Ada to find the name
     of the main procedure.  It is difficult however to see how this can
     be guaranteed for languages such as C, for instance.  This suggests
     that order of call for these methods becomes important, which means
     a more complicated approach.  */
  new_main_name = ada_main_name ();
  if (new_main_name != NULL)
    {
      set_main_name (pspace, new_main_name, language_ada);
      return;
    }

  new_main_name = d_main_name ();
  if (new_main_name != NULL)
    {
      set_main_name (pspace, new_main_name, language_d);
      return;
    }

  new_main_name = go_main_name ();
  if (new_main_name != NULL)
    {
      set_main_name (pspace, new_main_name, language_go);
      return;
    }

  new_main_name = pascal_main_name ();
  if (new_main_name != NULL)
    {
      set_main_name (pspace, new_main_name, language_pascal);
      return;
    }

  /* The languages above didn't identify the name of the main procedure.
     Fallback to "main".  */

  /* Try to find language for main in psymtabs.  */
  bool symbol_found_p = false;
  gdbarch_iterate_over_objfiles_in_search_order
    (current_inferior ()->arch (),
     [&symbol_found_p, pspace] (objfile *obj)
       {
	 language lang
	   = obj->lookup_global_symbol_language ("main",
						 SEARCH_FUNCTION_DOMAIN,
						 &symbol_found_p);
	 if (symbol_found_p)
	   {
	     set_main_name (pspace, "main", lang);
	     return 1;
	   }

	 return 0;
       }, nullptr);

  if (symbol_found_p)
    return;

  set_main_name (pspace, "main", language_unknown);
}

/* See symtab.h.  */

const char *
main_name ()
{
  main_info *info = get_main_info (current_program_space);

  if (info->name_of_main.empty ())
    find_main_name ();

  return info->name_of_main.c_str ();
}

/* Return the language of the main function.  If it is not known,
   return language_unknown.  */

enum language
main_language (void)
{
  main_info *info = get_main_info (current_program_space);

  if (info->name_of_main.empty ())
    find_main_name ();

  return info->language_of_main;
}



/* The next index to hand out in response to a registration request.  */

static int next_aclass_value = LOC_FINAL_VALUE;

/* The maximum number of "aclass" registrations we support.  This is
   constant for convenience.  */
#define MAX_SYMBOL_IMPLS (LOC_FINAL_VALUE + 11)

/* The objects representing the various "aclass" values.  The elements
   from 0 up to LOC_FINAL_VALUE-1 represent themselves, and subsequent
   elements are those registered at gdb initialization time.  */

static struct symbol_impl symbol_impl[MAX_SYMBOL_IMPLS];

/* The globally visible pointer.  This is separate from 'symbol_impl'
   so that it can be const.  */

gdb::array_view<const struct symbol_impl> symbol_impls (symbol_impl);

/* Make sure we saved enough room in struct symbol.  */

static_assert (MAX_SYMBOL_IMPLS <= (1 << SYMBOL_ACLASS_BITS));

/* Register a computed symbol type.  ACLASS must be LOC_COMPUTED.  OPS
   is the ops vector associated with this index.  This returns the new
   index, which should be used as the aclass_index field for symbols
   of this type.  */

int
register_symbol_computed_impl (enum address_class aclass,
			       const struct symbol_computed_ops *ops)
{
  int result = next_aclass_value++;

  gdb_assert (aclass == LOC_COMPUTED);
  gdb_assert (result < MAX_SYMBOL_IMPLS);
  symbol_impl[result].aclass = aclass;
  symbol_impl[result].ops_computed = ops;

  /* Sanity check OPS.  */
  gdb_assert (ops != NULL);
  gdb_assert (ops->tracepoint_var_ref != NULL);
  gdb_assert (ops->describe_location != NULL);
  gdb_assert (ops->get_symbol_read_needs != NULL);
  gdb_assert (ops->read_variable != NULL);

  return result;
}

/* Register a function with frame base type.  ACLASS must be LOC_BLOCK.
   OPS is the ops vector associated with this index.  This returns the
   new index, which should be used as the aclass_index field for symbols
   of this type.  */

int
register_symbol_block_impl (enum address_class aclass,
			    const struct symbol_block_ops *ops)
{
  int result = next_aclass_value++;

  gdb_assert (aclass == LOC_BLOCK);
  gdb_assert (result < MAX_SYMBOL_IMPLS);
  symbol_impl[result].aclass = aclass;
  symbol_impl[result].ops_block = ops;

  /* Sanity check OPS.  */
  gdb_assert (ops != NULL);
  gdb_assert (ops->find_frame_base_location != nullptr
	      || ops->get_block_value != nullptr);

  return result;
}

/* Register a register symbol type.  ACLASS must be LOC_REGISTER or
   LOC_REGPARM_ADDR.  OPS is the register ops vector associated with
   this index.  This returns the new index, which should be used as
   the aclass_index field for symbols of this type.  */

int
register_symbol_register_impl (enum address_class aclass,
			       const struct symbol_register_ops *ops)
{
  int result = next_aclass_value++;

  gdb_assert (aclass == LOC_REGISTER || aclass == LOC_REGPARM_ADDR);
  gdb_assert (result < MAX_SYMBOL_IMPLS);
  symbol_impl[result].aclass = aclass;
  symbol_impl[result].ops_register = ops;

  return result;
}

/* Initialize elements of 'symbol_impl' for the constants in enum
   address_class.  */

static void
initialize_ordinary_address_classes (void)
{
  int i;

  for (i = 0; i < LOC_FINAL_VALUE; ++i)
    symbol_impl[i].aclass = (enum address_class) i;
}



/* See symtab.h.  */

struct objfile *
symbol::objfile () const
{
  gdb_assert (is_objfile_owned ());
  return owner.symtab->compunit ()->objfile ();
}

/* See symtab.h.  */

struct gdbarch *
symbol::arch () const
{
  if (!is_objfile_owned ())
    return owner.arch;
  return owner.symtab->compunit ()->objfile ()->arch ();
}

/* See symtab.h.  */

struct symtab *
symbol::symtab () const
{
  gdb_assert (is_objfile_owned ());
  return owner.symtab;
}

/* See symtab.h.  */

void
symbol::set_symtab (struct symtab *symtab)
{
  gdb_assert (is_objfile_owned ());
  owner.symtab = symtab;
}

/* See symtab.h.  */

CORE_ADDR
symbol::get_maybe_copied_address () const
{
  gdb_assert (this->maybe_copied);
  gdb_assert (this->aclass () == LOC_STATIC);

  const char *linkage_name = this->linkage_name ();
  bound_minimal_symbol minsym
    = lookup_minimal_symbol_linkage (this->objfile ()->pspace (), linkage_name,
				     false, false);
  if (minsym.minsym != nullptr)
    return minsym.value_address ();

  return this->m_value.address;
}

/* See symtab.h.  */

CORE_ADDR
minimal_symbol::get_maybe_copied_address (objfile *objf) const
{
  gdb_assert (this->maybe_copied (objf));
  gdb_assert ((objf->flags & OBJF_MAINLINE) == 0);

  const char *linkage_name = this->linkage_name ();
  bound_minimal_symbol found
    = lookup_minimal_symbol_linkage (objf->pspace (), linkage_name,
				     false, true);
  if (found.minsym != nullptr)
    return found.value_address ();

  return (this->m_value.address
	  + objf->section_offsets[this->section_index ()]);
}



/* Hold the sub-commands of 'info module'.  */

static struct cmd_list_element *info_module_cmdlist = NULL;

/* See symtab.h.  */

std::vector<module_symbol_search>
search_module_symbols (const char *module_regexp, const char *regexp,
		       const char *type_regexp, domain_search_flags kind)
{
  std::vector<module_symbol_search> results;

  /* Search for all modules matching MODULE_REGEXP.  */
  global_symbol_searcher spec1 (SEARCH_MODULE_DOMAIN, module_regexp);
  spec1.set_exclude_minsyms (true);
  std::vector<symbol_search> modules = spec1.search ();

  /* Now search for all symbols of the required KIND matching the required
     regular expressions.  We figure out which ones are in which modules
     below.  */
  global_symbol_searcher spec2 (kind, regexp);
  spec2.set_symbol_type_regexp (type_regexp);
  spec2.set_exclude_minsyms (true);
  std::vector<symbol_search> symbols = spec2.search ();

  /* Now iterate over all MODULES, checking to see which items from
     SYMBOLS are in each module.  */
  for (const symbol_search &p : modules)
    {
      QUIT;

      /* This is a module.  */
      gdb_assert (p.symbol != nullptr);

      std::string prefix = p.symbol->print_name ();
      prefix += "::";

      for (const symbol_search &q : symbols)
	{
	  if (q.symbol == nullptr)
	    continue;

	  if (strncmp (q.symbol->print_name (), prefix.c_str (),
		       prefix.size ()) != 0)
	    continue;

	  results.push_back ({p, q});
	}
    }

  return results;
}

/* Implement the core of both 'info module functions' and 'info module
   variables'.  */

static void
info_module_subcommand (bool quiet, const char *module_regexp,
			const char *regexp, const char *type_regexp,
			domain_search_flags kind)
{
  gdb_assert (kind == SEARCH_FUNCTION_DOMAIN || kind == SEARCH_VAR_DOMAIN);

  /* Print a header line.  Don't build the header line bit by bit as this
     prevents internationalisation.  */
  if (!quiet)
    {
      if (module_regexp == nullptr)
	{
	  if (type_regexp == nullptr)
	    {
	      if (regexp == nullptr)
		gdb_printf ((kind == SEARCH_VAR_DOMAIN
			     ? _("All variables in all modules:")
			     : _("All functions in all modules:")));
	      else
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables matching regular expression"
			" \"%s\" in all modules:")
		    : _("All functions matching regular expression"
			" \"%s\" in all modules:")),
		   regexp);
	    }
	  else
	    {
	      if (regexp == nullptr)
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables with type matching regular "
			"expression \"%s\" in all modules:")
		    : _("All functions with type matching regular "
			"expression \"%s\" in all modules:")),
		   type_regexp);
	      else
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables matching regular expression "
			"\"%s\",\n\twith type matching regular "
			"expression \"%s\" in all modules:")
		    : _("All functions matching regular expression "
			"\"%s\",\n\twith type matching regular "
			"expression \"%s\" in all modules:")),
		   regexp, type_regexp);
	    }
	}
      else
	{
	  if (type_regexp == nullptr)
	    {
	      if (regexp == nullptr)
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables in all modules matching regular "
			"expression \"%s\":")
		    : _("All functions in all modules matching regular "
			"expression \"%s\":")),
		   module_regexp);
	      else
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables matching regular expression "
			"\"%s\",\n\tin all modules matching regular "
			"expression \"%s\":")
		    : _("All functions matching regular expression "
			"\"%s\",\n\tin all modules matching regular "
			"expression \"%s\":")),
		   regexp, module_regexp);
	    }
	  else
	    {
	      if (regexp == nullptr)
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables with type matching regular "
			"expression \"%s\"\n\tin all modules matching "
			"regular expression \"%s\":")
		    : _("All functions with type matching regular "
			"expression \"%s\"\n\tin all modules matching "
			"regular expression \"%s\":")),
		   type_regexp, module_regexp);
	      else
		gdb_printf
		  ((kind == SEARCH_VAR_DOMAIN
		    ? _("All variables matching regular expression "
			"\"%s\",\n\twith type matching regular expression "
			"\"%s\",\n\tin all modules matching regular "
			"expression \"%s\":")
		    : _("All functions matching regular expression "
			"\"%s\",\n\twith type matching regular expression "
			"\"%s\",\n\tin all modules matching regular "
			"expression \"%s\":")),
		   regexp, type_regexp, module_regexp);
	    }
	}
      gdb_printf ("\n");
    }

  /* Find all symbols of type KIND matching the given regular expressions
     along with the symbols for the modules in which those symbols
     reside.  */
  std::vector<module_symbol_search> module_symbols
    = search_module_symbols (module_regexp, regexp, type_regexp, kind);

  std::sort (module_symbols.begin (), module_symbols.end (),
	     [] (const module_symbol_search &a, const module_symbol_search &b)
	     {
	       if (a.first < b.first)
		 return true;
	       else if (a.first == b.first)
		 return a.second < b.second;
	       else
		 return false;
	     });

  const char *last_filename = "";
  const symbol *last_module_symbol = nullptr;
  for (const module_symbol_search &ms : module_symbols)
    {
      const symbol_search &p = ms.first;
      const symbol_search &q = ms.second;

      gdb_assert (q.symbol != nullptr);

      if (last_module_symbol != p.symbol)
	{
	  gdb_printf ("\n");
	  gdb_printf (_("Module \"%s\":\n"), p.symbol->print_name ());
	  last_module_symbol = p.symbol;
	  last_filename = "";
	}

      print_symbol_info (q.symbol, q.block, last_filename);
      last_filename
	= symtab_to_filename_for_display (q.symbol->symtab ());
    }
}

/* Hold the option values for the 'info module .....' sub-commands.  */

struct info_modules_var_func_options
{
  bool quiet = false;
  std::string type_regexp;
  std::string module_regexp;
};

/* The options used by 'info module variables' and 'info module functions'
   commands.  */

static const gdb::option::option_def info_modules_var_func_options_defs [] = {
  gdb::option::boolean_option_def<info_modules_var_func_options> {
    "q",
    [] (info_modules_var_func_options *opt) { return &opt->quiet; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  },

  gdb::option::string_option_def<info_modules_var_func_options> {
    "t",
    [] (info_modules_var_func_options *opt) { return &opt->type_regexp; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  },

  gdb::option::string_option_def<info_modules_var_func_options> {
    "m",
    [] (info_modules_var_func_options *opt) { return &opt->module_regexp; },
    nullptr, /* show_cmd_cb */
    nullptr /* set_doc */
  }
};

/* Return the option group used by the 'info module ...' sub-commands.  */

static inline gdb::option::option_def_group
make_info_modules_var_func_options_def_group
	(info_modules_var_func_options *opts)
{
  return {{info_modules_var_func_options_defs}, opts};
}

/* Implements the 'info module functions' command.  */

static void
info_module_functions_command (const char *args, int from_tty)
{
  info_modules_var_func_options opts;
  auto grp = make_info_modules_var_func_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
  if (args != nullptr && *args == '\0')
    args = nullptr;

  info_module_subcommand
    (opts.quiet,
     opts.module_regexp.empty () ? nullptr : opts.module_regexp.c_str (), args,
     opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
     SEARCH_FUNCTION_DOMAIN);
}

/* Implements the 'info module variables' command.  */

static void
info_module_variables_command (const char *args, int from_tty)
{
  info_modules_var_func_options opts;
  auto grp = make_info_modules_var_func_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
  if (args != nullptr && *args == '\0')
    args = nullptr;

  info_module_subcommand
    (opts.quiet,
     opts.module_regexp.empty () ? nullptr : opts.module_regexp.c_str (), args,
     opts.type_regexp.empty () ? nullptr : opts.type_regexp.c_str (),
     SEARCH_VAR_DOMAIN);
}

/* Command completer for 'info module ...' sub-commands.  */

static void
info_module_var_func_command_completer (struct cmd_list_element *ignore,
					completion_tracker &tracker,
					const char *text,
					const char * /* word */)
{

  const auto group = make_info_modules_var_func_options_def_group (nullptr);
  if (gdb::option::complete_options
      (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group))
    return;

  const char *word = advance_to_expression_complete_word_point (tracker, text);
  symbol_completer (ignore, tracker, text, word);
}



void _initialize_symtab ();
void
_initialize_symtab ()
{
  cmd_list_element *c;

  initialize_ordinary_address_classes ();

  c = add_info ("variables", info_variables_command,
		info_print_args_help (_("\
All global and static variable names or those matching REGEXPs.\n\
Usage: info variables [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the global and static variables.\n"),
				      _("global and static variables"),
				      true));
  set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);

  c = add_info ("functions", info_functions_command,
		info_print_args_help (_("\
All function names or those matching REGEXPs.\n\
Usage: info functions [-q] [-n] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the functions.\n"),
				      _("functions"),
				      true));
  set_cmd_completer_handle_brkchars (c, info_vars_funcs_command_completer);

  c = add_info ("types", info_types_command, _("\
All type names, or those matching REGEXP.\n\
Usage: info types [-q] [REGEXP]\n\
Print information about all types matching REGEXP, or all types if no\n\
REGEXP is given.  The optional flag -q disables printing of headers."));
  set_cmd_completer_handle_brkchars (c, info_types_command_completer);

  const auto info_sources_opts
    = make_info_sources_options_def_group (nullptr);

  static std::string info_sources_help
    = gdb::option::build_help (_("\
All source files in the program or those matching REGEXP.\n\
Usage: info sources [OPTION]... [REGEXP]\n\
By default, REGEXP is used to match anywhere in the filename.\n\
\n\
Options:\n\
%OPTIONS%"),
			       info_sources_opts);

  c = add_info ("sources", info_sources_command, info_sources_help.c_str ());
  set_cmd_completer_handle_brkchars (c, info_sources_command_completer);

  c = add_info ("modules", info_modules_command,
		_("All module names, or those matching REGEXP."));
  set_cmd_completer_handle_brkchars (c, info_types_command_completer);

  add_info ("main", info_main_command,
	    _("Get main symbol to identify entry point into program."));

  add_basic_prefix_cmd ("module", class_info, _("\
Print information about modules."),
			&info_module_cmdlist, 0, &infolist);

  c = add_cmd ("functions", class_info, info_module_functions_command, _("\
Display functions arranged by modules.\n\
Usage: info module functions [-q] [-m MODREGEXP] [-t TYPEREGEXP] [REGEXP]\n\
Print a summary of all functions within each Fortran module, grouped by\n\
module and file.  For each function the line on which the function is\n\
defined is given along with the type signature and name of the function.\n\
\n\
If REGEXP is provided then only functions whose name matches REGEXP are\n\
listed.  If MODREGEXP is provided then only functions in modules matching\n\
MODREGEXP are listed.  If TYPEREGEXP is given then only functions whose\n\
type signature matches TYPEREGEXP are listed.\n\
\n\
The -q flag suppresses printing some header information."),
	       &info_module_cmdlist);
  set_cmd_completer_handle_brkchars
    (c, info_module_var_func_command_completer);

  c = add_cmd ("variables", class_info, info_module_variables_command, _("\
Display variables arranged by modules.\n\
Usage: info module variables [-q] [-m MODREGEXP] [-t TYPEREGEXP] [REGEXP]\n\
Print a summary of all variables within each Fortran module, grouped by\n\
module and file.  For each variable the line on which the variable is\n\
defined is given along with the type and name of the variable.\n\
\n\
If REGEXP is provided then only variables whose name matches REGEXP are\n\
listed.  If MODREGEXP is provided then only variables in modules matching\n\
MODREGEXP are listed.  If TYPEREGEXP is given then only variables whose\n\
type matches TYPEREGEXP are listed.\n\
\n\
The -q flag suppresses printing some header information."),
	       &info_module_cmdlist);
  set_cmd_completer_handle_brkchars
    (c, info_module_var_func_command_completer);

  add_com ("rbreak", class_breakpoint, rbreak_command,
	   _("Set a breakpoint for all functions matching REGEXP."));

  add_setshow_enum_cmd ("multiple-symbols", no_class,
			multiple_symbols_modes, &multiple_symbols_mode,
			_("\
Set how the debugger handles ambiguities in expressions."), _("\
Show how the debugger handles ambiguities in expressions."), _("\
Valid values are \"ask\", \"all\", \"cancel\", and the default is \"all\"."),
			NULL, NULL, &setlist, &showlist);

  add_setshow_boolean_cmd ("basenames-may-differ", class_obscure,
			   &basenames_may_differ, _("\
Set whether a source file may have multiple base names."), _("\
Show whether a source file may have multiple base names."), _("\
(A \"base name\" is the name of a file with the directory part removed.\n\
Example: The base name of \"/home/user/hello.c\" is \"hello.c\".)\n\
If set, GDB will canonicalize file names (e.g., expand symlinks)\n\
before comparing them.  Canonicalization is an expensive operation,\n\
but it allows the same file be known by more than one base name.\n\
If not set (the default), all source files are assumed to have just\n\
one base name, and gdb will do file name comparisons more efficiently."),
			   NULL, NULL,
			   &setlist, &showlist);

  add_setshow_zuinteger_cmd ("symtab-create", no_class, &symtab_create_debug,
			     _("Set debugging of symbol table creation."),
			     _("Show debugging of symbol table creation."), _("\
When enabled (non-zero), debugging messages are printed when building\n\
symbol tables.  A value of 1 (one) normally provides enough information.\n\
A value greater than 1 provides more verbose information."),
			     NULL,
			     NULL,
			     &setdebuglist, &showdebuglist);

  add_setshow_zuinteger_cmd ("symbol-lookup", no_class, &symbol_lookup_debug,
			   _("\
Set debugging of symbol lookup."), _("\
Show debugging of symbol lookup."), _("\
When enabled (non-zero), symbol lookups are logged."),
			   NULL, NULL,
			   &setdebuglist, &showdebuglist);

  add_setshow_zuinteger_cmd ("symbol-cache-size", no_class,
			     &new_symbol_cache_size,
			     _("Set the size of the symbol cache."),
			     _("Show the size of the symbol cache."), _("\
The size of the symbol cache.\n\
If zero then the symbol cache is disabled."),
			     set_symbol_cache_size_handler, NULL,
			     &maintenance_set_cmdlist,
			     &maintenance_show_cmdlist);

  add_setshow_boolean_cmd ("ignore-prologue-end-flag", no_class,
			   &ignore_prologue_end_flag,
			   _("Set if the PROLOGUE-END flag is ignored."),
			   _("Show if the PROLOGUE-END flag is ignored."),
			   _("\
The PROLOGUE-END flag from the line-table entries is used to place\n\
breakpoints past the prologue of functions.  Disabling its use forces\n\
the use of prologue scanners."),
			   nullptr, nullptr,
			   &maintenance_set_cmdlist,
			   &maintenance_show_cmdlist);


  add_cmd ("symbol-cache", class_maintenance, maintenance_print_symbol_cache,
	   _("Dump the symbol cache for each program space."),
	   &maintenanceprintlist);

  add_cmd ("symbol-cache-statistics", class_maintenance,
	   maintenance_print_symbol_cache_statistics,
	   _("Print symbol cache statistics for each program space."),
	   &maintenanceprintlist);

  cmd_list_element *maintenance_flush_symbol_cache_cmd
    = add_cmd ("symbol-cache", class_maintenance,
	       maintenance_flush_symbol_cache,
	       _("Flush the symbol cache for each program space."),
	       &maintenanceflushlist);
  c = add_alias_cmd ("flush-symbol-cache", maintenance_flush_symbol_cache_cmd,
		     class_maintenance, 0, &maintenancelist);
  deprecate_cmd (c, "maintenance flush symbol-cache");

  gdb::observers::new_objfile.attach (symtab_new_objfile_observer, "symtab");
  gdb::observers::all_objfiles_removed.attach (symtab_all_objfiles_removed,
					       "symtab");
  gdb::observers::free_objfile.attach (symtab_free_objfile_observer, "symtab");
}
