/* Support routines for building symbol tables in GDB's internal format.
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-/* This module provides subroutines used for creating and adding to
- the symbol table. These routines are called from various symbol-
- file-reading routines.
-
- Routines to support specific debugging information formats (stabs,
- DWARF, etc) belong somewhere else.
-
- The basic way this module is used is as follows:
-
- scoped_free_pendings free_pending;
- cust = start_symtab (...);
- ... read debug info ...
- cust = end_symtab (...);
-
- The compunit symtab pointer ("cust") is returned from both start_symtab
- and end_symtab to simplify the debug info readers.
-
- There are minor variations on this, e.g., dwarf2read.c splits end_symtab
- into two calls: end_symtab_get_static_block, end_symtab_from_static_block,
- but all debug info readers follow this basic flow.
-
- Reading DWARF Type Units is another variation:
-
- scoped_free_pendings free_pending;
- cust = start_symtab (...);
- ... read debug info ...
- cust = end_expandable_symtab (...);
-
- And then reading subsequent Type Units within the containing "Comp Unit"
- will use a second flow:
-
- scoped_free_pendings free_pending;
- cust = restart_symtab (...);
- ... read debug info ...
- cust = augment_type_symtab (...);
-
- dbxread.c and xcoffread.c use another variation:
-
- scoped_free_pendings free_pending;
- cust = start_symtab (...);
- ... read debug info ...
- cust = end_symtab (...);
- ... start_symtab + read + end_symtab repeated ...
-*/
-
#include "defs.h"
-#include "buildsym.h"
+#include "buildsym-legacy.h"
#include "bfd.h"
#include "gdb_obstack.h"
#include "symtab.h"
#include "stabsread.h"
-/* The work-in-progress of the compunit we are building.
- This is created first, before any subfiles by start_symtab. */
-
-static struct buildsym_compunit *buildsym_compunit;
-
/* List of blocks already made (lexical contexts already closed).
This is used at the end to make the blockvector. */
struct block *block;
};
-static void free_buildsym_compunit (void);
-
-static int compare_line_numbers (const void *ln1p, const void *ln2p);
-
/* Initial sizes of data structures. These are realloc'd larger if
needed, and realloc'd down to the size actually used, when
completed. */
const char *comp_dir_,
enum language language_,
CORE_ADDR last_addr)
- : objfile (objfile_),
+ : m_objfile (objfile_),
m_last_source_file (name == nullptr ? nullptr : xstrdup (name)),
- comp_dir (comp_dir_ == nullptr ? nullptr : xstrdup (comp_dir_)),
- language (language_),
+ m_comp_dir (comp_dir_ == nullptr ? nullptr : xstrdup (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. */
- compunit_symtab = allocate_compunit_symtab (objfile, name);
+ 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.
start_subfile (name);
/* Save this so that we don't have to go looking for it at the end
of the subfiles list. */
- main_subfile = m_current_subfile;
+ m_main_subfile = m_current_subfile;
}
buildsym_compunit::~buildsym_compunit ()
if (m_pending_macros != nullptr)
free_macro_table (m_pending_macros);
- for (subfile = subfiles;
+ for (subfile = m_subfiles;
subfile != NULL;
subfile = nextsub)
{
buildsym_compunit::get_macro_table ()
{
if (m_pending_macros == nullptr)
- m_pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack,
- objfile->per_bfd->macro_cache,
- compunit_symtab);
+ 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;
}
struct pending *link;
/* If this is an alias for another symbol, don't add it. */
- if (symbol->ginfo.name && symbol->ginfo.name[0] == '#')
+ if (symbol->linkage_name () && symbol->linkage_name ()[0] == '#')
return;
/* We keep PENDINGSIZE symbols in each link of the list. If we
{
for (j = list->nsyms; --j >= 0;)
{
- pp = SYMBOL_LINKAGE_NAME (list->symbol[j]);
+ pp = list->symbol[j]->linkage_name ();
if (*pp == *name && strncmp (pp, name, length) == 0
&& pp[length] == '\0')
{
return (NULL);
}
-/* At end of reading syms, or in case of quit, ensure everything
- associated with building symtabs is freed.
-
- N.B. This is *not* intended to be used when building psymtabs. Some debug
- info readers call this anyway, which is harmless if confusing. */
-
-scoped_free_pendings::~scoped_free_pendings ()
-{
- free_buildsym_compunit ();
-}
-
/* 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. */
CORE_ADDR start, CORE_ADDR end,
int is_global, int expandable)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = get_objfile_arch (m_objfile);
struct pending *next, *next1;
struct block *block;
struct pending_block *pblock;
struct pending_block *opblock;
block = (is_global
- ? allocate_global_block (&objfile->objfile_obstack)
- : allocate_block (&objfile->objfile_obstack));
+ ? allocate_global_block (&m_objfile->objfile_obstack)
+ : allocate_block (&m_objfile->objfile_obstack));
if (symbol)
{
- BLOCK_DICT (block)
- = dict_create_linear (&objfile->objfile_obstack,
- language, *listhead);
+ BLOCK_MULTIDICT (block)
+ = mdict_create_linear (&m_objfile->objfile_obstack, *listhead);
}
else
{
if (expandable)
{
- BLOCK_DICT (block) = dict_create_hashed_expandable (language);
- dict_add_pending (BLOCK_DICT (block), *listhead);
+ BLOCK_MULTIDICT (block) = mdict_create_hashed_expandable (m_language);
+ mdict_add_pending (BLOCK_MULTIDICT (block), *listhead);
}
else
{
- BLOCK_DICT (block) =
- dict_create_hashed (&objfile->objfile_obstack,
- language, *listhead);
+ BLOCK_MULTIDICT (block) =
+ mdict_create_hashed (&m_objfile->objfile_obstack, *listhead);
}
}
if (symbol)
{
struct type *ftype = SYMBOL_TYPE (symbol);
- struct dict_iterator iter;
+ struct mdict_iterator miter;
SYMBOL_BLOCK_VALUE (symbol) = block;
BLOCK_FUNCTION (block) = symbol;
/* Here we want to directly access the dictionary, because
we haven't fully initialized the block yet. */
- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym)
{
if (SYMBOL_IS_ARGUMENT (sym))
nparams++;
iparams = 0;
/* Here we want to directly access the dictionary, because
we haven't fully initialized the block yet. */
- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym)
{
if (iparams == nparams)
break;
}
if (static_link != NULL)
- objfile_register_static_link (objfile, block, static_link);
+ objfile_register_static_link (m_objfile, block, static_link);
/* Now free the links of the list, and empty the list. */
{
complaint (_("block end address less than block "
"start address in %s (patched it)"),
- SYMBOL_PRINT_NAME (symbol));
+ symbol->print_name ());
}
else
{
if (symbol)
{
complaint (_("inner block not inside outer block in %s"),
- SYMBOL_PRINT_NAME (symbol));
+ symbol->print_name ());
}
else
{
(is_global
? m_global_using_directives
: m_local_using_directives),
- &objfile->objfile_obstack);
+ &m_objfile->objfile_obstack);
if (is_global)
m_global_using_directives = NULL;
else
}
blockvector = (struct blockvector *)
- obstack_alloc (&objfile->objfile_obstack,
+ obstack_alloc (&m_objfile->objfile_obstack,
(sizeof (struct blockvector)
+ (i - 1) * sizeof (struct block *)));
blockvector. */
if (m_pending_addrmap != nullptr && m_pending_addrmap_interesting)
BLOCKVECTOR_MAP (blockvector)
- = addrmap_create_fixed (m_pending_addrmap, &objfile->objfile_obstack);
+ = addrmap_create_fixed (m_pending_addrmap, &m_objfile->objfile_obstack);
else
BLOCKVECTOR_MAP (blockvector) = 0;
const char *subfile_dirname;
struct subfile *subfile;
- subfile_dirname = comp_dir.get ();
+ subfile_dirname = m_comp_dir.get ();
/* See if this subfile is already registered. */
- for (subfile = subfiles; subfile; subfile = subfile->next)
+ for (subfile = m_subfiles; subfile; subfile = subfile->next)
{
char *subfile_name;
memset (subfile, 0, sizeof (struct subfile));
subfile->buildsym_compunit = this;
- subfile->next = subfiles;
- subfiles = subfile;
+ subfile->next = m_subfiles;
+ m_subfiles = subfile;
m_current_subfile = subfile;
enum language sublang = deduce_language_from_filename (subfile->name);
if (sublang == language_cplus || sublang == language_fortran)
- for (s = subfiles; s != NULL; s = s->next)
+ for (s = m_subfiles; s != NULL; s = s->next)
if (s->language == language_c)
s->language = sublang;
}
}
}
-/* Delete the buildsym compunit. */
-
-static void
-free_buildsym_compunit (void)
-{
- if (buildsym_compunit == NULL)
- return;
- delete buildsym_compunit;
- buildsym_compunit = NULL;
-}
-
/* 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
const char *name)
{
if (subfile != NULL
- && comp_dir == NULL
+ && m_comp_dir == NULL
&& subfile->name != NULL
&& IS_DIR_SEPARATOR (subfile->name[strlen (subfile->name) - 1]))
{
- comp_dir.reset (subfile->name);
+ m_comp_dir.reset (subfile->name);
subfile->name = xstrdup (name);
set_last_source_file (name);
void
buildsym_compunit::record_line (struct subfile *subfile, int line,
- CORE_ADDR pc)
+ CORE_ADDR pc, bool is_stmt)
{
struct linetable_entry *e;
- /* Ignore the dummy line number in libg.o */
- if (line == 0xffff)
- {
- return;
- }
-
/* Make sure line vector exists and is big enough. */
if (!subfile->line_vector)
{
m_have_line_numbers = true;
}
- if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length)
+ if (subfile->line_vector->nitems > 0)
+ {
+ /* If we have a duplicate for the previous entry then ignore the new
+ entry, except, if the new entry is setting the is_stmt flag, then
+ ensure the previous entry respects the new setting. */
+ e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
+ if (e->line == line && e->pc == pc)
+ {
+ if (is_stmt && !e->is_stmt)
+ e->is_stmt = 1;
+ return;
+ }
+ }
+
+ if (subfile->line_vector->nitems >= subfile->line_vector_length)
{
subfile->line_vector_length *= 2;
subfile->line_vector = (struct linetable *)
* sizeof (struct linetable_entry))));
}
- /* 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. */
+ /* The end of sequence marker is special. We need to reset the
+ is_stmt flag on previous lines at the same PC, otherwise these
+ lines may cause problems since they might be at the same address
+ as the following function. For instance suppose a function calls
+ abort there is no reason to emit a ret after that point (no joke).
+ So the label may be at the same address where the following
+ function begins. A similar problem appears if a label is at the
+ same address where an inline function ends we cannot reliably tell
+ if this is considered part of the inline function or the calling
+ program or even the next inline function, so stack traces may
+ give surprising results. Expect gdb.cp/step-and-next-inline.exp
+ to fail if these lines are not modified here. */
if (line == 0 && subfile->line_vector->nitems > 0)
{
- e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
- while (subfile->line_vector->nitems > 0 && e->pc == pc)
+ e = subfile->line_vector->item + subfile->line_vector->nitems;
+ do
{
e--;
- subfile->line_vector->nitems--;
+ if (e->pc != pc || e->line == 0)
+ break;
+ e->is_stmt = 0;
}
+ while (e > subfile->line_vector->item);
}
e = subfile->line_vector->item + subfile->line_vector->nitems++;
e->line = line;
+ e->is_stmt = is_stmt ? 1 : 0;
e->pc = pc;
}
-/* Needed in order to sort line tables from IBM xcoff files. Sigh! */
-
-static int
-compare_line_numbers (const void *ln1p, const void *ln2p)
-{
- struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
- struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
-
- /* Note: this code does not assume that CORE_ADDRs can fit in ints.
- Please keep it that way. */
- if (ln1->pc < ln2->pc)
- return -1;
-
- if (ln1->pc > ln2->pc)
- return 1;
-
- /* If pc equal, sort by line. I'm not sure whether this is optimum
- behavior (see comment at struct linetable in symtab.h). */
- return ln1->line - ln2->line;
-}
-\f
-/* See buildsym.h. */
-
-struct compunit_symtab *
-buildsym_compunit_symtab (void)
-{
- gdb_assert (buildsym_compunit != NULL);
-
- return buildsym_compunit->get_compunit_symtab ();
-}
-
-/* See buildsym.h. */
-
-struct macro_table *
-get_macro_table (void)
-{
- struct objfile *objfile;
-
- gdb_assert (buildsym_compunit != NULL);
- return buildsym_compunit->get_macro_table ();
-}
\f
-/* Start a new symtab for a new source file in OBJFILE. Called, for example,
- when a stabs symbol of type N_SO is seen, or when a DWARF
- TAG_compile_unit DIE is seen. It indicates the start of data for
- one original source file.
-
- NAME is the name of the file (cannot be NULL). COMP_DIR is the
- directory in which the file was compiled (or NULL if not known).
- START_ADDR is the lowest address of objects in the file (or 0 if
- not known). LANGUAGE is the language of the source file, or
- language_unknown if not known, in which case it'll be deduced from
- the filename. */
-
-struct compunit_symtab *
-start_symtab (struct objfile *objfile, const char *name, const char *comp_dir,
- CORE_ADDR start_addr, enum language language)
-{
- /* These should have been reset either by successful completion of building
- a symtab, or by the scoped_free_pendings destructor. */
- gdb_assert (buildsym_compunit == nullptr);
-
- buildsym_compunit = new struct buildsym_compunit (objfile, name, comp_dir,
- language, start_addr);
-
- return buildsym_compunit->get_compunit_symtab ();
-}
-
-/* Restart compilation for a symtab.
- CUST is the result of end_expandable_symtab.
- NAME, START_ADDR are the source file we are resuming with.
-
- This is used when a symtab is built from multiple sources.
- The symtab is first built with start_symtab/end_expandable_symtab
- and then for each additional piece call restart_symtab/augment_*_symtab.
- Note: At the moment there is only augment_type_symtab. */
-
-void
-restart_symtab (struct compunit_symtab *cust,
- const char *name, CORE_ADDR start_addr)
-{
- /* These should have been reset either by successful completion of building
- a symtab, or by the scoped_free_pendings destructor. */
- gdb_assert (buildsym_compunit == nullptr);
-
- buildsym_compunit
- = new struct buildsym_compunit (COMPUNIT_OBJFILE (cust),
- name,
- COMPUNIT_DIRNAME (cust),
- compunit_language (cust),
- start_addr,
- cust);
-}
-
/* Subroutine of end_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
struct subfile *mainsub, *subfile;
/* Get the main source file. */
- mainsub = main_subfile;
+ 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. */
struct subfile *prev_mainsub_alias = NULL;
prevsub = NULL;
- for (subfile = subfiles;
+ for (subfile = m_subfiles;
subfile != NULL;
subfile = subfile->next)
{
mainsub->symtab = mainsub_alias->symtab;
if (prev_mainsub_alias == NULL)
- subfiles = mainsub_alias->next;
+ m_subfiles = mainsub_alias->next;
else
prev_mainsub_alias->next = mainsub_alias->next;
xfree (mainsub_alias->name);
/* Reordered executables may have out of order pending blocks; if
OBJF_REORDERED is true, then sort the pending blocks. */
- if ((objfile->flags & OBJF_REORDERED) && m_pending_blocks)
+ if ((m_objfile->flags & OBJF_REORDERED) && m_pending_blocks)
{
struct pending_block *pb;
are no-ops. FIXME: Is this handled right in case of QUIT? Can
we make this cleaner? */
- cleanup_undefined_stabs_types (objfile);
- finish_global_stabs (objfile);
+ cleanup_undefined_stabs_types (m_objfile);
+ finish_global_stabs (m_objfile);
if (!required
&& m_pending_blocks == NULL
buildsym_compunit::end_symtab_with_blockvector (struct block *static_block,
int section, int expandable)
{
- struct compunit_symtab *cu = compunit_symtab;
- struct symtab *symtab;
+ struct compunit_symtab *cu = m_compunit_symtab;
struct blockvector *blockvector;
struct subfile *subfile;
CORE_ADDR end_addr;
gdb_assert (static_block != NULL);
- gdb_assert (subfiles != NULL);
+ gdb_assert (m_subfiles != NULL);
end_addr = BLOCK_END (static_block);
/* Read the line table if it has to be read separately.
This is only used by xcoffread.c. */
- if (objfile->sf->sym_read_linetable != NULL)
- objfile->sf->sym_read_linetable (objfile);
+ 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
/* Now create the symtab objects proper, if not already done,
one for each subfile. */
- for (subfile = subfiles;
+ for (subfile = m_subfiles;
subfile != NULL;
subfile = subfile->next)
{
linetablesize = sizeof (struct linetable) +
subfile->line_vector->nitems * sizeof (struct linetable_entry);
- /* Like the pending blocks, the line table may be
- scrambled in reordered executables. Sort it if
- OBJF_REORDERED is true. */
- if (objfile->flags & OBJF_REORDERED)
- qsort (subfile->line_vector->item,
- subfile->line_vector->nitems,
- sizeof (struct linetable_entry), compare_line_numbers);
+ const auto lte_is_less_than
+ = [] (const linetable_entry &ln1,
+ const linetable_entry &ln2) -> bool
+ {
+ return (ln1.pc < ln2.pc);
+ };
+
+ /* Like the pending blocks, the line table may be scrambled in
+ reordered executables. Sort it if OBJF_REORDERED is true. 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. */
+ if (m_objfile->flags & OBJF_REORDERED)
+ std::stable_sort (subfile->line_vector->item,
+ subfile->line_vector->item
+ + subfile->line_vector->nitems,
+ lte_is_less_than);
}
/* Allocate a symbol table if necessary. */
if (subfile->symtab == NULL)
subfile->symtab = allocate_symtab (cu, subfile->name);
- symtab = subfile->symtab;
+ struct symtab *symtab = subfile->symtab;
/* Fill in its components. */
{
/* Reallocate the line table on the symbol obstack. */
SYMTAB_LINETABLE (symtab) = (struct linetable *)
- obstack_alloc (&objfile->objfile_obstack, linetablesize);
+ obstack_alloc (&m_objfile->objfile_obstack, linetablesize);
memcpy (SYMTAB_LINETABLE (symtab), subfile->line_vector,
linetablesize);
}
{
struct symtab *main_symtab, *prev_symtab;
- main_symtab = main_subfile->symtab;
+ main_symtab = m_main_subfile->symtab;
prev_symtab = NULL;
- ALL_COMPUNIT_FILETABS (cu, symtab)
+ for (symtab *symtab : compunit_filetabs (cu))
{
if (symtab == main_symtab)
{
/* Fill out the compunit symtab. */
- if (comp_dir != NULL)
+ if (m_comp_dir != NULL)
{
/* Reallocate the dirname on the symbol obstack. */
- const char *comp_dir = this->comp_dir.get ();
- COMPUNIT_DIRNAME (cu)
- = (const char *) obstack_copy0 (&objfile->objfile_obstack,
- comp_dir, strlen (comp_dir));
+ const char *comp_dir = m_comp_dir.get ();
+ COMPUNIT_DIRNAME (cu) = obstack_strdup (&m_objfile->objfile_obstack,
+ comp_dir);
}
/* Save the debug format string (if any) in the symtab. */
- COMPUNIT_DEBUGFORMAT (cu) = debugformat;
+ COMPUNIT_DEBUGFORMAT (cu) = m_debugformat;
/* Similarly for the producer. */
- COMPUNIT_PRODUCER (cu) = producer;
+ COMPUNIT_PRODUCER (cu) = m_producer;
COMPUNIT_BLOCKVECTOR (cu) = blockvector;
{
int block_i;
/* The main source file's symtab. */
- symtab = COMPUNIT_FILETABS (cu);
+ struct symtab *symtab = COMPUNIT_FILETABS (cu);
for (block_i = 0; block_i < BLOCKVECTOR_NBLOCKS (blockvector); block_i++)
{
struct block *block = BLOCKVECTOR_BLOCK (blockvector, block_i);
struct symbol *sym;
- struct dict_iterator iter;
+ struct mdict_iterator miter;
/* Inlined functions may have symbols not in the global or
static symbol lists. */
/* 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 ALL_BLOCK_SYMBOLS. */
- ALL_DICT_SYMBOLS (BLOCK_DICT (block), iter, sym)
+ ALL_DICT_SYMBOLS (BLOCK_MULTIDICT (block), miter, sym)
if (symbol_symtab (sym) == NULL)
symbol_set_symtab (sym, symtab);
}
void
buildsym_compunit::augment_type_symtab ()
{
- struct compunit_symtab *cust = compunit_symtab;
+ struct compunit_symtab *cust = m_compunit_symtab;
const struct blockvector *blockvector = COMPUNIT_BLOCKVECTOR (cust);
if (!m_context_stack.empty ())
to the primary symtab. */
set_missing_symtab (m_file_symbols, cust);
- dict_add_pending (BLOCK_DICT (block), m_file_symbols);
+ mdict_add_pending (BLOCK_MULTIDICT (block), m_file_symbols);
}
if (m_global_symbols != NULL)
to the primary symtab. */
set_missing_symtab (m_global_symbols, cust);
- dict_add_pending (BLOCK_DICT (block),
+ mdict_add_pending (BLOCK_MULTIDICT (block),
m_global_symbols);
}
}
m_context_stack.pop_back ();
return result;
}
-
-\f
-
-void
-record_debugformat (const char *format)
-{
- buildsym_compunit->record_debugformat (format);
-}
-
-void
-record_producer (const char *producer)
-{
- buildsym_compunit->record_producer (producer);
-}
-
-\f
-
-/* See buildsym.h. */
-
-void
-set_last_source_file (const char *name)
-{
- gdb_assert (buildsym_compunit != nullptr || name == nullptr);
- if (buildsym_compunit != nullptr)
- buildsym_compunit->set_last_source_file (name);
-}
-
-/* See buildsym.h. */
-
-const char *
-get_last_source_file ()
-{
- if (buildsym_compunit == nullptr)
- return nullptr;
- return buildsym_compunit->get_last_source_file ();
-}
-
-/* See buildsym.h. */
-
-void
-set_last_source_start_addr (CORE_ADDR addr)
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->set_last_source_start_addr (addr);
-}
-
-/* See buildsym.h. */
-
-CORE_ADDR
-get_last_source_start_addr ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_last_source_start_addr ();
-}
-
-/* See buildsym.h. */
-
-struct using_direct **
-get_local_using_directives ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_local_using_directives ();
-}
-
-/* See buildsym.h. */
-
-void
-set_local_using_directives (struct using_direct *new_local)
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->set_local_using_directives (new_local);
-}
-
-/* See buildsym.h. */
-
-struct using_direct **
-get_global_using_directives ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_global_using_directives ();
-}
-
-/* See buildsym.h. */
-
-bool
-outermost_context_p ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->outermost_context_p ();
-}
-
-/* See buildsym.h. */
-
-struct context_stack *
-get_current_context_stack ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_current_context_stack ();
-}
-
-/* See buildsym.h. */
-
-int
-get_context_stack_depth ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_context_stack_depth ();
-}
-
-/* See buildsym.h. */
-
-struct subfile *
-get_current_subfile ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_current_subfile ();
-}
-
-/* See buildsym.h. */
-
-struct pending **
-get_local_symbols ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_local_symbols ();
-}
-
-/* See buildsym.h. */
-
-struct pending **
-get_file_symbols ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_file_symbols ();
-}
-
-/* See buildsym.h. */
-
-struct pending **
-get_global_symbols ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->get_global_symbols ();
-}
-
-void
-start_subfile (const char *name)
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->start_subfile (name);
-}
-
-void
-patch_subfile_names (struct subfile *subfile, const char *name)
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->patch_subfile_names (subfile, name);
-}
-
-void
-push_subfile ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->push_subfile ();
-}
-
-const char *
-pop_subfile ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->pop_subfile ();
-}
-
-struct block *
-end_symtab_get_static_block (CORE_ADDR end_addr, int expandable, int required)
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->end_symtab_get_static_block (end_addr, expandable,
- required);
-}
-
-struct compunit_symtab *
-end_symtab_from_static_block (struct block *static_block,
- int section, int expandable)
-{
- gdb_assert (buildsym_compunit != nullptr);
- struct compunit_symtab *result
- = buildsym_compunit->end_symtab_from_static_block (static_block,
- section, expandable);
- free_buildsym_compunit ();
- return result;
-}
-
-struct compunit_symtab *
-end_symtab (CORE_ADDR end_addr, int section)
-{
- gdb_assert (buildsym_compunit != nullptr);
- struct compunit_symtab *result
- = buildsym_compunit->end_symtab (end_addr, section);
- free_buildsym_compunit ();
- return result;
-}
-
-struct compunit_symtab *
-end_expandable_symtab (CORE_ADDR end_addr, int section)
-{
- gdb_assert (buildsym_compunit != nullptr);
- struct compunit_symtab *result
- = buildsym_compunit->end_expandable_symtab (end_addr, section);
- free_buildsym_compunit ();
- return result;
-}
-
-void
-augment_type_symtab ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->augment_type_symtab ();
- free_buildsym_compunit ();
-}
-
-struct context_stack *
-push_context (int desc, CORE_ADDR valu)
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->push_context (desc, valu);
-}
-
-struct context_stack
-pop_context ()
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->pop_context ();
-}
-
-struct block *
-finish_block (struct symbol *symbol, struct pending_block *old_blocks,
- const struct dynamic_prop *static_link,
- CORE_ADDR start, CORE_ADDR end)
-{
- gdb_assert (buildsym_compunit != nullptr);
- return buildsym_compunit->finish_block (symbol, old_blocks, static_link,
- start, end);
-}
-
-void
-record_block_range (struct block *block, CORE_ADDR start,
- CORE_ADDR end_inclusive)
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->record_block_range (block, start, end_inclusive);
-}
-
-void
-record_line (struct subfile *subfile, int line, CORE_ADDR pc)
-{
- gdb_assert (buildsym_compunit != nullptr);
- buildsym_compunit->record_line (subfile, line, pc);
-}