/* Support routines for building symbol tables in GDB's internal format.
- Copyright (C) 1986-2004, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 1986-2013 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbtypes.h"
#include "gdb_assert.h"
#include "complaints.h"
-#include "gdb_string.h"
+#include <string.h>
#include "expression.h" /* For "enum exp_opcode" used by... */
#include "bcache.h"
#include "filenames.h" /* For DOSish file names. */
the end, then we just toss the addrmap. */
static int pending_addrmap_interesting;
-\f
+/* An obstack used for allocating pending blocks. */
+
+static struct obstack pending_block_obstack;
+
+/* 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;
+ };
+
+/* 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;
+
+struct subfile_stack
+ {
+ struct subfile_stack *next;
+ char *name;
+ };
+
+static struct subfile_stack *subfile_stack;
+
+/* The macro table for the compilation unit whose symbols we're
+ currently reading. All the symtabs for the CU will point to this. */
+static struct macro_table *pending_macros;
+
static int compare_line_numbers (const void *ln1p, const void *ln2p);
static void record_pending_block (struct objfile *objfile,
struct block *block,
struct pending_block *opblock);
-\f
/* Initial sizes of data structures. These are realloc'd larger if
needed, and realloc'd down to the size actually used, when
void
free_pending_blocks (void)
{
- /* The links are made in the objfile_obstack, so we only need to
- reset PENDING_BLOCKS. */
- pending_blocks = NULL;
+ if (pending_blocks != NULL)
+ {
+ obstack_free (&pending_block_obstack, NULL);
+ pending_blocks = NULL;
+ }
}
/* Take one of the lists of symbols and make a block from it. Keep
{
struct pending_block *pblock;
+ if (pending_blocks == NULL)
+ obstack_init (&pending_block_obstack);
+
pblock = (struct pending_block *)
- obstack_alloc (&objfile->objfile_obstack, sizeof (struct pending_block));
+ obstack_alloc (&pending_block_obstack, sizeof (struct pending_block));
pblock->block = block;
if (opblock)
{
{
subfile->dirname = subfile->name;
subfile->name = xstrdup (name);
- last_source_file = 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++
return ln1->line - ln2->line;
}
\f
+/* Return the macro table.
+ Initialize it if this is the first use. */
+
+struct macro_table *
+get_macro_table (struct objfile *objfile, const char *comp_dir)
+{
+ if (! pending_macros)
+ pending_macros = new_macro_table (&objfile->per_bfd->storage_obstack,
+ objfile->per_bfd->macro_cache,
+ comp_dir);
+ return pending_macros;
+}
+\f
/* Start a new symtab for a new source file. 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
lowest address of objects in the file (or 0 if not known). */
void
-start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
+start_symtab (const char *name, const char *dirname, CORE_ADDR start_addr)
{
restart_symtab (start_addr);
- last_source_file = name;
+ set_last_source_file (name);
start_subfile (name, dirname);
}
void
restart_symtab (CORE_ADDR start_addr)
{
- last_source_file = NULL;
+ set_last_source_file (NULL);
last_source_start_addr = start_addr;
file_symbols = NULL;
global_symbols = NULL;
static void
reset_symtab_globals (void)
{
- last_source_file = NULL;
+ set_last_source_file (NULL);
current_subfile = NULL;
pending_macros = NULL;
if (pending_addrmap)
blockvector = make_blockvector (objfile);
}
- /* Read the line table if it has to be read separately. */
+ /* 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->sf->sym_read_linetable (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
if (subfile->dirname)
{
/* Reallocate the dirname on the symbol obstack. */
- symtab->dirname = (char *)
- obstack_alloc (&objfile->objfile_obstack,
- strlen (subfile->dirname) + 1);
- strcpy (symtab->dirname, subfile->dirname);
+ symtab->dirname =
+ obstack_copy0 (&objfile->objfile_obstack,
+ subfile->dirname,
+ strlen (subfile->dirname));
}
else
{
/* All symtabs for the main file and the subfiles share a
blockvector, so we need to clear primary for everything
but the main file. */
-
- symtab->primary = 0;
+ set_symtab_primary (symtab, 0);
}
else
{
/* Set this for the main source file. */
if (symtab)
{
- symtab->primary = 1;
+ set_symtab_primary (symtab, 1);
if (symtab->blockvector)
{
augment_type_symtab (struct objfile *objfile, struct symtab *primary_symtab)
{
struct blockvector *blockvector = primary_symtab->blockvector;
- int i;
if (context_stack_depth > 0)
{
free_pendings = (*srclist);
}
\f
+
+/* Name of source file whose symbol data we are now processing. This
+ comes from a symbol of type N_SO for stabs. For Dwarf it comes
+ from the DW_AT_name attribute of a DW_TAG_compile_unit DIE. */
+
+static char *last_source_file;
+
+/* See buildsym.h. */
+
+void
+set_last_source_file (const char *name)
+{
+ xfree (last_source_file);
+ last_source_file = name == NULL ? NULL : xstrdup (name);
+}
+
+/* See buildsym.h. */
+
+const char *
+get_last_source_file (void)
+{
+ return last_source_file;
+}
+
+\f
+
/* Initialize anything that needs initializing when starting to read a
fresh piece of a symbol file, e.g. reading in the stuff
corresponding to a psymtab. */
global_symbols = NULL;
pending_blocks = NULL;
pending_macros = NULL;
+ using_directives = NULL;
+ subfile_stack = NULL;
/* We shouldn't have any address map at this point. */
gdb_assert (! pending_addrmap);