/* Symbol table lookup for the GNU debugger, GDB.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 1997
Free Software Foundation, Inc.
This file is part of GDB.
#include "language.h"
#include "demangle.h"
-#include <obstack.h>
+#include "obstack.h"
#include <sys/types.h>
#include <fcntl.h>
static void
output_source_filename PARAMS ((char *, int *));
-static 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, enum namespace));
+ int, namespace_enum));
static struct symtab *
lookup_symtab_1 PARAMS ((char *));
+static void
+cplusplus_hint PARAMS ((char *));
+
/* */
/* The single non-language-specific builtin type */
using the new command completion feature on single quoted demangled C++
symbols. Remove when loose ends are cleaned up. FIXME -fnf */
-void
+static void
cplusplus_hint (name)
char *name;
{
work with the normal mechanisms. */
if (OPNAME_PREFIX_P (field_name))
{
- char *opname = cplus_mangle_opname (field_name + 3, 0);
+ const char *opname = cplus_mangle_opname (field_name + 3, 0);
if (opname == NULL)
error ("No mangling for \"%s\"", field_name);
mangled_name_len += strlen (opname);
struct partial_symtab *psymtab;
CORE_ADDR pc;
{
- struct partial_symbol *best = NULL, *p;
+ struct partial_symbol *best = NULL, *p, **pp;
CORE_ADDR best_pc;
if (!psymtab)
/* Search the global symbols as well as the static symbols, so that
find_pc_partial_function doesn't use a minimal symbol and thus
cache a bad endaddr. */
- for (p = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
- (p - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
+ for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
+ (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
< psymtab->n_global_syms);
- p++)
- if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
- && SYMBOL_CLASS (p) == LOC_BLOCK
- && pc >= SYMBOL_VALUE_ADDRESS (p)
- && SYMBOL_VALUE_ADDRESS (p) > best_pc)
- {
- best_pc = SYMBOL_VALUE_ADDRESS (p);
- best = p;
- }
- for (p = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
- (p - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
+ pp++)
+ {
+ p = *pp;
+ if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ && SYMBOL_CLASS (p) == LOC_BLOCK
+ && pc >= SYMBOL_VALUE_ADDRESS (p)
+ && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+ {
+ best_pc = SYMBOL_VALUE_ADDRESS (p);
+ 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);
- p++)
- if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
- && SYMBOL_CLASS (p) == LOC_BLOCK
- && pc >= SYMBOL_VALUE_ADDRESS (p)
- && SYMBOL_VALUE_ADDRESS (p) > best_pc)
- {
- best_pc = SYMBOL_VALUE_ADDRESS (p);
- best = p;
- }
+ pp++)
+ {
+ p = *pp;
+ if (SYMBOL_NAMESPACE (p) == VAR_NAMESPACE
+ && SYMBOL_CLASS (p) == LOC_BLOCK
+ && pc >= SYMBOL_VALUE_ADDRESS (p)
+ && SYMBOL_VALUE_ADDRESS (p) > best_pc)
+ {
+ best_pc = SYMBOL_VALUE_ADDRESS (p);
+ best = p;
+ }
+ }
if (best_pc == psymtab->textlow - 1)
return 0;
return best;
}
+/* Debug symbols usually don't have section information. We need to dig that
+ out of the minimal symbols and stash that in the debug symbol. */
+
+static
+struct symbol * fixup_symbol_section PARAMS ((struct symbol *sym,
+ struct objfile *objfile));
+static struct symbol *
+fixup_symbol_section (sym, objfile)
+ struct symbol *sym;
+ struct objfile *objfile;
+{
+ struct minimal_symbol *msym;
+
+ if (!sym)
+ return NULL;
+
+ if (SYMBOL_BFD_SECTION (sym))
+ return sym;
+
+ msym = lookup_minimal_symbol (SYMBOL_NAME (sym), NULL, objfile);
+
+ if (msym)
+ SYMBOL_BFD_SECTION (sym) = SYMBOL_BFD_SECTION (msym);
+
+ return sym;
+}
+
\f
/* Find the definition for a specified symbol name NAME
in namespace NAMESPACE, visible from lexical block BLOCK.
lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
const char *name;
register const struct block *block;
- const enum namespace namespace;
+ const namespace_enum namespace;
int *is_a_field_of_this;
struct symtab **symtab;
{
register struct symtab *s = NULL;
register struct partial_symtab *ps;
struct blockvector *bv;
- register struct objfile *objfile;
+ register struct objfile *objfile = NULL;
register struct block *b;
register struct minimal_symbol *msymbol;
*symtab = s;
}
- return (sym);
+ return fixup_symbol_section (sym, objfile);
}
block = BLOCK_SUPERBLOCK (block);
}
block_found = b;
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
}
*is_a_field_of_this = 1;
if (symtab != NULL)
*symtab = NULL;
- return 0;
+ return NULL;
}
}
block_found = block;
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
else if (MSYMBOL_TYPE (msymbol) != mst_text
&& MSYMBOL_TYPE (msymbol) != mst_file_text
{
/* This is a mangled variable, look it up by its
mangled name. */
- return lookup_symbol (SYMBOL_NAME (msymbol), block,
- namespace, is_a_field_of_this, symtab);
+ return fixup_symbol_section
+ (lookup_symbol (SYMBOL_NAME (msymbol), block,
+ namespace, is_a_field_of_this, symtab),
+ NULL);
}
/* There are no debug symbols for this file, or we are looking
for an unmangled variable.
error ("Internal: global symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
block_found = block;
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
error ("Internal: static symbol `%s' found in %s psymtab but not in symtab", name, ps->filename);
if (symtab != NULL)
*symtab = s;
- return sym;
+ return fixup_symbol_section (sym, objfile);
}
}
struct partial_symtab *pst;
const char *name;
int global;
- enum namespace namespace;
+ namespace_enum namespace;
{
- struct partial_symbol *start, *psym;
- struct partial_symbol *top, *bottom, *center;
+ struct partial_symbol **start, **psym;
+ struct partial_symbol **top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
center = bottom + (top - bottom) / 2;
if (!(center < top))
abort ();
- if (!do_linear_search && SYMBOL_LANGUAGE (center) == language_cplus)
+ if (!do_linear_search && SYMBOL_LANGUAGE (*center) == language_cplus)
{
do_linear_search = 1;
}
- if (STRCMP (SYMBOL_NAME (center), name) >= 0)
+ if (STRCMP (SYMBOL_NAME (*center), name) >= 0)
{
top = center;
}
}
if (!(top == bottom))
abort ();
- while (STREQ (SYMBOL_NAME (top), name))
+ while (STREQ (SYMBOL_NAME (*top), name))
{
- if (SYMBOL_NAMESPACE (top) == namespace)
+ if (SYMBOL_NAMESPACE (*top) == namespace)
{
- return top;
+ return (*top);
}
top ++;
}
{
for (psym = start; psym < start + length; psym++)
{
- if (namespace == SYMBOL_NAMESPACE (psym))
+ if (namespace == SYMBOL_NAMESPACE (*psym))
{
- if (SYMBOL_MATCHES_NAME (psym, name))
+ if (SYMBOL_MATCHES_NAME (*psym, name))
{
- return (psym);
+ return (*psym);
}
}
}
lookup_block_symbol (block, name, namespace)
register const struct block *block;
const char *name;
- const enum namespace namespace;
+ const namespace_enum namespace;
{
register int bot, top, inc;
register struct symbol *sym;
/* For an objfile that has its functions reordered,
find_pc_psymtab will find the proper partial symbol table
and we simply return its corresponding symtab. */
- if (objfile->flags & OBJF_REORDERED)
+ if ((objfile->flags & OBJF_REORDERED) && objfile->psymtabs)
{
ps = find_pc_psymtab (pc);
if (ps)
But what we want is the statement containing the instruction.
Fudge the pc to make sure we get that. */
- if (notcurrent) pc -= 1;
+ INIT_SAL (&val); /* initialize to zeroes */
+
+ if (notcurrent)
+ pc -= 1;
s = find_pc_symtab (pc);
if (!s)
{
- val.symtab = 0;
- val.line = 0;
val.pc = pc;
- val.end = 0;
return val;
}
for (i = 0; i < len; i++, item++)
{
- /* Return the last line that did not start after PC. */
+ /* Leave prev pointing to the linetable entry for the last line
+ that started at or before PC. */
if (item->pc > pc)
break;
{
if (!alt_symtab)
{ /* If we didn't find any line # info, just
- return zeros. */
- val.symtab = 0;
- val.line = 0;
+ return zeros. */
val.pc = pc;
- val.end = 0;
}
else
{
some legitimate operator text, return a pointer to the
beginning of the substring of the operator text.
Otherwise, return "". */
-static char *
+char *
operator_chars (p, end)
char *p;
char **end;
if (DESTRUCTOR_PREFIX_P (phys_name))
continue;
- /* FIXME: Why are we looking this up in the
- SYMBOL_BLOCK_VALUE (sym_class)? It is intended as a hook
- for nested types? If so, it should probably hook to the
- type, not the symbol. mipsread.c is the only symbol
- reader which sets the SYMBOL_BLOCK_VALUE for types, and
- this is not documented in symtab.h. -26Aug93. */
-
sym_arr[i1] = lookup_symbol (phys_name,
- SYMBOL_BLOCK_VALUE (sym_class),
- VAR_NAMESPACE,
+ NULL, VAR_NAMESPACE,
(int *) NULL,
(struct symtab **) NULL);
- if (sym_arr[i1]) i1++;
+ if (sym_arr[i1])
+ i1++;
else
{
fputs_filtered("(Cannot find method ", gdb_stdout);
char *saved_arg = *argptr;
extern char *gdb_completer_quote_characters;
+ INIT_SAL (&val); /* initialize to zeroes */
+
/* Defaults have defaults. */
if (default_symtab == 0)
sym_arr = (struct symbol **) alloca(total_number_of_methods (t)
* sizeof(struct symbol *));
- /* Cfront objects don't have fieldlists. */
- if (destructor_name_p (copy, t) && TYPE_FN_FIELDLISTS (t) != NULL)
+ if (destructor_name_p (copy, t))
{
- /* destructors are a special case. */
- struct fn_field *f = TYPE_FN_FIELDLIST1 (t, 0);
- int len = TYPE_FN_FIELDLIST_LENGTH (t, 0) - 1;
- /* gcc 1.x puts destructor in last field,
- gcc 2.x puts destructor in first field. */
- char *phys_name = TYPE_FN_FIELD_PHYSNAME (f, len);
- if (!DESTRUCTOR_PREFIX_P (phys_name))
+ /* Destructors are a special case. */
+ int m_index, f_index;
+
+ if (get_destructor_fn_field (t, &m_index, &f_index))
{
- phys_name = TYPE_FN_FIELD_PHYSNAME (f, 0);
- if (!DESTRUCTOR_PREFIX_P (phys_name))
- phys_name = "";
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (t, m_index);
+
+ sym_arr[i1] =
+ lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, f_index),
+ NULL, VAR_NAMESPACE, (int *) NULL,
+ (struct symtab **)NULL);
+ if (sym_arr[i1])
+ i1++;
}
- sym_arr[i1] =
- lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class),
- VAR_NAMESPACE, 0, (struct symtab **)NULL);
- if (sym_arr[i1]) i1++;
}
else
i1 = find_methods (t, copy, sym_arr);
msymbol = lookup_minimal_symbol (copy, NULL, NULL);
if (msymbol != NULL)
{
- val.symtab = 0;
- val.line = 0;
val.pc = SYMBOL_VALUE_ADDRESS (msymbol);
if (funfirstline)
{
val.pc += FUNCTION_START_OFFSET;
SKIP_PROLOGUE (val.pc);
}
- values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line));
+ values.sals = (struct symtab_and_line *)
+ xmalloc (sizeof (struct symtab_and_line));
values.sals[0] = val;
values.nelts = 1;
return values;
printf_unfiltered("[0] cancel\n[1] all\n");
while (i < nelts)
{
+ INIT_SAL (&return_values.sals[i]); /* initialize to zeroes */
+ INIT_SAL (&values.sals[i]);
if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
{
values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline);
return return_values;
}
- if (num > nelts + 2)
+ if (num >= nelts + 2)
{
printf_unfiltered ("No choice number %d.\n", num);
}
register struct block *b;
register int i, j;
register struct symbol *sym;
- struct partial_symbol *psym;
+ struct partial_symbol **psym;
struct objfile *objfile;
struct minimal_symbol *msymbol;
char *val;
ALL_PSYMTABS (objfile, ps)
{
- struct partial_symbol *bound, *gbound, *sbound;
+ struct partial_symbol **bound, **gbound, **sbound;
int keep_going = 1;
if (ps->readin) continue;
/* If it would match (logic taken from loop below)
load the file and go on to the next one */
- if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (psym))
- && ((class == 0 && SYMBOL_CLASS (psym) != LOC_TYPEDEF
- && SYMBOL_CLASS (psym) != LOC_BLOCK)
- || (class == 1 && SYMBOL_CLASS (psym) == LOC_BLOCK)
- || (class == 2 && SYMBOL_CLASS (psym) == LOC_TYPEDEF)
- || (class == 3 && SYMBOL_CLASS (psym) == LOC_BLOCK)))
+ if ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
+ && ((class == 0 && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
+ && SYMBOL_CLASS (*psym) != LOC_BLOCK)
+ || (class == 1 && SYMBOL_CLASS (*psym) == LOC_BLOCK)
+ || (class == 2 && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
+ || (class == 3 && SYMBOL_CLASS (*psym) == LOC_BLOCK)))
{
PSYMTAB_TO_SYMTAB(ps);
keep_going = 0;
}
else
{
-# if 0 /* FIXME, why is this zapped out? */
- char buf[1024];
+# if 0
+/* Tiemann says: "info methods was never implemented." */
+ char *demangled_name;
c_type_print_base (TYPE_FN_FIELD_TYPE(t, i),
gdb_stdout, 0, 0);
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i),
gdb_stdout, 0);
- sprintf (buf, " %s::", type_name_no_tag (t));
- cp_type_print_method_args (TYPE_FN_FIELD_ARGS (t, i),
- buf, name, gdb_stdout);
+ if (TYPE_FN_FIELD_STUB (t, i))
+ check_stub_method (TYPE_DOMAIN_TYPE (type), j, i);
+ demangled_name =
+ cplus_demangle (TYPE_FN_FIELD_PHYSNAME (t, i),
+ DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name == NULL)
+ fprintf_filtered (stream, "<badly mangled name %s>",
+ TYPE_FN_FIELD_PHYSNAME (t, i));
+ else
+ {
+ fputs_filtered (demangled_name, stream);
+ free (demangled_name);
+ }
# endif
}
}
register struct objfile *objfile;
register struct block *b, *surrounding_static_block = 0;
register int i, j;
- struct partial_symbol *psym;
+ struct partial_symbol **psym;
/* The symbol we are completing on. Points in same buffer as text. */
char *sym_text;
/* Length of sym_text. */
{
/* If interrupted, then quit. */
QUIT;
- COMPLETION_LIST_ADD_SYMBOL (psym, sym_text, sym_text_len, text, word);
+ COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text, word);
}
for (psym = objfile->static_psymbols.list + ps->statics_offset;
psym++)
{
QUIT;
- COMPLETION_LIST_ADD_SYMBOL (psym, sym_text, sym_text_len, text, word);
+ COMPLETION_LIST_ADD_SYMBOL (*psym, sym_text, sym_text_len, text, word);
}
}