/* Support routines for building symbol tables in GDB's internal format.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
struct block *block;
};
-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. */
{
if (m_pending_macros == nullptr)
m_pending_macros = new_macro_table (&m_objfile->per_bfd->storage_obstack,
- &m_objfile->per_bfd->macro_cache,
+ &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')
{
CORE_ADDR start, CORE_ADDR end,
int is_global, int expandable)
{
- struct gdbarch *gdbarch = get_objfile_arch (m_objfile);
+ struct gdbarch *gdbarch = m_objfile->arch ();
struct pending *next, *next1;
struct block *block;
struct pending_block *pblock;
SYMBOL_BLOCK_VALUE (symbol) = block;
BLOCK_FUNCTION (block) = symbol;
- if (TYPE_NFIELDS (ftype) <= 0)
+ if (ftype->num_fields () <= 0)
{
/* No parameter type information is recorded with the
function's type. Set that from the type of the
}
if (nparams > 0)
{
- TYPE_NFIELDS (ftype) = nparams;
- TYPE_FIELDS (ftype) = (struct field *)
- TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+ 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
if (SYMBOL_IS_ARGUMENT (sym))
{
- TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+ ftype->field (iparams).set_type (SYMBOL_TYPE (sym));
TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
iparams++;
}
{
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
{
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. */
+ 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);
if (subfile->language == language_unknown
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 >= subfile->line_vector_length)
{
subfile->line_vector_length *= 2;
subfile->line_vector = (struct linetable *)
end of sequence markers. All we lose is the ability to set
breakpoints at some lines which contain no instructions
anyway. */
- if (line == 0 && subfile->line_vector->nitems > 0)
+ if (line == 0)
{
- e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
- while (subfile->line_vector->nitems > 0 && e->pc == pc)
+ struct linetable_entry *last = nullptr;
+ while (subfile->line_vector->nitems > 0)
{
- e--;
+ last = subfile->line_vector->item + subfile->line_vector->nitems - 1;
+ if (last->pc != pc)
+ break;
subfile->line_vector->nitems--;
}
+
+ /* Ignore an end-of-sequence marker marking an empty sequence. */
+ if (last == nullptr || last->line == 0)
+ return;
}
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
/* 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
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. */
+ const auto lte_is_less_than
+ = [] (const linetable_entry &ln1,
+ const linetable_entry &ln2) -> bool
+ {
+ if (ln1.pc == ln2.pc
+ && ((ln1.line == 0) != (ln2.line == 0)))
+ return ln1.line == 0;
+
+ 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)
- qsort (subfile->line_vector->item,
- subfile->line_vector->nitems,
- sizeof (struct linetable_entry), compare_line_numbers);
+ 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. */
{
/* Reallocate the dirname on the symbol obstack. */
const char *comp_dir = m_comp_dir.get ();
- COMPUNIT_DIRNAME (cu)
- = (const char *) obstack_copy0 (&m_objfile->objfile_obstack,
- comp_dir, strlen (comp_dir));
+ COMPUNIT_DIRNAME (cu) = obstack_strdup (&m_objfile->objfile_obstack,
+ comp_dir);
}
/* Save the debug format string (if any) in the symtab. */