/* Support routines for building symbol tables in GDB's internal format.
   Copyright (C) 1986-2024 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 "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"
#include "filenames.h"
#include "macrotab.h"
#include "demangle.h"
#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 ();
      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;

	  /* Here we want to directly access the dictionary, because
	     we haven't fully initialized the block yet.  */
	  for (struct symbol *sym : block->multidict_symbols ())
	    {
	      if (sym->is_argument ())
		nparams++;
	    }
	  if (nparams > 0)
	    {
	      ftype->alloc_fields (nparams);

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

		  if (sym->is_argument ())
		    {
		      ftype->field (iparams).set_type (sym->type ());
		      ftype->field (iparams).set_is_artificial (false);
		      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)
    {
      std::optional<int> last_line;

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

	  if (last->unrelocated_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;
    }

  linetable_entry &e = subfile->line_vector_entries.emplace_back ();
  e.line = line;
  e.is_stmt = (flags & LEF_IS_STMT) != 0;
  e.set_unrelocated_pc (pc);
  e.prologue_end = (flags & LEF_PROLOGUE_END) != 0;
  e.epilogue_begin = (flags & LEF_EPILOGUE_BEGIN) != 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);

	/* 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 an mdict iterator here and not a block
	   iterator.  */
	for (struct symbol *sym : block->multidict_symbols ())
	  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)
{
  struct context_stack *newobj = &m_context_stack.emplace_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;
}
