questionable--see comment where we call them). */
#include "stabsread.h"
-/* Pointer to the head of a linked list of symbol blocks which have
- already been finalized (lexical contexts already closed) and which are
- just waiting to be built into a blockvector when finalizing the
- associated symtab. */
-
-static struct pending_block *pending_blocks = NULL;
-
/* List of free `struct pending' structures for reuse. */
static struct pending *free_pendings;
+/* Non-zero if symtab has line number info. This prevents an otherwise empty
+ symtab from being tossed. */
+
+static int have_line_numbers;
\f
static int
compare_line_numbers PARAMS ((const void *, const void *));
struct pending **listhead;
{
register struct pending *link;
+
+ /* If this is an alias for another symbol, don't add it. */
+ if (symbol->ginfo.name && symbol->ginfo.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. */
BLOCK_END (block) = end;
/* Superblock filled in when containing block is made */
BLOCK_SUPERBLOCK (block) = NULL;
+
BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
/* Put the block in as the value of the symbol that names it. */
case LOC_UNDEF:
case LOC_CONST:
case LOC_STATIC:
+ case LOC_INDIRECT:
case LOC_REGISTER:
case LOC_LOCAL:
case LOC_TYPEDEF:
case LOC_UNDEF:
case LOC_CONST:
case LOC_STATIC:
+ case LOC_INDIRECT:
case LOC_REGISTER:
case LOC_LOCAL:
case LOC_TYPEDEF:
subfile->language = subfile->next->language;
}
+ /* Initialize the debug format string to NULL. We may supply it
+ later via a call to record_debugformat. */
+ subfile->debugformat = NULL;
+
/* cfront output is a C program, so in most ways it looks like a C
program. But to demangle we need to set the language to C++. We
can distinguish cfront code by the fact that it has #line
xmalloc (sizeof (struct linetable)
+ subfile->line_vector_length * sizeof (struct linetable_entry));
subfile->line_vector->nitems = 0;
+ have_line_numbers = 1;
}
if (subfile->line_vector->nitems + 1 >= subfile->line_vector_length)
file_symbols = NULL;
global_symbols = NULL;
within_function = 0;
+ have_line_numbers = 0;
/* Context stack is initially empty. Allocate first one with room for
10 levels; reuse it forever afterward. */
OBJF_REORDERED is true, then sort the pending blocks. */
if ((objfile->flags & OBJF_REORDERED) && pending_blocks)
{
- /* FIXME! Remove this horrid bubble sort and use qsort!!!
- It'd be a whole lot easier if they weren't in a linked list!!! */
+ /* FIXME! Remove this horrid bubble sort and use merge sort!!! */
int swapped;
do
{
if (pending_blocks == NULL
&& file_symbols == NULL
- && global_symbols == NULL)
+ && global_symbols == NULL
+ && have_line_numbers == 0)
{
/* Ignore symtabs that have no functions with real debugging info */
blockvector = NULL;
blockvector = make_blockvector (objfile);
}
-#ifdef PROCESS_LINENUMBER_HOOK
- PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */
+#ifndef PROCESS_LINENUMBER_HOOK
+#define PROCESS_LINENUMBER_HOOK()
#endif
+ PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */
/* Now create the symtab objects proper, one for each subfile. */
/* (The main file is the last one on the chain.) */
language it is from things we found in the symbols. */
symtab->language = subfile->language;
+ /* Save the debug format string (if any) in the symtab */
+ if (subfile -> debugformat != NULL)
+ {
+ symtab->debugformat = obsavestring (subfile->debugformat,
+ strlen (subfile->debugformat),
+ &objfile -> symbol_obstack);
+ }
+
/* All symtabs for the main file and the subfiles share a
blockvector, so we need to clear primary for everything but
the main file. */
{
free ((PTR) subfile->line_vector);
}
+ if (subfile->debugformat != NULL)
+ {
+ free ((PTR) subfile->debugformat);
+ }
nextsub = subfile->next;
free ((PTR)subfile);
new = &context_stack[context_stack_depth++];
new->depth = desc;
new->locals = local_symbols;
+ new->params = param_symbols;
new->old_blocks = pending_blocks;
new->start_addr = valu;
new->name = NULL;
local_symbols = NULL;
+ param_symbols = NULL;
return (new);
}
return (total % HASHSIZE);
}
+\f
+void
+record_debugformat (format)
+ char *format;
+{
+ current_subfile -> debugformat = savestring (format, strlen (format));
+}
+
+
+/* Merge the first symbol list SRCLIST into the second symbol list
+ TARGETLIST by repeated calls to add_symbol_to_list(). This
+ procedure "frees" each link of SRCLIST by adding it to the
+ free_pendings list. Caller must set SRCLIST to a null list after
+ calling this function.
+
+ Void return. */
+
+void
+merge_symbol_lists (srclist, targetlist)
+ struct pending ** srclist;
+ struct pending ** targetlist;
+{
+ register int i;
+ register struct pending * link;
+
+ if (!srclist || !*srclist)
+ return;
+
+ /* Merge in elements from current link */
+ for (i=0; i < (*srclist)->nsyms; i++)
+ add_symbol_to_list ((*srclist)->symbol[i], targetlist);
+
+ /* Recurse on next */
+ merge_symbol_lists (&(*srclist)->next, targetlist);
+
+ /* "Free" the current link */
+ (*srclist)->next = free_pendings;
+ free_pendings = (*srclist);
+}
+
+
+
\f
/* Initialize anything that needs initializing when starting to read
a fresh piece of a symbol file, e.g. reading in the stuff corresponding