/* Support routines for building symbol tables in GDB's internal format.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
This file is part of GDB.
for (j = list->nsyms; --j >= 0;)
{
pp = SYMBOL_LINKAGE_NAME (list->symbol[j]);
- if (*pp == *name && strncmp (pp, name, length) == 0 &&
- pp[length] == '\0')
+ if (*pp == *name && strncmp (pp, name, length) == 0
+ && pp[length] == '\0')
{
return (list->symbol[j]);
}
CORE_ADDR start, CORE_ADDR end,
struct objfile *objfile)
{
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct pending *next, *next1;
struct block *block;
struct pending_block *pblock;
else
{
complaint (&symfile_complaints,
- _("block end address 0x%s less than block start address 0x%s (patched it)"),
- paddr_nz (BLOCK_END (block)), paddr_nz (BLOCK_START (block)));
+ _("block end address %s less than block start address %s (patched it)"),
+ paddress (gdbarch, BLOCK_END (block)),
+ paddress (gdbarch, BLOCK_START (block)));
}
/* Better than nothing */
BLOCK_END (block) = BLOCK_START (block);
else
{
complaint (&symfile_complaints,
- _("inner block (0x%s-0x%s) not inside outer block (0x%s-0x%s)"),
- paddr_nz (BLOCK_START (pblock->block)),
- paddr_nz (BLOCK_END (pblock->block)),
- paddr_nz (BLOCK_START (block)),
- paddr_nz (BLOCK_END (block)));
+ _("inner block (%s-%s) not inside outer block (%s-%s)"),
+ paddress (gdbarch, BLOCK_START (pblock->block)),
+ paddress (gdbarch, BLOCK_END (pblock->block)),
+ paddress (gdbarch, BLOCK_START (block)),
+ paddress (gdbarch, BLOCK_END (block)));
}
if (BLOCK_START (pblock->block) < BLOCK_START (block))
BLOCK_START (pblock->block) = BLOCK_START (block);
opblock = pblock;
}
+ block_set_using (block, using_directives, &objfile->objfile_obstack);
+ using_directives = NULL;
+
record_pending_block (objfile, block, opblock);
return block;
source file. */
subfile->language = deduce_language_from_filename (subfile->name);
- if (subfile->language == language_unknown &&
- subfile->next != NULL)
+ if (subfile->language == language_unknown
+ && subfile->next != NULL)
{
subfile->language = subfile->next->language;
}
symbols have been processed for a given source file. */
subfile->language = deduce_language_from_filename (subfile->name);
- if (subfile->language == language_unknown &&
- subfile->next != NULL)
+ if (subfile->language == language_unknown
+ && subfile->next != NULL)
{
subfile->language = subfile->next->language;
}
push_subfile (void)
{
struct subfile_stack *tem
- = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack));
+ = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack));
tem->next = subfile_stack;
subfile_stack = tem;
record_line (struct subfile *subfile, int line, CORE_ADDR pc)
{
struct linetable_entry *e;
- /* Ignore the dummy line number in libg.o */
+ /* Ignore the dummy line number in libg.o */
if (line == 0xffff)
{
return;
* sizeof (struct linetable_entry))));
}
- pc = gdbarch_addr_bits_remove (current_gdbarch, pc);
-
/* 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
/* We shouldn't have any address map at this point. */
gdb_assert (! pending_addrmap);
- /* Set up support for C++ namespace support, in case we need it. */
-
- cp_initialize_namespace ();
-
/* Initialize the list of sub source files with one entry for this
file (the top-level source file). */
}
}
+/* Helper function for qsort. Parametes are `struct block *' pointers,
+ function sorts them in descending order by their BLOCK_START. */
+
+static int
+block_compar (const void *ap, const void *bp)
+{
+ const struct block *a = *(const struct block **) ap;
+ const struct block *b = *(const struct block **) bp;
+
+ return ((BLOCK_START (b) > BLOCK_START (a))
+ - (BLOCK_START (b) < BLOCK_START (a)));
+}
+
/* 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
OBJF_REORDERED is true, then sort the pending blocks. */
if ((objfile->flags & OBJF_REORDERED) && pending_blocks)
{
- /* FIXME! Remove this horrid bubble sort and use merge sort!!! */
- int swapped;
- do
- {
- struct pending_block *pb, *pbnext;
+ unsigned count = 0;
+ struct pending_block *pb;
+ struct block **barray, **bp;
+ struct cleanup *back_to;
- pb = pending_blocks;
- pbnext = pb->next;
- swapped = 0;
+ for (pb = pending_blocks; pb != NULL; pb = pb->next)
+ count++;
- while (pbnext)
- {
- /* swap blocks if unordered! */
+ barray = xmalloc (sizeof (*barray) * count);
+ back_to = make_cleanup (xfree, barray);
- if (BLOCK_START (pb->block) < BLOCK_START (pbnext->block))
- {
- struct block *tmp = pb->block;
- pb->block = pbnext->block;
- pbnext->block = tmp;
- swapped = 1;
- }
- pb = pbnext;
- pbnext = pbnext->next;
- }
- }
- while (swapped);
+ bp = barray;
+ for (pb = pending_blocks; pb != NULL; pb = pb->next)
+ *bp++ = pb->block;
+
+ qsort (barray, count, sizeof (*barray), block_compar);
+
+ bp = barray;
+ for (pb = pending_blocks; pb != NULL; pb = pb->next)
+ pb->block = *bp++;
+
+ do_cleanups (back_to);
}
/* Cleanup any undefined types that have been left hanging around
are no-ops. FIXME: Is this handled right in case of QUIT? Can
we make this cleaner? */
- cleanup_undefined_types ();
+ cleanup_undefined_types (objfile);
finish_global_stabs (objfile);
if (pending_blocks == NULL
finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
objfile);
blockvector = make_blockvector (objfile);
- cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
- &objfile->objfile_obstack);
}
/* Read the line table if it has to be read separately. */
struct symbol *sym;
struct dict_iterator iter;
+ /* Inlined functions may have symbols not in the global or static
+ symbol lists. */
+ if (BLOCK_FUNCTION (block) != NULL)
+ if (SYMBOL_SYMTAB (BLOCK_FUNCTION (block)) == NULL)
+ SYMBOL_SYMTAB (BLOCK_FUNCTION (block)) = symtab;
+
for (sym = dict_iterator_first (BLOCK_DICT (block), &iter);
sym != NULL;
sym = dict_iterator_next (&iter))
new->params = param_symbols;
new->old_blocks = pending_blocks;
new->start_addr = valu;
+ new->using_directives = using_directives;
new->name = NULL;
local_symbols = NULL;
param_symbols = NULL;
+ using_directives = NULL;
return new;
}