2003-07-16 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index 5078935fefebb98e2eb2615bb904857fb0bcae54..f0d75ce3f52ce64c1d82460c9738bf7d70a52137 100644 (file)
@@ -1,6 +1,7 @@
 /* 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.
+   1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include "bfd.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
 #include "symtab.h"
-#include "symfile.h"           /* Needed for "struct complaint" */
+#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 "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"
+
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
 #define        EXTERN
 /**/
@@ -71,23 +78,6 @@ 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 complaint block_end_complaint =
-{"block end address less than block start address in %s (patched it)", 0, 0};
-
-struct complaint anon_block_end_complaint =
-{"block end address 0x%lx less than block start address 0x%lx (patched it)", 0, 0};
-
-struct complaint innerblock_complaint =
-{"inner block not inside outer block in %s", 0, 0};
-
-struct complaint innerblock_anon_complaint =
-{"inner block (0x%lx-0x%lx) not inside outer block (0x%lx-0x%lx)", 0, 0};
-
-struct 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. */
@@ -104,7 +94,10 @@ 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)
@@ -135,6 +128,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
@@ -150,7 +149,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')
            {
@@ -167,7 +166,7 @@ find_symbol_in_list (struct pending *list, char *name, int length)
 
 /* ARGSUSED */
 void
-really_free_pendings (PTR dummy)
+really_free_pendings (void *dummy)
 {
   struct pending *next, *next1;
 
@@ -231,36 +230,29 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   register struct block *block;
   register struct pending_block *pblock;
   struct pending_block *opblock;
-  register int i;
-  register int j;
 
-  /* Count the length of the list of symbols.  */
+  /* Initialize the block's dictionary.  */
 
-  for (next = *listhead, i = 0;
-       next;
-       i += next->nsyms, next = next->next)
+  if (symbol)
     {
-      /* EMPTY */ ;
+      block = (struct block *) 
+       obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+      BLOCK_DICT (block) = dict_create_linear (&objfile->symbol_obstack,
+                                              *listhead);
     }
-
-  block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
-           (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
-
-  /* Copy the symbols into the block.  */
-
-  BLOCK_NSYMS (block) = i;
-  for (next = *listhead; next; next = next->next)
+  else
     {
-      for (j = next->nsyms - 1; j >= 0; j--)
-       {
-         BLOCK_SYM (block, --i) = next->symbol[j];
-       }
+      block = (struct block *) 
+       obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
+      BLOCK_DICT (block) = dict_create_hashed (&objfile->symbol_obstack,
+                                              *listhead);
     }
 
   BLOCK_START (block) = start;
   BLOCK_END (block) = end;
   /* Superblock filled in when containing block is made */
   BLOCK_SUPERBLOCK (block) = NULL;
+  BLOCK_NAMESPACE (block) = NULL;
 
   BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
 
@@ -269,6 +261,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   if (symbol)
     {
       struct type *ftype = SYMBOL_TYPE (symbol);
+      struct dict_iterator iter;
       SYMBOL_BLOCK_VALUE (symbol) = block;
       BLOCK_FUNCTION (block) = symbol;
 
@@ -279,7 +272,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))
                {
@@ -289,6 +282,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:
@@ -304,6 +298,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                case LOC_BASEREG:
                case LOC_UNRESOLVED:
                case LOC_OPTIMIZED_OUT:
+               case LOC_COMPUTED:
                default:
                  break;
                }
@@ -314,9 +309,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:
@@ -325,6 +323,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++;
@@ -342,12 +341,19 @@ 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->symbol_obstack);
+       }
     }
   else
     {
@@ -372,11 +378,15 @@ 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);
@@ -387,7 +397,9 @@ finish_block (struct symbol *symbol, struct pending **listhead,
      start of this scope that don't have superblocks yet.  */
 
   opblock = NULL;
-  for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
+  for (pblock = pending_blocks; 
+       pblock && pblock != old_blocks; 
+       pblock = pblock->next)
     {
       if (BLOCK_SUPERBLOCK (pblock->block) == NULL)
        {
@@ -400,14 +412,18 @@ finish_block (struct symbol *symbol, struct pending **listhead,
            {
              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);
@@ -423,6 +439,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   record_pending_block (objfile, block, opblock);
 }
 
+
 /* 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.
@@ -451,11 +468,7 @@ record_pending_block (struct objfile *objfile, struct block *block,
     }
 }
 
-/* Note that this is only used in this file and in dstread.c, which
-   should be fixed to not need direct access to this function.  When
-   that is done, it can be made static again. */
-
-struct blockvector *
+static struct blockvector *
 make_blockvector (struct objfile *objfile)
 {
   register struct pending_block *next;
@@ -512,8 +525,8 @@ 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",
+                        local_hex_string ((LONGEST) start));
            }
        }
     }
@@ -584,15 +597,17 @@ 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.
-
-     So if the filename of this subfile ends in .C, then change the
+#if 0 /* OBSOLETE CFront */
+// OBSOLETE   /* cfront output is a C program, so in most ways it looks like a C
+// OBSOLETE      program.  But to demangle we need to set the language to C++.  We
+// OBSOLETE      can distinguish cfront code by the fact that it has #line
+// OBSOLETE      directives which specify a file name ending in .C. */
+#endif /* OBSOLETE CFront */
+     
+  /* 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.  */
+  /* OBSOLETE     (in particular, some people use .cxx with cfront).  */
   /* Likewise for f2c.  */
 
   if (subfile->name)
@@ -781,6 +796,10 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
     }
   context_stack_depth = 0;
 
+  /* 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).  */
 
@@ -832,9 +851,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 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;
        }
     }
@@ -903,6 +921,8 @@ 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->symbol_obstack);
     }
 
 #ifndef PROCESS_LINENUMBER_HOOK
@@ -975,7 +995,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
@@ -1063,6 +1083,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. */
This page took 0.036578 seconds and 4 git commands to generate.