#include "demangle.h"
#include "inferior.h"
#include "linespec.h"
+#include "source.h"
#include "filenames.h" /* for FILENAME_CMP */
-#include "obstack.h"
+#include "gdb_obstack.h"
#include <sys/types.h>
#include <fcntl.h>
#include <ctype.h>
#include "cp-abi.h"
-/* Prototype for one function in parser-defs.h,
- instead of including that entire file. */
-
-extern char *find_template_name_end (char *);
-
/* Prototypes for local functions */
static void completion_list_add_name (char *, char *, int, char *, char *);
const struct block *block_found;
-/* While the C++ support is still in flux, issue a possibly helpful hint on
- using the new command completion feature on single quoted demangled C++
- symbols. Remove when loose ends are cleaned up. FIXME -fnf */
-
-static void
-cplusplus_hint (char *name)
-{
- while (*name == '\'')
- name++;
- printf_filtered ("Hint: try '%s<TAB> or '%s<ESC-?>\n", name, name);
- printf_filtered ("(Note leading single quote.)\n");
-}
-
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work. */
}
\f
+/* Initialize the language dependent portion of a symbol
+ depending upon the language for the symbol. */
+void
+symbol_init_language_specific (struct general_symbol_info *gsymbol,
+ enum language language)
+{
+ gsymbol->language = language;
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_java)
+ {
+ gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+ }
+ else if (gsymbol->language == language_objc)
+ {
+ gsymbol->language_specific.objc_specific.demangled_name = NULL;
+ }
+ /* OBSOLETE else if (SYMBOL_LANGUAGE (symbol) == language_chill) */
+ /* OBSOLETE { */
+ /* OBSOLETE SYMBOL_CHILL_DEMANGLED_NAME (symbol) = NULL; */
+ /* OBSOLETE } */
+ else
+ {
+ memset (&gsymbol->language_specific, 0,
+ sizeof (gsymbol->language_specific));
+ }
+}
+
/* Initialize a symbol's mangled name. */
/* Try to initialize the demangled name for a symbol, based on the
gsymbol->language_specific.cplus_specific.demangled_name = NULL;
}
}
- if (demangled == NULL
- && (gsymbol->language == language_chill
- || gsymbol->language == language_auto))
- {
- demangled =
- chill_demangle (gsymbol->name);
- if (demangled != NULL)
- {
- gsymbol->language = language_chill;
- gsymbol->language_specific.chill_specific.demangled_name =
- obsavestring (demangled, strlen (demangled), obstack);
- xfree (demangled);
- }
- else
- {
- gsymbol->language_specific.chill_specific.demangled_name = NULL;
- }
- }
+#if 0
+ /* OBSOLETE if (demangled == NULL */
+ /* OBSOLETE && (gsymbol->language == language_chill */
+ /* OBSOLETE || gsymbol->language == language_auto)) */
+ /* OBSOLETE { */
+ /* OBSOLETE demangled = */
+ /* OBSOLETE chill_demangle (gsymbol->name); */
+ /* OBSOLETE if (demangled != NULL) */
+ /* OBSOLETE { */
+ /* OBSOLETE gsymbol->language = language_chill; */
+ /* OBSOLETE gsymbol->language_specific.chill_specific.demangled_name = */
+ /* OBSOLETE obsavestring (demangled, strlen (demangled), obstack); */
+ /* OBSOLETE xfree (demangled); */
+ /* OBSOLETE } */
+ /* OBSOLETE else */
+ /* OBSOLETE { */
+ /* OBSOLETE gsymbol->language_specific.chill_specific.demangled_name = NULL; */
+ /* OBSOLETE } */
+ /* OBSOLETE } */
+#endif
}
+/* Return the demangled name for a symbol based on the language for
+ that symbol. If no demangled name exists, return NULL. */
+char *
+symbol_demangled_name (struct general_symbol_info *gsymbol)
+{
+ if (gsymbol->language == language_cplus
+ || gsymbol->language == language_java)
+ return gsymbol->language_specific.cplus_specific.demangled_name;
+
+ else if (gsymbol->language == language_objc)
+ return gsymbol->language_specific.objc_specific.demangled_name;
+ else
+ return NULL;
+
+ /* OBSOLETE (SYMBOL_LANGUAGE (symbol) == language_chill */
+ /* OBSOLETE ? SYMBOL_CHILL_DEMANGLED_NAME (symbol) */
+}
+
+/* Initialize the structure fields to zero values. */
+void
+init_sal (struct symtab_and_line *sal)
+{
+ sal->symtab = 0;
+ sal->section = 0;
+ sal->line = 0;
+ sal->pc = 0;
+ sal->end = 0;
+}
\f
const namespace_enum namespace, int *is_a_field_of_this,
struct symtab **symtab)
{
- char *modified_name = NULL;
- char *modified_name2 = NULL;
+ char *demangled_name = NULL;
+ const char *modified_name = NULL;
const char *mangled_name = NULL;
int needtofreename = 0;
struct symbol *returnval;
+ modified_name = name;
+
+ /* If we are using C++ language, demangle the name before doing a lookup, so
+ we can always binary search. */
+ if (current_language->la_language == language_cplus)
+ {
+ demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ needtofreename = 1;
+ }
+ }
+
if (case_sensitivity == case_sensitive_off)
{
char *copy;
copy[len] = 0;
modified_name = copy;
}
- else
- modified_name = (char *) name;
-
- /* If we are using C++ language, demangle the name before doing a lookup, so
- we can always binary search. */
- if (current_language->la_language == language_cplus)
- {
- modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS);
- if (modified_name2)
- {
- mangled_name = name;
- modified_name = modified_name2;
- needtofreename = 1;
- }
- }
returnval = lookup_symbol_aux (modified_name, mangled_name, block,
namespace, is_a_field_of_this, symtab);
if (needtofreename)
- xfree (modified_name2);
+ xfree (demangled_name);
return returnval;
}
/* This is a function which has a symtab for its address. */
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
+
+ /* This call used to pass `SYMBOL_NAME (msymbol)' as the
+ `name' argument to lookup_block_symbol. But the name
+ of a minimal symbol is always mangled, so that seems
+ to be clearly the wrong thing to pass as the
+ unmangled name. */
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
/* We kept static functions in minimal symbol table as well as
in static scope. We want to find them in the symbol table. */
if (!sym)
{
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
+ sym = lookup_block_symbol (block, name,
+ mangled_name, namespace);
}
/* sym == 0 if symbol was found in the minimal symbol table
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
+ /* This call used to pass `SYMBOL_NAME (msymbol)' as the
+ `name' argument to lookup_block_symbol. But the name
+ of a minimal symbol is always mangled, so that seems
+ to be clearly the wrong thing to pass as the
+ unmangled name. */
+ sym = lookup_block_symbol (block, name, mangled_name, namespace);
/* We kept static functions in minimal symbol table as well as
in static scope. We want to find them in the symbol table. */
if (!sym)
{
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol),
- mangled_name, namespace);
+ sym = lookup_block_symbol (block, name,
+ mangled_name, namespace);
}
/* If we found one, return it */
if (sym)
register struct symbol *sym_found = NULL;
register int do_linear_search = 1;
+ if (BLOCK_HASHTABLE (block))
+ {
+ unsigned int hash_index;
+ hash_index = msymbol_hash_iw (name);
+ hash_index = hash_index % BLOCK_BUCKETS (block);
+ for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
+ {
+ if (SYMBOL_NAMESPACE (sym) == namespace
+ && (mangled_name
+ ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+ : SYMBOL_MATCHES_NAME (sym, name)))
+ return sym;
+ }
+ return NULL;
+ }
+
/* If the blocks's symbols were sorted, start with a binary search. */
if (BLOCK_SHOULD_SORT (block))
if (section != 0)
{
int i;
+ struct symbol *sym = NULL;
- for (i = 0; i < b->nsyms; i++)
+ ALL_BLOCK_SYMBOLS (b, i, sym)
{
- fixup_symbol_section (b->sym[i], objfile);
- if (section == SYMBOL_BFD_SECTION (b->sym[i]))
+ fixup_symbol_section (sym, objfile);
+ if (section == SYMBOL_BFD_SECTION (sym))
break;
}
- if (i >= b->nsyms)
+ if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
continue; /* no symbol in this symtab matches section */
}
distance = BLOCK_END (b) - BLOCK_START (b);
{
QUIT;
block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
- top = BLOCK_NSYMS (block);
- for (bot = 0; bot < top; bot++)
+ ALL_BLOCK_SYMBOLS (block, bot, sym)
{
- sym = BLOCK_SYM (block, bot);
switch (SYMBOL_CLASS (sym))
{
case LOC_STATIC:
But what we want is the statement containing the instruction.
Fudge the pc to make sure we get that. */
- INIT_SAL (&val); /* initialize to zeroes */
+ init_sal (&val); /* initialize to zeroes */
/* It's tempting to assume that, if we can't find debugging info for
any function enclosing PC, that we shouldn't search for line
struct symbol_search *prevtail = tail;
int nfound = 0;
b = BLOCKVECTOR_BLOCK (bv, i);
- for (j = 0; j < BLOCK_NSYMS (b); j++)
+ ALL_BLOCK_SYMBOLS (b, j, sym)
{
QUIT;
- sym = BLOCK_SYM (b, j);
if (file_matches (s->filename, files, nfiles)
&& ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
&& ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
/* Begin overload resolution functions */
+
+static char *
+remove_params (const char *demangled_name)
+{
+ const char *argp;
+ char *new_name;
+ int depth;
+
+ if (demangled_name == NULL)
+ return NULL;
+
+ /* First find the end of the arg list. */
+ argp = strrchr (demangled_name, ')');
+ if (argp == NULL)
+ return NULL;
+
+ /* Back up to the beginning. */
+ depth = 1;
+
+ while (argp-- > demangled_name)
+ {
+ if (*argp == ')')
+ depth ++;
+ else if (*argp == '(')
+ {
+ depth --;
+
+ if (depth == 0)
+ break;
+ }
+ }
+ if (depth != 0)
+ internal_error (__FILE__, __LINE__,
+ "bad demangled name %s\n", demangled_name);
+ while (argp[-1] == ' ' && argp > demangled_name)
+ argp --;
+
+ new_name = xmalloc (argp - demangled_name + 1);
+ memcpy (new_name, demangled_name, argp - demangled_name);
+ new_name[argp - demangled_name] = '\0';
+ return new_name;
+}
+
/* Helper routine for make_symbol_completion_list. */
static int sym_return_val_size;
{
int newsize;
int i;
+ char *sym_name;
+
+ /* If there is no type information, we can't do anything, so skip */
+ if (SYMBOL_TYPE (sym) == NULL)
+ return;
+
+ /* skip any symbols that we've already considered. */
+ for (i = 0; i < sym_return_val_index; ++i)
+ if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
+ return;
/* Get the demangled name without parameters */
- char *sym_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ARM | DMGL_ANSI);
+ sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
if (!sym_name)
- {
- sym_name = (char *) xmalloc (strlen (SYMBOL_NAME (sym)) + 1);
- strcpy (sym_name, SYMBOL_NAME (sym));
- }
+ return;
/* skip symbols that cannot match */
if (strcmp (sym_name, oload_name) != 0)
return;
}
- /* If there is no type information, we can't do anything, so skip */
- if (SYMBOL_TYPE (sym) == NULL)
- return;
-
- /* skip any symbols that we've already considered. */
- for (i = 0; i < sym_return_val_index; ++i)
- if (!strcmp (SYMBOL_NAME (sym), SYMBOL_NAME (sym_return_val[i])))
- return;
+ xfree (sym_name);
/* We have a match for an overload instance, so add SYM to the current list
* of overload instances */
}
sym_return_val[sym_return_val_index++] = sym;
sym_return_val[sym_return_val_index] = NULL;
-
- xfree (sym_name);
}
/* Return a null-terminated list of pointers to function symbols that
/* Length of name. */
int oload_name_len = 0;
- /* Look for the symbol we are supposed to complete on.
- * FIXME: This should be language-specific. */
+ /* Look for the symbol we are supposed to complete on. */
- oload_name = cplus_demangle (SYMBOL_NAME (fsym), DMGL_ARM | DMGL_ANSI);
+ oload_name = remove_params (SYMBOL_DEMANGLED_NAME (fsym));
if (!oload_name)
{
- oload_name = (char *) xmalloc (strlen (SYMBOL_NAME (fsym)) + 1);
- strcpy (oload_name, SYMBOL_NAME (fsym));
+ sym_return_val_size = 1;
+ sym_return_val = (struct symbol **) xmalloc (2 * sizeof (struct symbol *));
+ sym_return_val[0] = fsym;
+ sym_return_val[1] = NULL;
+
+ return sym_return_val;
}
oload_name_len = strlen (oload_name);
decode_line_spec (char *string, int funfirstline)
{
struct symtabs_and_lines sals;
+ struct symtab_and_line cursal;
+
if (string == 0)
error ("Empty line specification.");
+
+ /* We use whatever is set as the current source line. We do not try
+ and get a default or it will recursively call us! */
+ cursal = get_current_source_symtab_and_line ();
+
sals = decode_line_1 (&string, funfirstline,
- current_source_symtab, current_source_line,
+ cursal.symtab, cursal.line,
(char ***) NULL);
+
if (*string)
error ("Junk at end of line specification: %s", string);
return sals;