/* Support routines for building symbol tables in GDB's internal format.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007
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, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* This module provides subroutines used for creating and adding to
the symbol table. These routines are called from various symbol-
#include "complaints.h"
#include "gdb_string.h"
#include "expression.h" /* For "enum exp_opcode" used by... */
-#include "language.h" /* For "local_hex_string" */
#include "bcache.h"
#include "filenames.h" /* For DOSish file names */
#include "macrotab.h"
free_pending_blocks (void)
{
#if 0 /* Now we make the links in the
- symbol_obstack, so don't free
+ objfile_obstack, so don't free
them. */
struct pending_block *bnext, *bnext1;
struct pending_block *pblock;
struct pending_block *opblock;
- block = allocate_block (&objfile->symbol_obstack);
+ block = allocate_block (&objfile->objfile_obstack);
if (symbol)
{
- BLOCK_DICT (block) = dict_create_linear (&objfile->symbol_obstack,
+ BLOCK_DICT (block) = dict_create_linear (&objfile->objfile_obstack,
*listhead);
}
else
{
- BLOCK_DICT (block) = dict_create_hashed (&objfile->symbol_obstack,
+ BLOCK_DICT (block) = dict_create_hashed (&objfile->objfile_obstack,
*listhead);
}
/* If we're in the C++ case, set the block's scope. */
if (SYMBOL_LANGUAGE (symbol) == language_cplus)
{
- cp_set_block_scope (symbol, block, &objfile->symbol_obstack);
+ cp_set_block_scope (symbol, block, &objfile->objfile_obstack);
}
}
else
if (symbol)
{
complaint (&symfile_complaints,
- "block end address less than block start address in %s (patched it)",
+ _("block end address less than block start address in %s (patched it)"),
SYMBOL_PRINT_NAME (symbol));
}
else
{
complaint (&symfile_complaints,
- "block end address 0x%s less than block start address 0x%s (patched it)",
+ _("block end address 0x%s less than block start address 0x%s (patched it)"),
paddr_nz (BLOCK_END (block)), paddr_nz (BLOCK_START (block)));
}
/* Better than nothing */
#if 1
/* Check to be sure the blocks are nested as we receive
them. If the compiler/assembler/linker work, this just
- burns a small amount of time. */
- if (BLOCK_START (pblock->block) < BLOCK_START (block) ||
- BLOCK_END (pblock->block) > BLOCK_END (block))
+ burns a small amount of time.
+
+ Skip blocks which correspond to a function; they're not
+ physically nested inside this other blocks, only
+ lexically nested. */
+ if (BLOCK_FUNCTION (pblock->block) == NULL
+ && (BLOCK_START (pblock->block) < BLOCK_START (block)
+ || BLOCK_END (pblock->block) > BLOCK_END (block)))
{
if (symbol)
{
complaint (&symfile_complaints,
- "inner block not inside outer block in %s",
+ _("inner block not inside outer block in %s"),
SYMBOL_PRINT_NAME (symbol));
}
else
{
complaint (&symfile_complaints,
- "inner block (0x%s-0x%s) not inside outer block (0x%s-0x%s)",
+ _("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)),
OPBLOCK, or at the beginning if opblock is NULL. This puts the
block in the list after all its subblocks.
- Allocate the pending block struct in the symbol_obstack to save
+ Allocate the pending block struct in the objfile_obstack to save
time. This wastes a little space. FIXME: Is it worth it? */
void
struct pending_block *pblock;
pblock = (struct pending_block *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct pending_block));
+ obstack_alloc (&objfile->objfile_obstack, sizeof (struct pending_block));
pblock->block = block;
if (opblock)
{
}
blockvector = (struct blockvector *)
- obstack_alloc (&objfile->symbol_obstack,
+ obstack_alloc (&objfile->objfile_obstack,
(sizeof (struct blockvector)
+ (i - 1) * sizeof (struct block *)));
CORE_ADDR start
= BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i));
- complaint (&symfile_complaints, "block at %s out of order",
- local_hex_string ((LONGEST) start));
+ complaint (&symfile_complaints, _("block at %s out of order"),
+ hex_string ((LONGEST) start));
}
}
}
later via a call to record_debugformat. */
subfile->debugformat = NULL;
+ /* Similarly for the producer. */
+ subfile->producer = NULL;
+
/* If the filename of this subfile ends in .C, then change the
language of any pending subfiles from C to C++. We also accept
any other C++ suffixes accepted by deduce_language_from_filename. */
subfile_stack = tem;
if (current_subfile == NULL || current_subfile->name == NULL)
{
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
}
tem->name = current_subfile->name;
}
if (link == NULL)
{
- internal_error (__FILE__, __LINE__, "failed internal consistency check");
+ internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
}
name = link->name;
subfile_stack = link->next;
believed to happen in most cases (even for coffread.c);
it used to be an abort(). */
complaint (&symfile_complaints,
- "Context stack not empty in end_symtab");
+ _("Context stack not empty in end_symtab"));
context_stack_depth = 0;
}
}
objfile);
blockvector = make_blockvector (objfile);
cp_finalize_namespace (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
- &objfile->symbol_obstack);
+ &objfile->objfile_obstack);
}
#ifndef PROCESS_LINENUMBER_HOOK
}
/* Now, allocate a symbol table. */
- symtab = allocate_symtab (subfile->name, objfile);
+ if (subfile->symtab == NULL)
+ symtab = allocate_symtab (subfile->name, objfile);
+ else
+ symtab = subfile->symtab;
/* Fill in its components. */
symtab->blockvector = blockvector;
{
/* Reallocate the line table on the symbol obstack */
symtab->linetable = (struct linetable *)
- obstack_alloc (&objfile->symbol_obstack, linetablesize);
+ obstack_alloc (&objfile->objfile_obstack, linetablesize);
memcpy (symtab->linetable, subfile->line_vector, linetablesize);
}
else
{
/* Reallocate the dirname on the symbol obstack */
symtab->dirname = (char *)
- obstack_alloc (&objfile->symbol_obstack,
+ obstack_alloc (&objfile->objfile_obstack,
strlen (subfile->dirname) + 1);
strcpy (symtab->dirname, subfile->dirname);
}
{
symtab->debugformat = obsavestring (subfile->debugformat,
strlen (subfile->debugformat),
- &objfile->symbol_obstack);
+ &objfile->objfile_obstack);
}
+ /* Similarly for the producer. */
+ if (subfile->producer != NULL)
+ symtab->producer = obsavestring (subfile->producer,
+ strlen (subfile->producer),
+ &objfile->objfile_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. */
{
xfree ((void *) subfile->debugformat);
}
+ if (subfile->producer != NULL)
+ xfree (subfile->producer);
nextsub = subfile->next;
xfree ((void *) subfile);
symtab->primary = 1;
}
+ /* Default any symbols without a specified symtab to the primary
+ symtab. */
+ if (blockvector)
+ {
+ int block_i;
+
+ 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;
+
+ for (sym = dict_iterator_first (BLOCK_DICT (block), &iter);
+ sym != NULL;
+ sym = dict_iterator_next (&iter))
+ if (SYMBOL_SYMTAB (sym) == NULL)
+ SYMBOL_SYMTAB (sym) = symtab;
+ }
+ }
+
last_source_file = NULL;
current_subfile = NULL;
pending_macros = NULL;
current_subfile->debugformat = savestring (format, strlen (format));
}
+void
+record_producer (const char *producer)
+{
+ /* The producer is not always provided in the debugging info.
+ Do nothing if PRODUCER is NULL. */
+ if (producer == NULL)
+ return;
+
+ current_subfile->producer = savestring (producer, strlen (producer));
+}
+
/* 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