1999-01-19 Fernando Nasser <fnasser@totem.to.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 9b0a9964e473d464f31cafc577061647da3cad13..b54c9f66bb825f0a3ecf9e4a23e85c25ad3cdbdf 100644 (file)
@@ -1,5 +1,5 @@
 /* Symbol table lookup for the GNU debugger, GDB.
-   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
+   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
              Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -45,56 +45,65 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 /* Prototypes for local functions */
 
-static int
-find_methods PARAMS ((struct type *, char *, struct symbol **));
+static int find_methods PARAMS ((struct type *, char *, struct symbol **));
 
-static void
-completion_list_add_name PARAMS ((char *, char *, int, char *, char *));
+static void completion_list_add_name PARAMS ((char *, char *, int, char *, 
+                                              char *));
 
-static void
-build_canonical_line_spec PARAMS ((struct symtab_and_line *, char *, char ***));
+static void build_canonical_line_spec PARAMS ((struct symtab_and_line *, 
+                                               char *, char ***));
 
-static struct symtabs_and_lines
-decode_line_2 PARAMS ((struct symbol *[], int, int, char ***));
+static struct symtabs_and_lines decode_line_2 PARAMS ((struct symbol *[], 
+                                                       int, int, char ***));
 
-static void
-rbreak_command PARAMS ((char *, int));
+static void rbreak_command PARAMS ((char *, int));
 
-static void
-types_info PARAMS ((char *, int));
+static void types_info PARAMS ((char *, int));
 
-static void
-functions_info PARAMS ((char *, int));
+static void functions_info PARAMS ((char *, int));
 
-static void
-variables_info PARAMS ((char *, int));
+static void variables_info PARAMS ((char *, int));
 
-static void
-sources_info PARAMS ((char *, int));
+static void sources_info PARAMS ((char *, int));
 
-static void
-output_source_filename PARAMS ((char *, int *));
+static void output_source_filename PARAMS ((char *, int *));
 
-char *
-operator_chars PARAMS ((char *, char **));
+char *operator_chars PARAMS ((char *, char **));
 
 static int find_line_common PARAMS ((struct linetable *, int, int *));
 
-static struct partial_symbol *
-lookup_partial_symbol PARAMS ((struct partial_symtab *, const char *,
-                              int, namespace_enum));
+static struct partial_symbol *lookup_partial_symbol PARAMS 
+                                  ((struct partial_symtab *, const char *,
+                                   int, namespace_enum));
 
-static struct partial_symbol *
-fixup_psymbol_section PARAMS ((struct partial_symbol *, struct objfile *));
+static struct partial_symbol *fixup_psymbol_section PARAMS ((struct 
+                                        partial_symbol *, struct objfile *));
 
-static struct symtab *
-lookup_symtab_1 PARAMS ((char *));
+static struct symtab *lookup_symtab_1 PARAMS ((char *));
 
-static void
-cplusplus_hint PARAMS ((char *));
+static void cplusplus_hint PARAMS ((char *));
 
-static struct symbol *
-find_active_alias PARAMS ((struct symbol *sym, CORE_ADDR addr));
+static struct symbol *find_active_alias PARAMS ((struct symbol *sym, 
+                                                 CORE_ADDR addr));
+
+/* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
+/* Signals the presence of objects compiled by HP compilers */
+int hp_som_som_object_present = 0;
+
+static void fixup_section PARAMS ((struct general_symbol_info *, 
+                                   struct objfile *));
+
+static int file_matches PARAMS ((char *, char **, int));
+
+static void print_symbol_info PARAMS ((namespace_enum, 
+                                       struct symtab *, struct symbol *, 
+                                       int, char *));
+
+static void print_msymbol_info PARAMS ((struct minimal_symbol *));
+
+static void symtab_symbol_info PARAMS ((char *, namespace_enum, int));
+
+void _initialize_symtab PARAMS ((void));
 
 /* */
 
@@ -439,7 +448,8 @@ find_pc_sect_psymbol (psymtab, pc, section)
   if (!psymtab)
     return 0;
 
-  best_pc = psymtab->textlow - 1;
+  /* Cope with programs that start at address 0 */
+  best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
 
   /* Search the global symbols as well as the static symbols, so that
      find_pc_partial_function doesn't use a minimal symbol and thus
@@ -453,7 +463,9 @@ find_pc_sect_psymbol (psymtab, pc, section)
       if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
          && SYMBOL_CLASS (p) == LOC_BLOCK
          && pc >= SYMBOL_VALUE_ADDRESS (p)
-         && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+         && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+             || (psymtab->textlow == 0
+                 && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
        {
          if (section)  /* match on a specific section */
            {
@@ -465,6 +477,7 @@ find_pc_sect_psymbol (psymtab, pc, section)
          best = p;
        }
     }
+
   for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
        (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
        < psymtab->n_static_syms);
@@ -474,7 +487,9 @@ find_pc_sect_psymbol (psymtab, pc, section)
       if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
          && SYMBOL_CLASS (p) == LOC_BLOCK
          && pc >= SYMBOL_VALUE_ADDRESS (p)
-         && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+         && (SYMBOL_VALUE_ADDRESS (p) > best_pc
+             || (psymtab->textlow == 0 
+                 && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
        {
          if (section)  /* match on a specific section */
            {
@@ -486,8 +501,7 @@ find_pc_sect_psymbol (psymtab, pc, section)
          best = p;
        }
     }
-  if (best_pc == psymtab->textlow - 1)
-    return 0;
+
   return best;
 }
 
@@ -882,6 +896,120 @@ lookup_partial_symbol (pst, name, global, namespace)
   return (NULL);
 }
 
+/* Look up a type named NAME in the struct_namespace.  The type returned
+   must not be opaque -- i.e., must have at least one field defined
+
+   This code was modelled on lookup_symbol -- the parts not relevant to looking
+   up types were just left out.  In particular it's assumed here that types
+   are available in struct_namespace and only at file-static or global blocks. */
+
+
+struct type *
+lookup_transparent_type (name)
+     const char *name;
+{
+  register struct symbol *sym;
+  register struct symtab *s = NULL;
+  register struct partial_symtab *ps;
+  struct blockvector *bv;
+  register struct objfile *objfile;
+  register struct block *block;
+  register struct minimal_symbol *msymbol;
+
+  /* Now search all the global symbols.  Do the symtab's first, then
+     check the psymtab's. If a psymtab indicates the existence
+     of the desired name as a global, then do psymtab-to-symtab
+     conversion on the fly and return the found symbol.  */
+  
+  ALL_SYMTABS (objfile, s)
+    {
+      bv = BLOCKVECTOR (s);
+      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+      sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+      if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+       {
+         return SYMBOL_TYPE (sym);
+       }
+    }
+
+  ALL_PSYMTABS (objfile, ps)
+    {
+      if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_NAMESPACE))
+       {
+         s = PSYMTAB_TO_SYMTAB(ps);
+         bv = BLOCKVECTOR (s);
+         block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+         sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+         if (!sym) 
+            {
+              /* This shouldn't be necessary, but as a last resort
+               * try looking in the statics even though the psymtab
+               * claimed the symbol was global. It's possible that
+               * the psymtab gets it wrong in some cases.
+               */
+             block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+             sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+              if (!sym)
+                error ("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+                       name, ps->filename, name, name);
+            }
+          if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+            return SYMBOL_TYPE (sym);
+       }
+    }
+
+  /* Now search the static file-level symbols.
+     Not strictly correct, but more useful than an error.
+     Do the symtab's first, then
+     check the psymtab's. If a psymtab indicates the existence
+     of the desired name as a file-level static, then do psymtab-to-symtab
+     conversion on the fly and return the found symbol.
+   */
+
+  ALL_SYMTABS (objfile, s)
+    {
+      bv = BLOCKVECTOR (s);
+      block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+      sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+      if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+       {
+         return SYMBOL_TYPE (sym);
+       }
+    }
+
+  ALL_PSYMTABS (objfile, ps)
+    {
+      if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_NAMESPACE))
+       {
+         s = PSYMTAB_TO_SYMTAB(ps);
+         bv = BLOCKVECTOR (s);
+         block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+         sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+         if (!sym)
+            {
+              /* This shouldn't be necessary, but as a last resort
+               * try looking in the globals even though the psymtab
+               * claimed the symbol was static. It's possible that
+               * the psymtab gets it wrong in some cases.
+               */
+             block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+             sym = lookup_block_symbol (block, name, STRUCT_NAMESPACE);
+              if (!sym)
+               error ("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
+%s may be an inlined function, or may be a template function\n\
+(if a template, try specifying an instantiation: %s<type>).",
+                       name, ps->filename, name, name);
+            }
+          if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+            return SYMBOL_TYPE (sym);
+       }
+    }
+  return (struct type *) 0;
+}
+
+
 /* Find the psymtab containing main(). */
 /* FIXME:  What about languages without main() or specially linked
    executables that have no main() ? */
@@ -1466,24 +1594,23 @@ find_pc_line (pc, notcurrent)
 }
 
 \f
-static int find_line_symtab PARAMS ((struct symtab *, int, struct linetable **,
-                                    int *, int *));
+static struct symtab* find_line_symtab PARAMS ((struct symtab *, int,
+                                               int *, int *));
 
 /* Find line number LINE in any symtab whose name is the same as
    SYMTAB.
 
-   If found, return 1, set *LINETABLE to the linetable in which it was
+   If found, return the symtab that contains the linetable in which it was
    found, set *INDEX to the index in the linetable of the best entry
    found, and set *EXACT_MATCH nonzero if the value returned is an
    exact match.
 
-   If not found, return 0.  */
+   If not found, return NULL.  */
 
-static int
-find_line_symtab (symtab, line, linetable, index, exact_match)
+static struct symtab*
+find_line_symtab (symtab, line, index, exact_match)
      struct symtab *symtab;
      int line;
-     struct linetable **linetable;
      int *index;
      int *exact_match;
 {
@@ -1494,9 +1621,11 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
 
   int best_index;
   struct linetable *best_linetable;
+  struct symtab *best_symtab;
 
   /* First try looking it up in the given symtab.  */
   best_linetable = LINETABLE (symtab);
+  best_symtab = symtab;
   best_index = find_line_common (best_linetable, line, &exact);
   if (best_index < 0 || !exact)
     {
@@ -1535,6 +1664,7 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
                {
                  best_index = ind;
                  best_linetable = l;
+                 best_symtab = s;
                  goto done;
                }
              if (best == 0 || l->item[ind].line < best)
@@ -1542,21 +1672,21 @@ find_line_symtab (symtab, line, linetable, index, exact_match)
                  best = l->item[ind].line;
                  best_index = ind;
                  best_linetable = l;
+                 best_symtab = s;
                }
            }
        }
     }
  done:
   if (best_index < 0)
-    return 0;
+    return NULL;
 
   if (index)
     *index = best_index;
-  if (linetable)
-    *linetable = best_linetable;
   if (exact_match)
     *exact_match = exact;
-  return 1;
+
+  return best_symtab;
 }
 \f
 /* Set the PC value for a given source file and line number and return true.
@@ -1576,8 +1706,10 @@ find_line_pc (symtab, line, pc)
   if (symtab == 0)
     return 0;
 
-  if (find_line_symtab (symtab, line, &l, &ind, NULL))
+  symtab = find_line_symtab (symtab, line, &ind, NULL);
+  if (symtab != NULL)
     {
+      l = LINETABLE (symtab);
       *pc = l->item[ind].pc;
       return 1;
     }
@@ -1903,10 +2035,12 @@ find_methods (t, name, sym_arr)
           if (strncmp (method_name, "__", 2) == 0 ||
              strncmp (method_name, "op", 2) == 0 ||
              strncmp (method_name, "type", 4) == 0)
-           if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
-             method_name = dem_opname;
-           else if (cplus_demangle_opname (method_name, dem_opname, 0))
-             method_name = dem_opname; 
+            {
+             if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
+               method_name = dem_opname;
+             else if (cplus_demangle_opname (method_name, dem_opname, 0))
+               method_name = dem_opname; 
+            }
 
          if (STREQ (name, method_name))
            /* Find all the overloaded methods with that name.  */
@@ -2427,7 +2561,14 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
       *argptr = q;
       if (s == 0)
        s = default_symtab;
-      val.symtab = s;
+
+      /* It is possible that this source file has more than one symtab, 
+        and that the new line number specification has moved us from the
+        default (in s) to a new one.  */
+      val.symtab = find_line_symtab (s, val.line, NULL, NULL);
+      if (val.symtab == 0)
+       val.symtab = s;
+     
       val.pc = 0;
       values.sals = (struct symtab_and_line *)
        xmalloc (sizeof (struct symtab_and_line));
@@ -2559,16 +2700,16 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical)
   msymbol = lookup_minimal_symbol (copy, NULL, NULL);
   if (msymbol != NULL)
     {
-      val.pc      = SYMBOL_VALUE_ADDRESS (msymbol);
-      val.section = SYMBOL_BFD_SECTION (msymbol);
+      values.sals = (struct symtab_and_line *)
+       xmalloc (sizeof (struct symtab_and_line));
+      values.sals[0] = find_pc_sect_line ( SYMBOL_VALUE_ADDRESS (msymbol), 
+                                          (struct sec *)0,0 );
+      values.sals[0].section = SYMBOL_BFD_SECTION (msymbol);
       if (funfirstline)
        {
-         val.pc += FUNCTION_START_OFFSET;
-         SKIP_PROLOGUE (val.pc);
+         values.sals[0].pc += FUNCTION_START_OFFSET;
+         SKIP_PROLOGUE (values.sals[0].pc);
        }
-      values.sals = (struct symtab_and_line *)
-       xmalloc (sizeof (struct symtab_and_line));
-      values.sals[0] = val;
       values.nelts = 1;
       return values;
     }
@@ -2653,12 +2794,9 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical)
   
   if ((prompt = getenv ("PS2")) == NULL)
     {
-      prompt = ">";
+      prompt = "> ";
     }
-  printf_unfiltered("%s ",prompt);
-  gdb_flush(gdb_stdout);
-
-  args = command_line_input ((char *) NULL, 0, "overload-choice");
+  args = command_line_input (prompt, 0, "overload-choice");
   
   if (args == 0 || *args == 0)
     error_no_arg ("one or more choice numbers");
@@ -2888,7 +3026,8 @@ search_symbols (regexp, kind, nfiles, files, matches)
   register struct blockvector *bv;
   struct blockvector *prev_bv = 0;
   register struct block *b;
-  register int i, j;
+  register int i = 0;
+  register int j;
   register struct symbol *sym;
   struct partial_symbol **psym;
   struct objfile *objfile;
@@ -3088,7 +3227,8 @@ search_symbols (regexp, kind, nfiles, files, matches)
                     if (tail == NULL)
                       {
                         sr = psr;
-                        old_chain = make_cleanup (free_search_symbols, sr);
+                        old_chain = make_cleanup ((make_cleanup_func) 
+                                                  free_search_symbols, sr);
                       }
                     else
                       tail->next = psr;
@@ -3132,7 +3272,8 @@ search_symbols (regexp, kind, nfiles, files, matches)
                           if (tail == NULL)
                             {
                               sr = psr;
-                              old_chain = make_cleanup (free_search_symbols, &sr);
+                              old_chain = make_cleanup ((make_cleanup_func) 
+                                                      free_search_symbols, &sr);
                             }
                           else
                             tail->next = psr;
@@ -3153,7 +3294,7 @@ search_symbols (regexp, kind, nfiles, files, matches)
    the data returned from search_symbols() to print information
    regarding the match to gdb_stdout.
 */
-static int
+static void
 print_symbol_info (kind, s, sym, block, last)
      namespace_enum kind;
      struct symtab *s;
@@ -3246,7 +3387,7 @@ symtab_symbol_info (regexp, kind, from_tty)
 
   /* must make sure that if we're interrupted, symbols gets freed */
   search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
-  old_chain = make_cleanup (free_search_symbols, symbols);
+  old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, symbols);
 
   printf_filtered (regexp
                    ? "All %ss matching regular expression \"%s\":\n"
@@ -3325,7 +3466,7 @@ rbreak_command (regexp, from_tty)
   struct cleanup *old_chain;
 
   search_symbols (regexp, FUNCTIONS_NAMESPACE, 0, (char **) NULL, &ss);
-  old_chain = make_cleanup (free_search_symbols, ss);
+  old_chain = make_cleanup ((make_cleanup_func) free_search_symbols, ss);
 
   for (p = ss; p != NULL; p = p->next)
     {
This page took 0.028692 seconds and 4 git commands to generate.