aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-support.c
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2003-06-12 15:33:45 +0000
committerDavid Carlton <carlton@bactrian.org>2003-06-12 15:33:45 +0000
commitb64296285dff79d58ce7b9dad578d5f3438a6cd4 (patch)
treec0da4b856c19734555a8da3d1f52fd63f4ec65d9 /gdb/cp-support.c
parent00c22daa1fec5c861e84cc6caa129e7c9a4d1b71 (diff)
downloadfsf-binutils-gdb-b64296285dff79d58ce7b9dad578d5f3438a6cd4.zip
fsf-binutils-gdb-b64296285dff79d58ce7b9dad578d5f3438a6cd4.tar.gz
fsf-binutils-gdb-b64296285dff79d58ce7b9dad578d5f3438a6cd4.tar.bz2
2003-06-12 David Carlton <carlton@bactrian.org>
* symtab.h: Delete declaration of make_symbol_overload_list. Add declaration of lookup_partial_symbol. * symtab.c (remove_params): Move to cp-support.c. (overload_list_add_symbol, make_symbol_overload_list) (sym_return_val_size, sym_return_val_index): Ditto. (lookup_partial_symbol): Make extern. * cp-support.h: Add declaration of make_symbol_overload_list. * cp-support.c: Include dictionary.h, objfiles.h, frame.h, symtab.h, and block.h. (remove_params): Move here from symtab.c. (overload_list_add_symbol, make_symbol_overload_list) (sym_return_val_size, sym_return_val_index): Ditto. * valops.c: Include cp-support.h. * Makefile.in (cp-support.o): Depend on dictionary_h, objfiles_h, frame_h, and block_h. (valops.o): Depend on cp_support_h.
Diffstat (limited to 'gdb/cp-support.c')
-rw-r--r--gdb/cp-support.c213
1 files changed, 213 insertions, 0 deletions
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index 364d31e..64b3f89 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -27,6 +27,21 @@
#include "demangle.h"
#include "gdb_assert.h"
#include "gdbcmd.h"
+#include "dictionary.h"
+#include "objfiles.h"
+#include "frame.h"
+#include "symtab.h"
+#include "block.h"
+
+/* Functions/variables related to overload resolution. */
+
+static int sym_return_val_size;
+static int sym_return_val_index;
+static struct symbol **sym_return_val;
+
+static char *remove_params (const char *demangled_name);
+
+static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
/* The list of "maint cplus" commands. */
@@ -324,6 +339,204 @@ cp_entire_prefix_len (const char *name)
return previous_len;
}
+/* 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;
+}
+
+/* Test to see if the symbol specified by SYMNAME (which is already
+ demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
+ characters. If so, add it to the current completion list. */
+
+static void
+overload_list_add_symbol (struct symbol *sym, char *oload_name)
+{
+ 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 (DEPRECATED_SYMBOL_NAME (sym), DEPRECATED_SYMBOL_NAME (sym_return_val[i])))
+ return;
+
+ /* Get the demangled name without parameters */
+ sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
+ if (!sym_name)
+ return;
+
+ /* skip symbols that cannot match */
+ if (strcmp (sym_name, oload_name) != 0)
+ {
+ xfree (sym_name);
+ return;
+ }
+
+ xfree (sym_name);
+
+ /* We have a match for an overload instance, so add SYM to the current list
+ * of overload instances */
+ if (sym_return_val_index + 3 > sym_return_val_size)
+ {
+ newsize = (sym_return_val_size *= 2) * sizeof (struct symbol *);
+ sym_return_val = (struct symbol **) xrealloc ((char *) sym_return_val, newsize);
+ }
+ sym_return_val[sym_return_val_index++] = sym;
+ sym_return_val[sym_return_val_index] = NULL;
+}
+
+/* Return a null-terminated list of pointers to function symbols that
+ * match name of the supplied symbol FSYM.
+ * This is used in finding all overloaded instances of a function name.
+ * This has been modified from make_symbol_completion_list. */
+
+
+struct symbol **
+make_symbol_overload_list (struct symbol *fsym)
+{
+ register struct symbol *sym;
+ register struct symtab *s;
+ register struct partial_symtab *ps;
+ register struct objfile *objfile;
+ register struct block *b, *surrounding_static_block = 0;
+ struct dict_iterator iter;
+ /* The name we are completing on. */
+ char *oload_name = NULL;
+ /* Length of name. */
+ int oload_name_len = 0;
+
+ /* Look for the symbol we are supposed to complete on. */
+
+ oload_name = remove_params (SYMBOL_DEMANGLED_NAME (fsym));
+ if (!oload_name)
+ {
+ 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);
+
+ sym_return_val_size = 100;
+ sym_return_val_index = 0;
+ sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
+ sym_return_val[0] = NULL;
+
+ /* Read in all partial symtabs containing a partial symbol named
+ OLOAD_NAME. */
+
+ ALL_PSYMTABS (objfile, ps)
+ {
+ struct partial_symbol **psym;
+
+ /* If the psymtab's been read in we'll get it when we search
+ through the blockvector. */
+ if (ps->readin)
+ continue;
+
+ if ((lookup_partial_symbol (ps, oload_name, NULL, 1, VAR_DOMAIN)
+ != NULL)
+ || (lookup_partial_symbol (ps, oload_name, NULL, 0, VAR_DOMAIN)
+ != NULL))
+ PSYMTAB_TO_SYMTAB (ps);
+ }
+
+ /* Search upwards from currently selected frame (so that we can
+ complete on local vars. */
+
+ for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+ {
+ if (!BLOCK_SUPERBLOCK (b))
+ {
+ surrounding_static_block = b; /* For elimination of dups */
+ }
+
+ /* Also catch fields of types defined in this places which match our
+ text string. Only complete on types visible from current context. */
+
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ /* Go through the symtabs and check the externs and statics for
+ symbols which match. */
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ ALL_SYMTABS (objfile, s)
+ {
+ QUIT;
+ b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
+ /* Don't do this block twice. */
+ if (b == surrounding_static_block)
+ continue;
+ ALL_BLOCK_SYMBOLS (b, iter, sym)
+ {
+ overload_list_add_symbol (sym, oload_name);
+ }
+ }
+
+ xfree (oload_name);
+
+ return (sym_return_val);
+}
+
+
/* Don't allow just "maintenance cplus". */
static void