2003-05-19 David Carlton <carlton@bactrian.org>
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index b62c3464d01d19921712b4a387b4c29cc4e11c23..d3c9ddfc175b46e2c58fa53075bd5787f8eabc63 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 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 "language.h"          /* For "longest_local_hex_string_custom" */
+#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"
+
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
 #define        EXTERN
 /**/
@@ -70,23 +77,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. */
@@ -103,7 +93,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)
@@ -134,6 +127,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
@@ -149,7 +148,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,7 +165,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;
 
@@ -192,6 +191,9 @@ really_free_pendings (PTR dummy)
       xfree ((void *) next);
     }
   global_symbols = NULL;
+
+  if (pending_macros)
+    free_macro_table (pending_macros);
 }
 
 /* This function is called to discard any pending blocks. */
@@ -239,17 +241,49 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       /* EMPTY */ ;
     }
 
-  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)
+  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];
+         }
+    }
+  else
     {
-      for (j = next->nsyms - 1; j >= 0; j--)
+      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)
        {
-         BLOCK_SYM (block, --i) = next->symbol[j];
+         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 = DEPRECATED_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;
+           }
        }
     }
 
@@ -257,6 +291,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   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;
 
@@ -267,6 +302,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       struct type *ftype = SYMBOL_TYPE (symbol);
       SYMBOL_BLOCK_VALUE (symbol) = block;
       BLOCK_FUNCTION (block) = symbol;
+      BLOCK_HASHTABLE (block) = 0;
 
       if (TYPE_NFIELDS (ftype) <= 0)
        {
@@ -275,9 +311,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
             parameter symbols. */
          int nparams = 0, iparams;
          struct symbol *sym;
-         for (i = 0; i < BLOCK_NSYMS (block); i++)
+         ALL_BLOCK_SYMBOLS (block, i, sym)
            {
-             sym = BLOCK_SYM (block, i);
              switch (SYMBOL_CLASS (sym))
                {
                case LOC_ARG:
@@ -286,6 +321,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:
@@ -301,6 +337,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                case LOC_BASEREG:
                case LOC_UNRESOLVED:
                case LOC_OPTIMIZED_OUT:
+               case LOC_COMPUTED:
                default:
                  break;
                }
@@ -322,7 +359,9 @@ 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++;
                      break;
                    case LOC_UNDEF:
@@ -338,16 +377,24 @@ 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
     {
       BLOCK_FUNCTION (block) = NULL;
+      BLOCK_HASHTABLE (block) = 1;
     }
 
   /* Now "free" the links of the list, and empty the list.  */
@@ -368,11 +415,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);
@@ -383,7 +434,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)
        {
@@ -396,14 +449,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);
@@ -447,11 +504,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;
@@ -508,8 +561,8 @@ make_blockvector (struct objfile *objfile)
              CORE_ADDR start
                = BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i));
 
-             complain (&blockvector_complaint,
-                       longest_local_hex_string ((LONGEST) start));
+             complaint (&symfile_complaints, "block at %s out of order",
+                        local_hex_string ((LONGEST) start));
            }
        }
     }
@@ -580,15 +633,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)
@@ -777,6 +832,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).  */
 
@@ -828,9 +887,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;
        }
     }
@@ -883,7 +941,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
   if (pending_blocks == NULL
       && file_symbols == NULL
       && global_symbols == NULL
-      && have_line_numbers == 0)
+      && have_line_numbers == 0
+      && pending_macros == NULL)
     {
       /* Ignore symtabs that have no functions with real debugging
          info.  */
@@ -898,6 +957,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
@@ -944,6 +1005,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 
          /* Fill in its components.  */
          symtab->blockvector = blockvector;
+          symtab->macro_table = pending_macros;
          if (subfile->line_vector)
            {
              /* Reallocate the line table on the symbol obstack */
@@ -1022,6 +1084,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 
   last_source_file = NULL;
   current_subfile = NULL;
+  pending_macros = NULL;
 
   return symtab;
 }
@@ -1056,6 +1119,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. */
@@ -1112,6 +1186,7 @@ buildsym_init (void)
   file_symbols = NULL;
   global_symbols = NULL;
   pending_blocks = NULL;
+  pending_macros = NULL;
 }
 
 /* Initialize anything that needs initializing when a completely new
This page took 0.028965 seconds and 4 git commands to generate.