/* Support routines for building symbol tables in GDB's internal format.
   Copyright (C) 1986-2023 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 "defs.h"
#include "buildsym-legacy.h"
#include "bfd.h"
#include "gdbsupport/gdb_obstack.h"
#include "gdbsupport/pathstuff.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "complaints.h"
#include "expression.h"		/* For "enum exp_opcode" used by...  */
#include "filenames.h"		/* For DOSish file names.  */
#include "macrotab.h"
#include "demangle.h"		/* Needed by SYMBOL_INIT_DEMANGLED_NAME.  */
#include "block.h"
#include "cp-support.h"
#include "dictionary.h"
#include <algorithm>

/* For cleanup_undefined_stabs_types and finish_global_stabs (somewhat
   questionable--see comment where we call them).  */

#include "stabsread.h"

/* List of blocks already made (lexical contexts already closed).
   This is used at the end to make the blockvector.  */

struct pending_block
  {
    struct pending_block *next;
    struct block *block;
  };

buildsym_compunit::buildsym_compunit (struct objfile *objfile_,
				      const char *name,
				      const char *comp_dir_,
				      const char *name_for_id,
				      enum language language_,
				      CORE_ADDR last_addr)
  : m_objfile (objfile_),
    m_last_source_file (name == nullptr ? nullptr : xstrdup (name)),
    m_comp_dir (comp_dir_ == nullptr ? "" : comp_dir_),
    m_language (language_),
    m_last_source_start_addr (last_addr)
{
  /* Allocate the compunit symtab now.  The caller needs it to allocate
     non-primary symtabs.  It is also needed by get_macro_table.  */
  m_compunit_symtab = allocate_compunit_symtab (m_objfile, name);

  /* Build the subfile for NAME (the main source file) so that we can record
     a pointer to it for later.
     IMPORTANT: Do not allocate a struct symtab for NAME here.
     It can happen that the debug info provides a different path to NAME than
     DIRNAME,NAME.  We cope with this in watch_main_source_file_lossage but
     that only works if the main_subfile doesn't have a symtab yet.  */
  start_subfile (name, name_for_id);
  /* Save this so that we don't have to go looking for it at the end
     of the subfiles list.  */
  m_main_subfile = m_current_subfile;
}

buildsym_compunit::~buildsym_compunit ()
{
  struct subfile *subfile, *nextsub;

  if (m_pending_macros != nullptr)
    free_macro_table (m_pending_macros);

  for (subfile = m_subfiles;
       subfile != NULL;
       subfile = nextsub)
    {
      nextsub = subfile->next;
      delete subfile;
    }

  struct pending *next, *next1;

  for (next = m_file_symbols; next != NULL; next = next1)
    {
      next1 = next->next;
      xfree ((void *) next);
    }

  for (next = m_global_symbols; next != NULL; next = next1)
    {
      next1 = next->next;
      xfree ((void *) next);
    }
}

struct macro_table *
buildsym_compunit::get_macro_table ()
{
  if (m_pending_macros == nullptr)
    m_pending_macros = new_macro_table (&m_objfile->per_bfd->storage_obstack,
					&m_objfile->per_bfd->string_cache,
					m_compunit_symtab);
  return m_pending_macros;
}

/* Maintain the lists of symbols and blocks.  */

/* Add a symbol to one of the lists of symbols.  */

void
add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
{
  struct pending *link;

  /* If this is an alias for another symbol, don't add it.  */
  if (symbol->linkage_name () && symbol->linkage_name ()[0] == '#')
    return;

  /* We keep PENDINGSIZE symbols in each link of the list.  If we
     don't have a link with room in it, add a new link.  */
  if (*listhead == NULL || (*listhead)->nsyms == PENDINGSIZE)
    {
      link = XNEW (struct pending);
      link->next = *listhead;
      *listhead = link;
      link->nsyms = 0;
    }

  (*listhead)->symbol[(*listhead)->nsyms++] = symbol;
}

/* Find a symbol named NAME on a LIST.  NAME need not be
   '\0'-terminated; LENGTH is the length of the name.  */

struct symbol *
find_symbol_in_list (struct pending *list, char *name, int length)
{
  int j;
  const char *pp;

  while (list != NULL)
    {
      for (j = list->nsyms; --j >= 0;)
	{
	  pp = list->symbol[j]->linkage_name ();
	  if (*pp == *name && strncmp (pp, name, length) == 0
	      && pp[length] == '\0')
	    {
	      return (list->symbol[j]);
	    }
	}
      list = list->next;
    }
  return (NULL);
}

/* Record BLOCK on the list of all blocks in the file.  Put it after
   OPBLOCK, or at the beginning if opblock is NULL.  This puts the
   block in the list after all its subblocks.  */

void
buildsym_compunit::record_pending_block (struct block *block,
					 struct pending_block *opblock)
{
  struct pending_block *pblock;

  pblock = XOBNEW (&m_pending_block_obstack, struct pending_block);
  pblock->block = block;
  if (opblock)
    {
      pblock->next = opblock->next;
      opblock->next = pblock;
    }
  else
    {
      pblock->next = m_pending_blocks;
      m_pending_blocks = pblock;
    }
}

/* Take one of the lists of symbols and make a block from it.  Keep
   the order the symbols have in the list (reversed from the input
   file).  Put the block on the list of pending blocks.  */

struct block *
buildsym_compunit::finish_block_internal
    (struct symbol *symbol,
     struct pending **listhead,
     struct pending_block *old_blocks,
     const struct dynamic_prop *static_link,
     CORE_ADDR start, CORE_ADDR end,
     int is_global, int expandable)
{
  struct gdbarch *gdbarch = m_objfile->arch ();
  struct pending *next, *next1;
  struct block *block;
  struct pending_block *pblock;
  struct pending_block *opblock;

  if (is_global)
    block = new (&m_objfile->objfile_obstack) global_block;
  else
    block = new (&m_objfile->objfile_obstack) struct block;

  if (symbol)
    {
      block->set_multidict
	(mdict_create_linear (&m_objfile->objfile_obstack, *listhead));
    }
  else
    {
      if (expandable)
	{
	  block->set_multidict
	    (mdict_create_hashed_expandable (m_language));
	  mdict_add_pending (block->multidict (), *listhead);
	}
      else
	{
	  block->set_multidict
	    (mdict_create_hashed (&m_objfile->objfile_obstack, *listhead));
	}
    }

  block->set_start (start);
  block->set_end (end);

  /* Put the block in as the value of the symbol that names it.  */

  if (symbol)
    {
      struct type *ftype = symbol->type ();
      struct mdict_iterator miter;
      symbol->set_value_block (block);
      symbol->set_section_index (SECT_OFF_TEXT (m_objfile));
      block->set_function (symbol);

      if (ftype->num_fields () <= 0)
	{
	  /* No parameter type information is recorded with the
	     function's type.  Set that from the type of the
	     parameter symbols.  */
	  int nparams = 0, iparams;
	  struct symbol *sym;

	  /* Here we want to directly access the dictionary, because
	     we haven't fully initialized the block yet.  */
	  ALL_DICT_SYMBOLS (block->multidict (), miter, sym)
	    {
	      if (sym->is_argument ())
		nparams++;
	    }
	  if (nparams > 0)
	    {
	      ftype->set_num_fields (nparams);
	      ftype->set_fields
		((struct field *)
		 TYPE_ALLOC (ftype, nparams * sizeof (struct field)));

	      iparams = 0;
	      /* Here we want to directly access the dictionary, because
		 we haven't fully initialized the block yet.  */
	      ALL_DICT_SYMBOLS (block->multidict (), miter, sym)
		{
		  if (iparams == nparams)
		    break;

		  if (sym->is_argument ())
		    {
		      ftype->field (iparams).set_type (sym->type ());
		      TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
		      iparams++;
		    }
		}
	    }
	}
    }
  else
    block->set_function (nullptr);

  if (static_link != NULL)
    objfile_register_static_link (m_objfile, block, static_link);

  /* Now free the links of the list, and empty the list.  */

  for (next = *listhead; next; next = next1)
    {
      next1 = next->next;
      xfree (next);
    }
  *listhead = NULL;

  /* Check to be sure that the blocks have an end address that is
     greater than starting address.  */

  if (block->end () < block->start ())
    {
      if (symbol)
	{
	  complaint (_("block end address less than block "
		       "start address in %s (patched it)"),
		     symbol->print_name ());
	}
      else
	{
	  complaint (_("block end address %s less than block "
		       "start address %s (patched it)"),
		     paddress (gdbarch, block->end ()),
		     paddress (gdbarch, block->start ()));
	}
      /* Better than nothing.  */
      block->set_end (block->start ());
    }

  /* Install this block as the superblock of all blocks made since the
     start of this scope that don't have superblocks yet.  */

  opblock = NULL;
  for (pblock = m_pending_blocks;
       pblock && pblock != old_blocks; 
       pblock = pblock->next)
    {
      if (pblock->block->superblock () == NULL)
	{
	  /* Check to be sure the blocks are nested as we receive
	     them.  If the compiler/assembler/linker work, this just
	     burns a small amount of time.

	     Skip blocks which correspond to a function; they're not
	     physically nested inside this other blocks, only
	     lexically nested.  */
	  if (pblock->block->function () == NULL
	      && (pblock->block->start () < block->start ()
		  || pblock->block->end () > block->end ()))
	    {
	      if (symbol)
		{
		  complaint (_("inner block not inside outer block in %s"),
			     symbol->print_name ());
		}
	      else
		{
		  complaint (_("inner block (%s-%s) not "
			       "inside outer block (%s-%s)"),
			     paddress (gdbarch, pblock->block->start ()),
			     paddress (gdbarch, pblock->block->end ()),
			     paddress (gdbarch, block->start ()),
			     paddress (gdbarch, block->end ()));
		}

	      if (pblock->block->start () < block->start ())
		pblock->block->set_start (block->start ());

	      if (pblock->block->end () > block->end ())
		pblock->block->set_end (block->end ());
	    }
	  pblock->block->set_superblock (block);
	}
      opblock = pblock;
    }

  block->set_using ((is_global
		     ? m_global_using_directives
		     : m_local_using_directives),
		    &m_objfile->objfile_obstack);
  if (is_global)
    m_global_using_directives = NULL;
  else
    m_local_using_directives = NULL;

  record_pending_block (block, opblock);

  return block;
}

struct block *
buildsym_compunit::finish_block (struct symbol *symbol,
				 struct pending_block *old_blocks,
				 const struct dynamic_prop *static_link,
				 CORE_ADDR start, CORE_ADDR end)
{
  return finish_block_internal (symbol, &m_local_symbols,
				old_blocks, static_link, start, end, 0, 0);
}

/* Record that the range of addresses from START to END_INCLUSIVE
   (inclusive, like it says) belongs to BLOCK.  BLOCK's start and end
   addresses must be set already.  You must apply this function to all
   BLOCK's children before applying it to BLOCK.

   If a call to this function complicates the picture beyond that
   already provided by BLOCK_START and BLOCK_END, then we create an
   address map for the block.  */
void
buildsym_compunit::record_block_range (struct block *block,
				       CORE_ADDR start,
				       CORE_ADDR end_inclusive)
{
  /* If this is any different from the range recorded in the block's
     own BLOCK_START and BLOCK_END, then note that the address map has
     become interesting.  Note that even if this block doesn't have
     any "interesting" ranges, some later block might, so we still
     need to record this block in the addrmap.  */
  if (start != block->start ()
      || end_inclusive + 1 != block->end ())
    m_pending_addrmap_interesting = true;

  m_pending_addrmap.set_empty (start, end_inclusive, block);
}

struct blockvector *
buildsym_compunit::make_blockvector ()
{
  struct pending_block *next;
  struct blockvector *blockvector;
  int i;

  /* Count the length of the list of blocks.  */

  for (next = m_pending_blocks, i = 0; next; next = next->next, i++)
    {
    }

  blockvector = (struct blockvector *)
    obstack_alloc (&m_objfile->objfile_obstack,
		   (sizeof (struct blockvector)
		    + (i - 1) * sizeof (struct block *)));

  /* Copy the blocks into the blockvector.  This is done in reverse
     order, which happens to put the blocks into the proper order
     (ascending starting address).  finish_block has hair to insert
     each block into the list after its subblocks in order to make
     sure this is true.  */

  blockvector->set_num_blocks (i);
  for (next = m_pending_blocks; next; next = next->next)
    blockvector->set_block (--i, next->block);

  free_pending_blocks ();

  /* If we needed an address map for this symtab, record it in the
     blockvector.  */
  if (m_pending_addrmap_interesting)
    blockvector->set_map
      (new (&m_objfile->objfile_obstack) addrmap_fixed
       (&m_objfile->objfile_obstack, &m_pending_addrmap));
  else
    blockvector->set_map (nullptr);

  /* Some compilers output blocks in the wrong order, but we depend on
     their being in the right order so we can binary search.  Check the
     order and moan about it.
     Note: Remember that the first two blocks are the global and static
     blocks.  We could special case that fact and begin checking at block 2.
     To avoid making that assumption we do not.  */
  if (blockvector->num_blocks () > 1)
    {
      for (i = 1; i < blockvector->num_blocks (); i++)
	{
	  if (blockvector->block (i - 1)->start ()
	      > blockvector->block (i)->start ())
	    {
	      CORE_ADDR start
		= blockvector->block (i)->start ();

	      complaint (_("block at %s out of order"),
			 hex_string ((LONGEST) start));
	    }
	}
    }

  return (blockvector);
}

/* See buildsym.h.  */

void
buildsym_compunit::start_subfile (const char *name, const char *name_for_id)
{
  /* See if this subfile is already registered.  */

  symtab_create_debug_printf ("name = %s, name_for_id = %s", name, name_for_id);

  for (subfile *subfile = m_subfiles; subfile; subfile = subfile->next)
    if (FILENAME_CMP (subfile->name_for_id.c_str (), name_for_id) == 0)
      {
	symtab_create_debug_printf ("found existing symtab with name_for_id %s",
				    subfile->name_for_id.c_str ());
	m_current_subfile = subfile;
	return;
      }

  /* This subfile is not known.  Add an entry for it.  */

  subfile_up subfile (new struct subfile);
  subfile->name = name;
  subfile->name_for_id = name_for_id;

  m_current_subfile = subfile.get ();

  /* Default the source language to whatever can be deduced from the
     filename.  If nothing can be deduced (such as for a C/C++ include
     file with a ".h" extension), then inherit whatever language the
     previous subfile had.  This kludgery is necessary because there
     is no standard way in some object formats to record the source
     language.  Also, when symtabs are allocated we try to deduce a
     language then as well, but it is too late for us to use that
     information while reading symbols, since symtabs aren't allocated
     until after all the symbols have been processed for a given
     source file.  */

  subfile->language = deduce_language_from_filename (subfile->name.c_str ());
  if (subfile->language == language_unknown && m_subfiles != nullptr)
    subfile->language = m_subfiles->language;

  /* If the filename of this subfile ends in .C, then change the
     language of any pending subfiles from C to C++.  We also accept
     any other C++ suffixes accepted by deduce_language_from_filename.  */
  /* Likewise for f2c.  */

  if (!subfile->name.empty ())
    {
      struct subfile *s;
      language sublang = deduce_language_from_filename (subfile->name.c_str ());

      if (sublang == language_cplus || sublang == language_fortran)
	for (s = m_subfiles; s != NULL; s = s->next)
	  if (s->language == language_c)
	    s->language = sublang;
    }

  /* And patch up this file if necessary.  */
  if (subfile->language == language_c
      && m_subfiles != nullptr
      && (m_subfiles->language == language_cplus
	  || m_subfiles->language == language_fortran))
    subfile->language = m_subfiles->language;

  /* Link this subfile at the front of the subfile list.  */
  subfile->next = m_subfiles;
  m_subfiles = subfile.release ();
}

/* For stabs readers, the first N_SO symbol is assumed to be the
   source file name, and the subfile struct is initialized using that
   assumption.  If another N_SO symbol is later seen, immediately
   following the first one, then the first one is assumed to be the
   directory name and the second one is really the source file name.

   So we have to patch up the subfile struct by moving the old name
   value to dirname and remembering the new name.  Some sanity
   checking is performed to ensure that the state of the subfile
   struct is reasonable and that the old name we are assuming to be a
   directory name actually is (by checking for a trailing '/').  */

void
buildsym_compunit::patch_subfile_names (struct subfile *subfile,
					const char *name)
{
  if (subfile != NULL
      && m_comp_dir.empty ()
      && !subfile->name.empty ()
      && IS_DIR_SEPARATOR (subfile->name.back ()))
    {
      m_comp_dir = std::move (subfile->name);
      subfile->name = name;
      subfile->name_for_id = name;
      set_last_source_file (name);

      /* Default the source language to whatever can be deduced from
	 the filename.  If nothing can be deduced (such as for a C/C++
	 include file with a ".h" extension), then inherit whatever
	 language the previous subfile had.  This kludgery is
	 necessary because there is no standard way in some object
	 formats to record the source language.  Also, when symtabs
	 are allocated we try to deduce a language then as well, but
	 it is too late for us to use that information while reading
	 symbols, since symtabs aren't allocated until after all the
	 symbols have been processed for a given source file.  */

      subfile->language
	= deduce_language_from_filename (subfile->name.c_str ());
      if (subfile->language == language_unknown
	  && subfile->next != NULL)
	{
	  subfile->language = subfile->next->language;
	}
    }
}

/* Handle the N_BINCL and N_EINCL symbol types that act like N_SOL for
   switching source files (different subfiles, as we call them) within
   one object file, but using a stack rather than in an arbitrary
   order.  */

void
buildsym_compunit::push_subfile ()
{
  gdb_assert (m_current_subfile != NULL);
  gdb_assert (!m_current_subfile->name.empty ());
  m_subfile_stack.push_back (m_current_subfile->name.c_str ());
}

const char *
buildsym_compunit::pop_subfile ()
{
  gdb_assert (!m_subfile_stack.empty ());
  const char *name = m_subfile_stack.back ();
  m_subfile_stack.pop_back ();
  return name;
}

/* Add a linetable entry for line number LINE and address PC to the
   line vector for SUBFILE.  */

void
buildsym_compunit::record_line (struct subfile *subfile, int line,
				unrelocated_addr pc, linetable_entry_flags flags)
{
  m_have_line_numbers = true;

  /* Normally, we treat lines as unsorted.  But the end of sequence
     marker is special.  We sort line markers at the same PC by line
     number, so end of sequence markers (which have line == 0) appear
     first.  This is right if the marker ends the previous function,
     and there is no padding before the next function.  But it is
     wrong if the previous line was empty and we are now marking a
     switch to a different subfile.  We must leave the end of sequence
     marker at the end of this group of lines, not sort the empty line
     to after the marker.  The easiest way to accomplish this is to
     delete any empty lines from our table, if they are followed by
     end of sequence markers.  All we lose is the ability to set
     breakpoints at some lines which contain no instructions
     anyway.  */
  if (line == 0)
    {
      gdb::optional<int> last_line;

      while (!subfile->line_vector_entries.empty ())
	{
	  linetable_entry *last = &subfile->line_vector_entries.back ();
	  last_line = last->line;

	  if (last->raw_pc () != pc)
	    break;

	  subfile->line_vector_entries.pop_back ();
	}

      /* Ignore an end-of-sequence marker marking an empty sequence.  */
      if (!last_line.has_value () || *last_line == 0)
	return;
    }

  subfile->line_vector_entries.emplace_back ();
  linetable_entry &e = subfile->line_vector_entries.back ();
  e.line = line;
  e.is_stmt = (flags & LEF_IS_STMT) != 0;
  e.set_raw_pc (pc);
  e.prologue_end = (flags & LEF_PROLOGUE_END) != 0;
}


/* Subroutine of end_compunit_symtab to simplify it.  Look for a subfile that
   matches the main source file's basename.  If there is only one, and
   if the main source file doesn't have any symbol or line number
   information, then copy this file's symtab and line_vector to the
   main source file's subfile and discard the other subfile.  This can
   happen because of a compiler bug or from the user playing games
   with #line or from things like a distributed build system that
   manipulates the debug info.  This can also happen from an innocent
   symlink in the paths, we don't canonicalize paths here.  */

void
buildsym_compunit::watch_main_source_file_lossage ()
{
  struct subfile *mainsub, *subfile;

  /* Get the main source file.  */
  mainsub = m_main_subfile;

  /* If the main source file doesn't have any line number or symbol
     info, look for an alias in another subfile.  */

  if (mainsub->line_vector_entries.empty ()
      && mainsub->symtab == NULL)
    {
      const char *mainbase = lbasename (mainsub->name.c_str ());
      int nr_matches = 0;
      struct subfile *prevsub;
      struct subfile *mainsub_alias = NULL;
      struct subfile *prev_mainsub_alias = NULL;

      prevsub = NULL;
      for (subfile = m_subfiles;
	   subfile != NULL;
	   subfile = subfile->next)
	{
	  if (subfile == mainsub)
	    continue;
	  if (filename_cmp (lbasename (subfile->name.c_str ()), mainbase) == 0)
	    {
	      ++nr_matches;
	      mainsub_alias = subfile;
	      prev_mainsub_alias = prevsub;
	    }
	  prevsub = subfile;
	}

      if (nr_matches == 1)
	{
	  gdb_assert (mainsub_alias != NULL && mainsub_alias != mainsub);

	  /* Found a match for the main source file.
	     Copy its line_vector and symtab to the main subfile
	     and then discard it.  */

	  symtab_create_debug_printf ("using subfile %s as the main subfile",
				      mainsub_alias->name.c_str ());

	  mainsub->line_vector_entries
	    = std::move (mainsub_alias->line_vector_entries);
	  mainsub->symtab = mainsub_alias->symtab;

	  if (prev_mainsub_alias == NULL)
	    m_subfiles = mainsub_alias->next;
	  else
	    prev_mainsub_alias->next = mainsub_alias->next;

	  delete mainsub_alias;
	}
    }
}

/* Implementation of the first part of end_compunit_symtab.  It allows modifying
   STATIC_BLOCK before it gets finalized by
   end_compunit_symtab_from_static_block.  If the returned value is NULL there
   is no blockvector created for this symtab (you still must call
   end_compunit_symtab_from_static_block).

   END_ADDR is the same as for end_compunit_symtab: the address of the end of
   the file's text.

   If EXPANDABLE is non-zero the STATIC_BLOCK dictionary is made
   expandable.

   If REQUIRED is non-zero, then a symtab is created even if it does
   not contain any symbols.  */

struct block *
buildsym_compunit::end_compunit_symtab_get_static_block (CORE_ADDR end_addr,
							 int expandable,
							 int required)
{
  /* Finish the lexical context of the last function in the file; pop
     the context stack.  */

  if (!m_context_stack.empty ())
    {
      struct context_stack cstk = pop_context ();

      /* Make a block for the local symbols within.  */
      finish_block (cstk.name, cstk.old_blocks, NULL,
		    cstk.start_addr, end_addr);

      if (!m_context_stack.empty ())
	{
	  /* This is said to happen with SCO.  The old coffread.c
	     code simply emptied the context stack, so we do the
	     same.  FIXME: Find out why it is happening.  This is not
	     believed to happen in most cases (even for coffread.c);
	     it used to be an abort().  */
	  complaint (_("Context stack not empty in end_compunit_symtab"));
	  m_context_stack.clear ();
	}
    }

  /* Executables may have out of order pending blocks; sort the
     pending blocks.  */
  if (m_pending_blocks != nullptr)
    {
      struct pending_block *pb;

      std::vector<block *> barray;

      for (pb = m_pending_blocks; pb != NULL; pb = pb->next)
	barray.push_back (pb->block);

      /* Sort blocks by start address in descending order.  Blocks with the
	 same start address must remain in the original order to preserve
	 inline function caller/callee relationships.  */
      std::stable_sort (barray.begin (), barray.end (),
			[] (const block *a, const block *b)
			{
			  return a->start () > b->start ();
			});

      int i = 0;
      for (pb = m_pending_blocks; pb != NULL; pb = pb->next)
	pb->block = barray[i++];
    }

  /* Cleanup any undefined types that have been left hanging around
     (this needs to be done before the finish_blocks so that
     file_symbols is still good).

     Both cleanup_undefined_stabs_types and finish_global_stabs are stabs
     specific, but harmless for other symbol readers, since on gdb
     startup or when finished reading stabs, the state is set so these
     are no-ops.  FIXME: Is this handled right in case of QUIT?  Can
     we make this cleaner?  */

  cleanup_undefined_stabs_types (m_objfile);
  finish_global_stabs (m_objfile);

  if (!required
      && m_pending_blocks == NULL
      && m_file_symbols == NULL
      && m_global_symbols == NULL
      && !m_have_line_numbers
      && m_pending_macros == NULL
      && m_global_using_directives == NULL)
    {
      /* Ignore symtabs that have no functions with real debugging info.  */
      return NULL;
    }
  else
    {
      /* Define the STATIC_BLOCK.  */
      return finish_block_internal (NULL, get_file_symbols (), NULL, NULL,
				    m_last_source_start_addr,
				    end_addr, 0, expandable);
    }
}

/* Subroutine of end_compunit_symtab_from_static_block to simplify it.
   Handle the "have blockvector" case.
   See end_compunit_symtab_from_static_block for a description of the
   arguments.  */

struct compunit_symtab *
buildsym_compunit::end_compunit_symtab_with_blockvector
  (struct block *static_block, int expandable)
{
  struct compunit_symtab *cu = m_compunit_symtab;
  struct blockvector *blockvector;
  struct subfile *subfile;
  CORE_ADDR end_addr;

  gdb_assert (static_block != NULL);
  gdb_assert (m_subfiles != NULL);

  end_addr = static_block->end ();

  /* Create the GLOBAL_BLOCK and build the blockvector.  */
  finish_block_internal (NULL, get_global_symbols (), NULL, NULL,
			 m_last_source_start_addr, end_addr,
			 1, expandable);
  blockvector = make_blockvector ();

  /* Read the line table if it has to be read separately.
     This is only used by xcoffread.c.  */
  if (m_objfile->sf->sym_read_linetable != NULL)
    m_objfile->sf->sym_read_linetable (m_objfile);

  /* Handle the case where the debug info specifies a different path
     for the main source file.  It can cause us to lose track of its
     line number information.  */
  watch_main_source_file_lossage ();

  /* Now create the symtab objects proper, if not already done,
     one for each subfile.  */

  for (subfile = m_subfiles;
       subfile != NULL;
       subfile = subfile->next)
    {
      if (!subfile->line_vector_entries.empty ())
	{
	  /* Like the pending blocks, the line table may be scrambled
	     in reordered executables.  Sort it.  It is important to
	     preserve the order of lines at the same address, as this
	     maintains the inline function caller/callee
	     relationships, this is why std::stable_sort is used.  */
	  std::stable_sort (subfile->line_vector_entries.begin (),
			    subfile->line_vector_entries.end ());
	}

      /* Allocate a symbol table if necessary.  */
      if (subfile->symtab == NULL)
	subfile->symtab = allocate_symtab (cu, subfile->name.c_str (),
					   subfile->name_for_id.c_str ());

      struct symtab *symtab = subfile->symtab;

      /* Fill in its components.  */

      if (!subfile->line_vector_entries.empty ())
	{
	  /* Reallocate the line table on the objfile obstack.  */
	  size_t n_entries = subfile->line_vector_entries.size ();
	  size_t entry_array_size = n_entries * sizeof (struct linetable_entry);
	  int linetablesize = sizeof (struct linetable) + entry_array_size;

	  struct linetable *new_table
	    = XOBNEWVAR (&m_objfile->objfile_obstack, struct linetable,
			 linetablesize);

	  new_table->nitems = n_entries;
	  memcpy (new_table->item,
		  subfile->line_vector_entries.data (), entry_array_size);

	  symtab->set_linetable (new_table);
	}
      else
	symtab->set_linetable (nullptr);

      /* Use whatever language we have been using for this
	 subfile, not the one that was deduced in allocate_symtab
	 from the filename.  We already did our own deducing when
	 we created the subfile, and we may have altered our
	 opinion of what language it is from things we found in
	 the symbols.  */
      symtab->set_language (subfile->language);
    }

  /* Make sure the filetab of main_subfile is the primary filetab of the CU.  */
  cu->set_primary_filetab (m_main_subfile->symtab);

  /* Fill out the compunit symtab.  */

  if (!m_comp_dir.empty ())
    {
      /* Reallocate the dirname on the symbol obstack.  */
      cu->set_dirname (obstack_strdup (&m_objfile->objfile_obstack,
				       m_comp_dir.c_str ()));
    }

  /* Save the debug format string (if any) in the symtab.  */
  cu->set_debugformat (m_debugformat);

  /* Similarly for the producer.  */
  cu->set_producer (m_producer);

  cu->set_blockvector (blockvector);
  {
    struct block *b = blockvector->global_block ();

    b->set_compunit_symtab (cu);
  }

  cu->set_macro_table (release_macros ());

  /* Default any symbols without a specified symtab to the primary symtab.  */
  {
    int block_i;

    /* The main source file's symtab.  */
    struct symtab *symtab = cu->primary_filetab ();

    for (block_i = 0; block_i < blockvector->num_blocks (); block_i++)
      {
	struct block *block = blockvector->block (block_i);
	struct symbol *sym;
	struct mdict_iterator miter;

	/* Inlined functions may have symbols not in the global or
	   static symbol lists.  */
	if (block->function () != nullptr
	    && block->function ()->symtab () == nullptr)
	    block->function ()->set_symtab (symtab);

	/* Note that we only want to fix up symbols from the local
	   blocks, not blocks coming from included symtabs.  That is why
	   we use ALL_DICT_SYMBOLS here and not a block iterator.  */
	ALL_DICT_SYMBOLS (block->multidict (), miter, sym)
	  if (sym->symtab () == NULL)
	    sym->set_symtab (symtab);
      }
  }

  add_compunit_symtab_to_objfile (cu);

  return cu;
}

/* Implementation of the second part of end_compunit_symtab.  Pass STATIC_BLOCK
   as value returned by end_compunit_symtab_get_static_block.

   If EXPANDABLE is non-zero the GLOBAL_BLOCK dictionary is made
   expandable.  */

struct compunit_symtab *
buildsym_compunit::end_compunit_symtab_from_static_block
  (struct block *static_block, int expandable)
{
  struct compunit_symtab *cu;

  if (static_block == NULL)
    {
      /* Handle the "no blockvector" case.
	 When this happens there is nothing to record, so there's nothing
	 to do: memory will be freed up later.

	 Note: We won't be adding a compunit to the objfile's list of
	 compunits, so there's nothing to unchain.  However, since each symtab
	 is added to the objfile's obstack we can't free that space.
	 We could do better, but this is believed to be a sufficiently rare
	 event.  */
      cu = NULL;
    }
  else
    cu = end_compunit_symtab_with_blockvector (static_block, expandable);

  return cu;
}

/* Finish the symbol definitions for one main source file, close off
   all the lexical contexts for that file (creating struct block's for
   them), then make the struct symtab for that file and put it in the
   list of all such.

   END_ADDR is the address of the end of the file's text.

   Note that it is possible for end_compunit_symtab() to return NULL.  In
   particular, for the DWARF case at least, it will return NULL when
   it finds a compilation unit that has exactly one DIE, a
   TAG_compile_unit DIE.  This can happen when we link in an object
   file that was compiled from an empty source file.  Returning NULL
   is probably not the correct thing to do, because then gdb will
   never know about this empty file (FIXME).

   If you need to modify STATIC_BLOCK before it is finalized you should
   call end_compunit_symtab_get_static_block and
   end_compunit_symtab_from_static_block yourself.  */

struct compunit_symtab *
buildsym_compunit::end_compunit_symtab (CORE_ADDR end_addr)
{
  struct block *static_block;

  static_block = end_compunit_symtab_get_static_block (end_addr, 0, 0);
  return end_compunit_symtab_from_static_block (static_block, 0);
}

/* Same as end_compunit_symtab except create a symtab that can be later added
   to.  */

struct compunit_symtab *
buildsym_compunit::end_expandable_symtab (CORE_ADDR end_addr)
{
  struct block *static_block;

  static_block = end_compunit_symtab_get_static_block (end_addr, 1, 0);
  return end_compunit_symtab_from_static_block (static_block, 1);
}

/* Subroutine of augment_type_symtab to simplify it.
   Attach the main source file's symtab to all symbols in PENDING_LIST that
   don't have one.  */

static void
set_missing_symtab (struct pending *pending_list,
		    struct compunit_symtab *cu)
{
  struct pending *pending;
  int i;

  for (pending = pending_list; pending != NULL; pending = pending->next)
    {
      for (i = 0; i < pending->nsyms; ++i)
	{
	  if (pending->symbol[i]->symtab () == NULL)
	    pending->symbol[i]->set_symtab (cu->primary_filetab ());
	}
    }
}

/* Same as end_compunit_symtab, but for the case where we're adding more symbols
   to an existing symtab that is known to contain only type information.
   This is the case for DWARF4 Type Units.  */

void
buildsym_compunit::augment_type_symtab ()
{
  struct compunit_symtab *cust = m_compunit_symtab;
  struct blockvector *blockvector = cust->blockvector ();

  if (!m_context_stack.empty ())
    complaint (_("Context stack not empty in augment_type_symtab"));
  if (m_pending_blocks != NULL)
    complaint (_("Blocks in a type symtab"));
  if (m_pending_macros != NULL)
    complaint (_("Macro in a type symtab"));
  if (m_have_line_numbers)
    complaint (_("Line numbers recorded in a type symtab"));

  if (m_file_symbols != NULL)
    {
      struct block *block = blockvector->static_block ();

      /* First mark any symbols without a specified symtab as belonging
	 to the primary symtab.  */
      set_missing_symtab (m_file_symbols, cust);

      mdict_add_pending (block->multidict (), m_file_symbols);
    }

  if (m_global_symbols != NULL)
    {
      struct block *block = blockvector->global_block ();

      /* First mark any symbols without a specified symtab as belonging
	 to the primary symtab.  */
      set_missing_symtab (m_global_symbols, cust);

      mdict_add_pending (block->multidict (), m_global_symbols);
    }
}

/* Push a context block.  Args are an identifying nesting level
   (checkable when you pop it), and the starting PC address of this
   context.  */

struct context_stack *
buildsym_compunit::push_context (int desc, CORE_ADDR valu)
{
  m_context_stack.emplace_back ();
  struct context_stack *newobj = &m_context_stack.back ();

  newobj->depth = desc;
  newobj->locals = m_local_symbols;
  newobj->old_blocks = m_pending_blocks;
  newobj->start_addr = valu;
  newobj->local_using_directives = m_local_using_directives;
  newobj->name = NULL;

  m_local_symbols = NULL;
  m_local_using_directives = NULL;

  return newobj;
}

/* Pop a context block.  Returns the address of the context block just
   popped.  */

struct context_stack
buildsym_compunit::pop_context ()
{
  gdb_assert (!m_context_stack.empty ());
  struct context_stack result = m_context_stack.back ();
  m_context_stack.pop_back ();
  return result;
}
