Updated copyright notices for most files.
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index 09e81228aea8d85a3016cd26a5b3ce82b63cd28e..cccd769ffa9b4f3480f3ee9c25058519648a7455 100644 (file)
@@ -1,12 +1,13 @@
 /* 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 Free Software Foundation, Inc.
+   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -15,9 +16,7 @@
    GNU General Public License for more details.
 
    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.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* This module provides subroutines used for creating and adding to
    the symbol table.  These routines are called from various symbol-
 #include "symfile.h"
 #include "objfiles.h"
 #include "gdbtypes.h"
+#include "gdb_assert.h"
 #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"
 #include "demangle.h"          /* Needed by SYMBOL_INIT_DEMANGLED_NAME.  */
+#include "block.h"
+#include "cp-support.h"
+#include "dictionary.h"
+#include "addrmap.h"
+
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
 #define        EXTERN
 /**/
 
 #include "stabsread.h"
 
+/* List of subfiles.  */
+
+static struct subfile *subfiles;
+
 /* List of free `struct pending' structures for reuse.  */
 
 static struct pending *free_pendings;
@@ -60,6 +68,23 @@ static struct pending *free_pendings;
    otherwise empty symtab from being tossed.  */
 
 static int have_line_numbers;
+
+/* The mutable address map for the compilation unit whose symbols
+   we're currently reading.  The symtabs' shared blockvector will
+   point to a fixed copy of this.  */
+static struct addrmap *pending_addrmap;
+
+/* The obstack on which we allocate pending_addrmap.
+   If pending_addrmap is NULL, this is uninitialized; otherwise, it is
+   initialized (and holds pending_addrmap).  */
+static struct obstack pending_addrmap_obstack;
+
+/* Non-zero if we recorded any ranges in the addrmap that are
+   different from those in the blockvector already.  We set this to
+   zero when we start processing a symfile, and if it's still zero at
+   the end, then we just toss the addrmap.  */
+static int pending_addrmap_interesting;
+
 \f
 static int compare_line_numbers (const void *ln1p, const void *ln2p);
 \f
@@ -72,30 +97,13 @@ static int compare_line_numbers (const void *ln1p, const void *ln2p);
 #define        INITIAL_LINE_VECTOR_LENGTH      1000
 \f
 
-/* Complaints about the symbols we have encountered.  */
-
-struct deprecated_complaint block_end_complaint =
-{"block end address less than block start address in %s (patched it)", 0, 0};
-
-struct deprecated_complaint anon_block_end_complaint =
-{"block end address 0x%lx less than block start address 0x%lx (patched it)", 0, 0};
-
-struct deprecated_complaint innerblock_complaint =
-{"inner block not inside outer block in %s", 0, 0};
-
-struct deprecated_complaint innerblock_anon_complaint =
-{"inner block (0x%lx-0x%lx) not inside outer block (0x%lx-0x%lx)", 0, 0};
-
-struct deprecated_complaint blockvector_complaint =
-{"block at %s out of order", 0, 0};
-\f
 /* maintain the lists of symbols and blocks */
 
 /* Add a pending list to free_pendings. */
 void
 add_free_pendings (struct pending *list)
 {
-  register struct pending *link = list;
+  struct pending *link = list;
 
   if (list)
     {
@@ -105,12 +113,15 @@ add_free_pendings (struct pending *list)
     }
 }
       
-/* Add a symbol to one of the lists of symbols.  */
+/* Add a symbol to one of the lists of symbols.  While we're at it, if
+   we're in the C++ case and don't have full namespace debugging info,
+   check to see if it references an anonymous namespace; if so, add an
+   appropriate using directive.  */
 
 void
 add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
 {
-  register struct pending *link;
+  struct pending *link;
 
   /* If this is an alias for another symbol, don't add it.  */
   if (symbol->ginfo.name && symbol->ginfo.name[0] == '#')
@@ -136,6 +147,12 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
     }
 
   (*listhead)->symbol[(*listhead)->nsyms++] = symbol;
+
+  /* Check to see if we might need to look for a mention of anonymous
+     namespaces.  */
+  
+  if (SYMBOL_LANGUAGE (symbol) == language_cplus)
+    cp_scan_for_anonymous_namespaces (symbol);
 }
 
 /* Find a symbol named NAME on a LIST.  NAME need not be
@@ -151,7 +168,7 @@ find_symbol_in_list (struct pending *list, char *name, int length)
     {
       for (j = list->nsyms; --j >= 0;)
        {
-         pp = SYMBOL_NAME (list->symbol[j]);
+         pp = DEPRECATED_SYMBOL_NAME (list->symbol[j]);
          if (*pp == *name && strncmp (pp, name, length) == 0 &&
              pp[length] == '\0')
            {
@@ -166,9 +183,8 @@ find_symbol_in_list (struct pending *list, char *name, int length)
 /* At end of reading syms, or in case of quit, really free as many
    `struct pending's as we can easily find. */
 
-/* ARGSUSED */
 void
-really_free_pendings (PTR dummy)
+really_free_pendings (void *dummy)
 {
   struct pending *next, *next1;
 
@@ -197,6 +213,12 @@ really_free_pendings (PTR dummy)
 
   if (pending_macros)
     free_macro_table (pending_macros);
+
+  if (pending_addrmap)
+    {
+      obstack_free (&pending_addrmap_obstack, NULL);
+      pending_addrmap = NULL;
+    }
 }
 
 /* This function is called to discard any pending blocks. */
@@ -204,17 +226,8 @@ really_free_pendings (PTR dummy)
 void
 free_pending_blocks (void)
 {
-#if 0                          /* Now we make the links in the
-                                  symbol_obstack, so don't free
-                                  them.  */
-  struct pending_block *bnext, *bnext1;
-
-  for (bnext = pending_blocks; bnext; bnext = bnext1)
-    {
-      bnext1 = bnext->next;
-      xfree ((void *) bnext);
-    }
-#endif
+  /* The links are made in the objfile_obstack, so we only need to
+     reset PENDING_BLOCKS.  */
   pending_blocks = NULL;
 }
 
@@ -222,89 +235,44 @@ free_pending_blocks (void)
    the order the symbols have in the list (reversed from the input
    file).  Put the block on the list of pending blocks.  */
 
-void
+struct block *
 finish_block (struct symbol *symbol, struct pending **listhead,
              struct pending_block *old_blocks,
              CORE_ADDR start, CORE_ADDR end,
              struct objfile *objfile)
 {
-  register struct pending *next, *next1;
-  register struct block *block;
-  register struct pending_block *pblock;
+  struct pending *next, *next1;
+  struct block *block;
+  struct pending_block *pblock;
   struct pending_block *opblock;
-  register int i;
-  register int j;
 
-  /* Count the length of the list of symbols.  */
-
-  for (next = *listhead, i = 0;
-       next;
-       i += next->nsyms, next = next->next)
-    {
-      /* EMPTY */ ;
-    }
-
-  /* Copy the symbols into the block.  */
+  block = allocate_block (&objfile->objfile_obstack);
 
   if (symbol)
     {
-      block = (struct block *) 
-       obstack_alloc (&objfile->symbol_obstack,
-                      (sizeof (struct block) + 
-                       ((i - 1) * sizeof (struct symbol *))));
-      BLOCK_NSYMS (block) = i;
-      for (next = *listhead; next; next = next->next)
-       for (j = next->nsyms - 1; j >= 0; j--)
-         {
-           BLOCK_SYM (block, --i) = next->symbol[j];
-         }
+      BLOCK_DICT (block) = dict_create_linear (&objfile->objfile_obstack,
+                                              *listhead);
     }
   else
     {
-      int htab_size = BLOCK_HASHTABLE_SIZE (i);
-
-      block = (struct block *) 
-       obstack_alloc (&objfile->symbol_obstack,
-                      (sizeof (struct block) + 
-                       ((htab_size - 1) * sizeof (struct symbol *))));
-      for (j = 0; j < htab_size; j++)
-       {
-         BLOCK_BUCKET (block, j) = 0;
-       }
-      BLOCK_BUCKETS (block) = htab_size;
-      for (next = *listhead; next; next = next->next)
-       {
-         for (j = next->nsyms - 1; j >= 0; j--)
-           {
-             struct symbol *sym;
-             unsigned int hash_index;
-             const char *name = SYMBOL_DEMANGLED_NAME (next->symbol[j]);
-             if (name == NULL)
-               name = SYMBOL_NAME (next->symbol[j]);
-             hash_index = msymbol_hash_iw (name);
-             hash_index = hash_index % BLOCK_BUCKETS (block);
-             sym = BLOCK_BUCKET (block, hash_index);
-             BLOCK_BUCKET (block, hash_index) = next->symbol[j];
-             next->symbol[j]->hash_next = sym;
-           }
-       }
+      BLOCK_DICT (block) = dict_create_hashed (&objfile->objfile_obstack,
+                                              *listhead);
     }
 
   BLOCK_START (block) = start;
   BLOCK_END (block) = end;
   /* Superblock filled in when containing block is made */
   BLOCK_SUPERBLOCK (block) = NULL;
-
-  BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
+  BLOCK_NAMESPACE (block) = NULL;
 
   /* Put the block in as the value of the symbol that names it.  */
 
   if (symbol)
     {
       struct type *ftype = SYMBOL_TYPE (symbol);
+      struct dict_iterator iter;
       SYMBOL_BLOCK_VALUE (symbol) = block;
       BLOCK_FUNCTION (block) = symbol;
-      BLOCK_HASHTABLE (block) = 0;
 
       if (TYPE_NFIELDS (ftype) <= 0)
        {
@@ -313,7 +281,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
             parameter symbols. */
          int nparams = 0, iparams;
          struct symbol *sym;
-         ALL_BLOCK_SYMBOLS (block, i, sym)
+         ALL_BLOCK_SYMBOLS (block, iter, sym)
            {
              switch (SYMBOL_CLASS (sym))
                {
@@ -323,6 +291,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                case LOC_REGPARM_ADDR:
                case LOC_BASEREG_ARG:
                case LOC_LOCAL_ARG:
+               case LOC_COMPUTED_ARG:
                  nparams++;
                  break;
                case LOC_UNDEF:
@@ -338,6 +307,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                case LOC_BASEREG:
                case LOC_UNRESOLVED:
                case LOC_OPTIMIZED_OUT:
+               case LOC_COMPUTED:
                default:
                  break;
                }
@@ -348,9 +318,12 @@ finish_block (struct symbol *symbol, struct pending **listhead,
              TYPE_FIELDS (ftype) = (struct field *)
                TYPE_ALLOC (ftype, nparams * sizeof (struct field));
 
-             for (i = iparams = 0; iparams < nparams; i++)
+             iparams = 0;
+             ALL_BLOCK_SYMBOLS (block, iter, sym)
                {
-                 sym = BLOCK_SYM (block, i);
+                 if (iparams == nparams)
+                   break;
+
                  switch (SYMBOL_CLASS (sym))
                    {
                    case LOC_ARG:
@@ -359,6 +332,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                    case LOC_REGPARM_ADDR:
                    case LOC_BASEREG_ARG:
                    case LOC_LOCAL_ARG:
+                   case LOC_COMPUTED_ARG:
                      TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
                      TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
                      iparams++;
@@ -376,17 +350,23 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                    case LOC_BASEREG:
                    case LOC_UNRESOLVED:
                    case LOC_OPTIMIZED_OUT:
+                   case LOC_COMPUTED:
                    default:
                      break;
                    }
                }
            }
        }
+
+      /* 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->objfile_obstack);
+       }
     }
   else
     {
       BLOCK_FUNCTION (block) = NULL;
-      BLOCK_HASHTABLE (block) = 1;
     }
 
   /* Now "free" the links of the list, and empty the list.  */
@@ -399,7 +379,6 @@ finish_block (struct symbol *symbol, struct pending **listhead,
     }
   *listhead = NULL;
 
-#if 1
   /* Check to be sure that the blocks have an end address that is
      greater than starting address */
 
@@ -407,16 +386,19 @@ finish_block (struct symbol *symbol, struct pending **listhead,
     {
       if (symbol)
        {
-         complain (&block_end_complaint, SYMBOL_SOURCE_NAME (symbol));
+         complaint (&symfile_complaints,
+                    _("block end address less than block start address in %s (patched it)"),
+                    SYMBOL_PRINT_NAME (symbol));
        }
       else
        {
-         complain (&anon_block_end_complaint, BLOCK_END (block), BLOCK_START (block));
+         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)));
        }
       /* Better than nothing */
       BLOCK_END (block) = BLOCK_START (block);
     }
-#endif
 
   /* Install this block as the superblock of all blocks made since the
      start of this scope that don't have superblocks yet.  */
@@ -428,53 +410,63 @@ finish_block (struct symbol *symbol, struct pending **listhead,
     {
       if (BLOCK_SUPERBLOCK (pblock->block) == NULL)
        {
-#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)
                {
-                 complain (&innerblock_complaint,
-                           SYMBOL_SOURCE_NAME (symbol));
+                 complaint (&symfile_complaints,
+                            _("inner block not inside outer block in %s"),
+                            SYMBOL_PRINT_NAME (symbol));
                }
              else
                {
-                 complain (&innerblock_anon_complaint, BLOCK_START (pblock->block),
-                           BLOCK_END (pblock->block), BLOCK_START (block),
-                           BLOCK_END (block));
+                 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)));
                }
              if (BLOCK_START (pblock->block) < BLOCK_START (block))
                BLOCK_START (pblock->block) = BLOCK_START (block);
              if (BLOCK_END (pblock->block) > BLOCK_END (block))
                BLOCK_END (pblock->block) = BLOCK_END (block);
            }
-#endif
          BLOCK_SUPERBLOCK (pblock->block) = block;
        }
       opblock = pblock;
     }
 
   record_pending_block (objfile, block, opblock);
+
+  return block;
 }
 
+
 /* Record BLOCK on the list of all blocks in the file.  Put it after
    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
 record_pending_block (struct objfile *objfile, struct block *block,
                      struct pending_block *opblock)
 {
-  register struct pending_block *pblock;
+  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)
     {
@@ -488,16 +480,44 @@ record_pending_block (struct objfile *objfile, struct block *block,
     }
 }
 
-/* OBSOLETE Note that this is only used in this file and in dstread.c, which */
-/* OBSOLETE should be fixed to not need direct access to this function.  When */
-/* OBSOLETE that is done, it can be made static again. */
+
+/* Record that the range of addresses from START to END_INCLUSIVE
+   (inclusive, like it says) belongs to BLOCK.  BLOCK's start and end
+   addresses must be set already.  You must apply this function to all
+   BLOCK's children before applying it to BLOCK.
+
+   If a call to this function complicates the picture beyond that
+   already provided by BLOCK_START and BLOCK_END, then we create an
+   address map for the block.  */
+void
+record_block_range (struct block *block,
+                    CORE_ADDR start, CORE_ADDR end_inclusive)
+{
+  /* If this is any different from the range recorded in the block's
+     own BLOCK_START and BLOCK_END, then note that the address map has
+     become interesting.  Note that even if this block doesn't have
+     any "interesting" ranges, some later block might, so we still
+     need to record this block in the addrmap.  */
+  if (start != BLOCK_START (block)
+      || end_inclusive + 1 != BLOCK_END (block))
+    pending_addrmap_interesting = 1;
+
+  if (! pending_addrmap)
+    {
+      obstack_init (&pending_addrmap_obstack);
+      pending_addrmap = addrmap_create_mutable (&pending_addrmap_obstack);
+    }
+
+  addrmap_set_empty (pending_addrmap, start, end_inclusive, block);
+}
+
 
 static struct blockvector *
 make_blockvector (struct objfile *objfile)
 {
-  register struct pending_block *next;
-  register struct blockvector *blockvector;
-  register int i;
+  struct pending_block *next;
+  struct blockvector *blockvector;
+  int i;
 
   /* Count the length of the list of blocks.  */
 
@@ -506,7 +526,7 @@ make_blockvector (struct objfile *objfile)
     }
 
   blockvector = (struct blockvector *)
-    obstack_alloc (&objfile->symbol_obstack,
+    obstack_alloc (&objfile->objfile_obstack,
                   (sizeof (struct blockvector)
                    + (i - 1) * sizeof (struct block *)));
 
@@ -522,23 +542,19 @@ make_blockvector (struct objfile *objfile)
       BLOCKVECTOR_BLOCK (blockvector, --i) = next->block;
     }
 
-#if 0                          /* Now we make the links in the
-                                  obstack, so don't free them.  */
-  /* Now free the links of the list, and empty the list.  */
-
-  for (next = pending_blocks; next; next = next1)
-    {
-      next1 = next->next;
-      xfree (next);
-    }
-#endif
-  pending_blocks = NULL;
+  free_pending_blocks ();
 
-#if 1                          /* FIXME, shut this off after a while
-                                  to speed up symbol reading.  */
+  /* If we needed an address map for this symtab, record it in the
+     blockvector.  */
+  if (pending_addrmap && pending_addrmap_interesting)
+    BLOCKVECTOR_MAP (blockvector)
+      = addrmap_create_fixed (pending_addrmap, &objfile->objfile_obstack);
+  else
+    BLOCKVECTOR_MAP (blockvector) = 0;
+        
   /* Some compilers output blocks in the wrong order, but we depend on
      their being in the right order so we can binary search. Check the
-     order and moan about it.  FIXME.  */
+     order and moan about it.  */
   if (BLOCKVECTOR_NBLOCKS (blockvector) > 1)
     {
       for (i = 1; i < BLOCKVECTOR_NBLOCKS (blockvector); i++)
@@ -549,12 +565,11 @@ make_blockvector (struct objfile *objfile)
              CORE_ADDR start
                = BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i));
 
-             complain (&blockvector_complaint,
-                       local_hex_string ((LONGEST) start));
+             complaint (&symfile_complaints, _("block at %s out of order"),
+                        hex_string ((LONGEST) start));
            }
        }
     }
-#endif
 
   return (blockvector);
 }
@@ -562,23 +577,39 @@ make_blockvector (struct objfile *objfile)
 /* Start recording information about source code that came from an
    included (or otherwise merged-in) source file with a different
    name.  NAME is the name of the file (cannot be NULL), DIRNAME is
-   the directory in which it resides (or NULL if not known).  */
+   the directory in which the file was compiled (or NULL if not known).  */
 
 void
 start_subfile (char *name, char *dirname)
 {
-  register struct subfile *subfile;
+  struct subfile *subfile;
 
   /* See if this subfile is already known as a subfile of the current
      main source file.  */
 
   for (subfile = subfiles; subfile; subfile = subfile->next)
     {
-      if (FILENAME_CMP (subfile->name, name) == 0)
+      char *subfile_name;
+
+      /* If NAME is an absolute path, and this subfile is not, then
+        attempt to create an absolute path to compare.  */
+      if (IS_ABSOLUTE_PATH (name)
+         && !IS_ABSOLUTE_PATH (subfile->name)
+         && subfile->dirname != NULL)
+       subfile_name = concat (subfile->dirname, SLASH_STRING,
+                              subfile->name, NULL);
+      else
+       subfile_name = subfile->name;
+
+      if (FILENAME_CMP (subfile_name, name) == 0)
        {
          current_subfile = subfile;
+         if (subfile_name != subfile->name)
+           xfree (subfile_name);
          return;
        }
+      if (subfile_name != subfile->name)
+       xfree (subfile_name);
     }
 
   /* This subfile is not known.  Add an entry for it. Make an entry
@@ -621,15 +652,12 @@ start_subfile (char *name, char *dirname)
      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
-     directives which specify a file name ending in .C.
+  /* Similarly for the producer.  */
+  subfile->producer = NULL;
 
-     So if the filename of this subfile ends in .C, then change the
+  /* 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
-     (in particular, some people use .cxx with cfront).  */
+     any other C++ suffixes accepted by deduce_language_from_filename.  */
   /* Likewise for f2c.  */
 
   if (subfile->name)
@@ -703,14 +731,14 @@ patch_subfile_names (struct subfile *subfile, char *name)
 void
 push_subfile (void)
 {
-  register struct subfile_stack *tem
+  struct subfile_stack *tem
   = (struct subfile_stack *) xmalloc (sizeof (struct subfile_stack));
 
   tem->next = subfile_stack;
   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;
 }
@@ -718,12 +746,12 @@ push_subfile (void)
 char *
 pop_subfile (void)
 {
-  register char *name;
-  register struct subfile_stack *link = subfile_stack;
+  char *name;
+  struct subfile_stack *link = subfile_stack;
 
   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;
@@ -735,7 +763,7 @@ pop_subfile (void)
    line vector for SUBFILE.  */
 
 void
-record_line (register struct subfile *subfile, int line, CORE_ADDR pc)
+record_line (struct subfile *subfile, int line, CORE_ADDR pc)
 {
   struct linetable_entry *e;
   /* Ignore the dummy line number in libg.o */
@@ -766,9 +794,34 @@ record_line (register struct subfile *subfile, int line, CORE_ADDR pc)
                      * 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
+     first.  This is right if the marker ends the previous function,
+     and there is no padding before the next function.  But it is
+     wrong if the previous line was empty and we are now marking a
+     switch to a different subfile.  We must leave the end of sequence
+     marker at the end of this group of lines, not sort the empty line
+     to after the marker.  The easiest way to accomplish this is to
+     delete any empty lines from our table, if they are followed by
+     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)
+    {
+      e = subfile->line_vector->item + subfile->line_vector->nitems - 1;
+      while (subfile->line_vector->nitems > 0 && e->pc == pc)
+       {
+         e--;
+         subfile->line_vector->nitems--;
+       }
+    }
+
   e = subfile->line_vector->item + subfile->line_vector->nitems++;
   e->line = line;
-  e->pc = ADDR_BITS_REMOVE(pc);
+  e->pc = pc;
 }
 
 /* Needed in order to sort line tables from IBM xcoff files.  Sigh!  */
@@ -795,12 +848,15 @@ compare_line_numbers (const void *ln1p, const void *ln2p)
 /* 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
-   one original source file.  */
+   one original source file.
+
+   NAME is the name of the file (cannot be NULL).  DIRNAME is the directory in
+   which the file was compiled (or NULL if not known).  START_ADDR is the
+   lowest address of objects in the file (or 0 if not known).  */
 
 void
 start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
 {
-
   last_source_file = name;
   last_source_start_addr = start_addr;
   file_symbols = NULL;
@@ -818,6 +874,13 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
     }
   context_stack_depth = 0;
 
+  /* 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).  */
 
@@ -846,10 +909,10 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
 struct symtab *
 end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 {
-  register struct symtab *symtab = NULL;
-  register struct blockvector *blockvector;
-  register struct subfile *subfile;
-  register struct context_stack *cstk;
+  struct symtab *symtab = NULL;
+  struct blockvector *blockvector;
+  struct subfile *subfile;
+  struct context_stack *cstk;
   struct subfile *nextsub;
 
   /* Finish the lexical context of the last function in the file; pop
@@ -869,9 +932,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
             same.  FIXME: Find out why it is happening.  This is not
             believed to happen in most cases (even for coffread.c);
             it used to be an abort().  */
-         static struct deprecated_complaint msg =
-         {"Context stack not empty in end_symtab", 0, 0};
-         complain (&msg);
+         complaint (&symfile_complaints,
+                    _("Context stack not empty in end_symtab"));
          context_stack_depth = 0;
        }
     }
@@ -940,12 +1002,13 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       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);
     }
 
-#ifndef PROCESS_LINENUMBER_HOOK
-#define PROCESS_LINENUMBER_HOOK()
-#endif
-  PROCESS_LINENUMBER_HOOK ();  /* Needed for xcoff. */
+  /* Read the line table if it has to be read separately.  */
+  if (objfile->sf->sym_read_linetable != NULL)
+    objfile->sf->sym_read_linetable ();
 
   /* Now create the symtab objects proper, one for each subfile.  */
   /* (The main file is the last one on the chain.)  */
@@ -963,14 +1026,6 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
            {
              linetablesize = sizeof (struct linetable) +
                subfile->line_vector->nitems * sizeof (struct linetable_entry);
-#if 0
-             /* I think this is artifact from before it went on the
-                obstack. I doubt we'll need the memory between now
-                and when we free it later in this function.  */
-             /* First, shrink the linetable to make more memory.  */
-             subfile->line_vector = (struct linetable *)
-               xrealloc ((char *) subfile->line_vector, linetablesize);
-#endif
 
              /* Like the pending blocks, the line table may be
                 scrambled in reordered executables.  Sort it if
@@ -982,7 +1037,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
            }
 
          /* 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;
@@ -991,7 +1049,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
            {
              /* 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
@@ -1003,7 +1061,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
            {
              /* 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);
            }
@@ -1012,7 +1070,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
              symtab->dirname = NULL;
            }
          symtab->free_code = free_linetable;
-         symtab->free_ptr = NULL;
+         symtab->free_func = NULL;
 
          /* Use whatever language we have been using for this
             subfile, not the one that was deduced in allocate_symtab
@@ -1027,9 +1085,15 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
            {
              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.  */
@@ -1052,6 +1116,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
        {
          xfree ((void *) subfile->debugformat);
        }
+      if (subfile->producer != NULL)
+       xfree (subfile->producer);
 
       nextsub = subfile->next;
       xfree ((void *) subfile);
@@ -1063,9 +1129,34 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       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;
+  if (pending_addrmap)
+    {
+      obstack_free (&pending_addrmap_obstack, NULL);
+      pending_addrmap = NULL;
+    }
 
   return symtab;
 }
@@ -1077,7 +1168,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 struct context_stack *
 push_context (int desc, CORE_ADDR valu)
 {
-  register struct context_stack *new;
+  struct context_stack *new;
 
   if (context_stack_depth == context_stack_size)
     {
@@ -1100,6 +1191,17 @@ push_context (int desc, CORE_ADDR valu)
 
   return new;
 }
+
+/* Pop a context block.  Returns the address of the context block just
+   popped. */
+
+struct context_stack *
+pop_context (void)
+{
+  gdb_assert (context_stack_depth > 0);
+  return (&context_stack[--context_stack_depth]);
+}
+
 \f
 
 /* Compute a small integer hash code for the given name. */
@@ -1117,6 +1219,17 @@ record_debugformat (char *format)
   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
@@ -1128,7 +1241,7 @@ record_debugformat (char *format)
 void
 merge_symbol_lists (struct pending **srclist, struct pending **targetlist)
 {
-  register int i;
+  int i;
 
   if (!srclist || !*srclist)
     return;
@@ -1157,6 +1270,10 @@ buildsym_init (void)
   global_symbols = NULL;
   pending_blocks = NULL;
   pending_macros = NULL;
+
+  /* We shouldn't have any address map at this point.  */
+  gdb_assert (! pending_addrmap);
+  pending_addrmap_interesting = 0;
 }
 
 /* Initialize anything that needs initializing when a completely new
This page took 0.037538 seconds and 4 git commands to generate.