summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2003-02-01 01:17:22 +0000
committerDavid Carlton <carlton@bactrian.org>2003-02-01 01:17:22 +0000
commit3bebe8f1863428e19f3d404f7bf0007c1451e51a (patch)
tree22d406b74117ece8e00472c3e4cd65235f3d57ae
parentbe431c34739ec12c2b1f8172e1d1fd16193db636 (diff)
downloadgdb-3bebe8f1863428e19f3d404f7bf0007c1451e51a.tar.gz
2003-01-31 David Carlton <carlton@math.stanford.edu>
From Jim Blandy <jimb@redhat.com>: Use a single, consistent representation for an empty minimal symbol table in an objfile. * objfiles.c (terminate_minimal_symbol_table): New function. (allocate_objfile): Call it. * objfiles.h (terminate_minimal_symbol_table): New declaration. (ALL_MSYMBOLS): No need to test whether (objfile)->msymbols is non-NULL. * minsyms.c (lookup_minimal_symbol_by_pc_section): To see whether objfile has minimal symbols, compare minimal_symbol_count to zero, instead of comparing msymbols with NULL. * objfiles.c (have_minimal_symbols): Same. * solib-sunos.c (solib_add_common_symbols): Call terminate_minimal_symbol_table. * symfile.c (reread_symbols): Same. * objfiles.h: Revert patch from 2003-01-27, to be replaced by similar patch from Jim Blandy. * objfiles.c (objfile_relocate): Ditto. * i386-linux-tdep.c (find_minsym_and_objfile): Ditto. * arm-linux-tdep.c (find_minsym_and_objfile): Ditto. * gdbtypes.h: Delete INTEGER_COERCION_BADNESS, FLOAT_COERCION_BADNESS. * gdbtypes.c (rank_one_type): Replace all uses of INTEGER_COERCION_BADNESS by INTEGER_CONVERSION_BADNESS. * valops.c (find_overload_match): Call cp_func_name. * cp-support.h: Declare cp_func_name. * cp-support.c (cp_func_name): New function. 2003-01-30 David Carlton <carlton@math.stanford.edu> * valops.c (find_overload_match): Move code into find_oload_champ_namespace. (find_oload_champ_namespace): New function, which immediately gets eviscerated and turned into a call to find_oload_champ_namespace_loop. (find_oload_champ_namespace_loop): New function. * symtab.c (make_symbol_overload_list): Move entire body into make_symbol_overload_list_qualified. (make_symbol_overload_list_qualified): New. (read_in_psymtabs): New. (make_symbol_overload_list_qualified): Rewrite. (make_symbol_overload_list_using): New. (lookup_symbol_namespace): Use alloca, not xmalloc. (make_symbol_overload_list): Put some memory management stuff back in.
-rw-r--r--gdb/ChangeLog50
-rw-r--r--gdb/arm-linux-tdep.c16
-rw-r--r--gdb/cp-support.c26
-rw-r--r--gdb/cp-support.h2
-rw-r--r--gdb/gdbtypes.c24
-rw-r--r--gdb/gdbtypes.h4
-rw-r--r--gdb/i386-linux-tdep.c16
-rw-r--r--gdb/minsyms.c3
-rw-r--r--gdb/objfiles.c44
-rw-r--r--gdb/objfiles.h15
-rw-r--r--gdb/solib-sunos.c1
-rw-r--r--gdb/symfile.c1
-rw-r--r--gdb/symtab.c190
-rw-r--r--gdb/valops.c178
14 files changed, 452 insertions, 118 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 052f9a34364..74c62362e69 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,53 @@
+2003-01-31 David Carlton <carlton@math.stanford.edu>
+
+ From Jim Blandy <jimb@redhat.com>:
+
+ Use a single, consistent representation for an empty minimal
+ symbol table in an objfile.
+ * objfiles.c (terminate_minimal_symbol_table): New function.
+ (allocate_objfile): Call it.
+ * objfiles.h (terminate_minimal_symbol_table): New declaration.
+ (ALL_MSYMBOLS): No need to test whether (objfile)->msymbols is
+ non-NULL.
+ * minsyms.c (lookup_minimal_symbol_by_pc_section): To see whether
+ objfile has minimal symbols, compare minimal_symbol_count to zero,
+ instead of comparing msymbols with NULL.
+ * objfiles.c (have_minimal_symbols): Same.
+ * solib-sunos.c (solib_add_common_symbols): Call
+ terminate_minimal_symbol_table.
+ * symfile.c (reread_symbols): Same.
+
+ * objfiles.h: Revert patch from 2003-01-27, to be replaced by
+ similar patch from Jim Blandy.
+ * objfiles.c (objfile_relocate): Ditto.
+ * i386-linux-tdep.c (find_minsym_and_objfile): Ditto.
+ * arm-linux-tdep.c (find_minsym_and_objfile): Ditto.
+ * gdbtypes.h: Delete INTEGER_COERCION_BADNESS,
+ FLOAT_COERCION_BADNESS.
+ * gdbtypes.c (rank_one_type): Replace all uses of
+ INTEGER_COERCION_BADNESS by INTEGER_CONVERSION_BADNESS.
+ * valops.c (find_overload_match): Call cp_func_name.
+ * cp-support.h: Declare cp_func_name.
+ * cp-support.c (cp_func_name): New function.
+
+2003-01-30 David Carlton <carlton@math.stanford.edu>
+
+ * valops.c (find_overload_match): Move code into
+ find_oload_champ_namespace.
+ (find_oload_champ_namespace): New function, which immediately gets
+ eviscerated and turned into a call to
+ find_oload_champ_namespace_loop.
+ (find_oload_champ_namespace_loop): New function.
+ * symtab.c (make_symbol_overload_list): Move entire body into
+ make_symbol_overload_list_qualified.
+ (make_symbol_overload_list_qualified): New.
+ (read_in_psymtabs): New.
+ (make_symbol_overload_list_qualified): Rewrite.
+ (make_symbol_overload_list_using): New.
+ (lookup_symbol_namespace): Use alloca, not xmalloc.
+ (make_symbol_overload_list): Put some memory management stuff back
+ in.
+
2003-01-28 David Carlton <carlton@math.stanford.edu>
* valops.c (find_overload_match): Calculate func_name via
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index a55fea94ad6..627ed8dda47 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -355,15 +355,19 @@ static struct minimal_symbol *
find_minsym_and_objfile (char *name, struct objfile **objfile_p)
{
struct objfile *objfile;
- struct minimal_symbol *msym;
- ALL_MSYMBOLS (objfile, msym)
+ ALL_OBJFILES (objfile)
{
- if (SYMBOL_NAME (msym)
- && strcmp (SYMBOL_NAME (msym), name) == 0)
+ struct minimal_symbol *msym;
+
+ ALL_OBJFILE_MSYMBOLS (objfile, msym)
{
- *objfile_p = objfile;
- return msym;
+ if (SYMBOL_NAME (msym)
+ && strcmp (SYMBOL_NAME (msym), name) == 0)
+ {
+ *objfile_p = objfile;
+ return msym;
+ }
}
}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index d91070515c8..ecdbabb031c 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -664,6 +664,32 @@ cp_is_anonymous (const char *namespace_name, int namespace_len)
return (location - namespace_name) < namespace_len;
}
+/* If FULL_NAME is the demangled name of a C++ function (including an
+ arg list, possibly including namespace/class qualifications),
+ return a new string containing only the function name (without the
+ arg list/class qualifications). Otherwise, return NULL. Caller is
+ responsible for freeing the memory in question. */
+
+char *
+cp_func_name (const char *full_name)
+{
+ const char *previous_component = full_name;
+ const char *next_component;
+
+ if (!full_name)
+ return NULL;
+
+ for (next_component = cp_find_first_component (previous_component);
+ *next_component == ':';
+ next_component = cp_find_first_component (previous_component))
+ {
+ /* Skip '::'. */
+ previous_component = next_component + 2;
+ }
+
+ return remove_params (previous_component);
+}
+
void
_initialize_cp_support (void)
{
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index f14cf994e3c..1bf2f78f89f 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -108,3 +108,5 @@ extern void cp_check_possible_namespace_symbols (const char *name);
extern struct symbol *cp_lookup_possible_namespace_symbol (const char *name);
extern int cp_is_anonymous (const char *namespace_name, int namespace_len);
+
+extern char *cp_func_name (const char *full_name);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index b40d1eac9a0..87bcc2c3a05 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -2570,7 +2570,7 @@ rank_one_type (struct type *parm, struct type *arg)
if (TYPE_NOSIGN (arg)) /* plain char -> plain char */
return 0;
else
- return INTEGER_COERCION_BADNESS; /* signed/unsigned char -> plain char */
+ return INTEGER_CONVERSION_BADNESS; /* signed/unsigned char -> plain char */
}
else if (TYPE_UNSIGNED (parm))
{
@@ -2581,12 +2581,12 @@ rank_one_type (struct type *parm, struct type *arg)
else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */
else
- return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */
+ return INTEGER_CONVERSION_BADNESS; /* unsigned long -> unsigned int */
}
else
{
if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int"))
- return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */
+ return INTEGER_CONVERSION_BADNESS; /* signed long -> unsigned int */
else
return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */
}
@@ -2598,15 +2598,15 @@ rank_one_type (struct type *parm, struct type *arg)
else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
return INTEGER_PROMOTION_BADNESS;
else
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
}
else
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
}
else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
return INTEGER_PROMOTION_BADNESS;
else
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
case TYPE_CODE_ENUM:
case TYPE_CODE_CHAR:
case TYPE_CODE_RANGE:
@@ -2628,7 +2628,7 @@ rank_one_type (struct type *parm, struct type *arg)
case TYPE_CODE_RANGE:
case TYPE_CODE_BOOL:
case TYPE_CODE_ENUM:
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
case TYPE_CODE_FLT:
return INT_FLOAT_CONVERSION_BADNESS;
default:
@@ -2641,12 +2641,12 @@ rank_one_type (struct type *parm, struct type *arg)
case TYPE_CODE_RANGE:
case TYPE_CODE_BOOL:
case TYPE_CODE_ENUM:
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
case TYPE_CODE_FLT:
return INT_FLOAT_CONVERSION_BADNESS;
case TYPE_CODE_INT:
if (TYPE_LENGTH (arg) > TYPE_LENGTH (parm))
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
else if (TYPE_LENGTH (arg) < TYPE_LENGTH (parm))
return INTEGER_PROMOTION_BADNESS;
/* >>> !! else fall through !! <<< */
@@ -2658,7 +2658,7 @@ rank_one_type (struct type *parm, struct type *arg)
if (TYPE_NOSIGN (arg))
return 0;
else
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
}
else if (TYPE_UNSIGNED (parm))
{
@@ -2670,7 +2670,7 @@ rank_one_type (struct type *parm, struct type *arg)
else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
return 0;
else
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
default:
return INCOMPATIBLE_TYPE_BADNESS;
}
@@ -2683,7 +2683,7 @@ rank_one_type (struct type *parm, struct type *arg)
case TYPE_CODE_RANGE:
case TYPE_CODE_BOOL:
case TYPE_CODE_ENUM:
- return INTEGER_COERCION_BADNESS;
+ return INTEGER_CONVERSION_BADNESS;
case TYPE_CODE_FLT:
return INT_FLOAT_CONVERSION_BADNESS;
default:
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 8adc89eeb2c..525ffd7e2be 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -1221,10 +1221,6 @@ extern int count_virtual_fns (struct type *);
#define TOO_FEW_PARAMS_BADNESS 100
/* Badness if no conversion among types */
#define INCOMPATIBLE_TYPE_BADNESS 100
-/* Badness of coercing large integer to smaller size */
-#define INTEGER_COERCION_BADNESS 100
-/* Badness of coercing large floating type to smaller size */
-#define FLOAT_COERCION_BADNESS 100
/* Badness of integral promotion */
#define INTEGER_PROMOTION_BADNESS 1
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 6dca390021c..1ef14fcb900 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -322,15 +322,19 @@ static struct minimal_symbol *
find_minsym_and_objfile (char *name, struct objfile **objfile_p)
{
struct objfile *objfile;
- struct minimal_symbol *msym;
- ALL_MSYMBOLS (objfile, msym)
+ ALL_OBJFILES (objfile)
{
- if (SYMBOL_NAME (msym)
- && STREQ (SYMBOL_NAME (msym), name))
+ struct minimal_symbol *msym;
+
+ ALL_OBJFILE_MSYMBOLS (objfile, msym)
{
- *objfile_p = objfile;
- return msym;
+ if (SYMBOL_NAME (msym)
+ && STREQ (SYMBOL_NAME (msym), name))
+ {
+ *objfile_p = objfile;
+ return msym;
+ }
}
}
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 080c5bc33cc..5d5506bff32 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -405,8 +405,9 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
"null symbol". If there are no real symbols, then there is no
minimal symbol table at all. */
- if ((msymbol = objfile->msymbols) != NULL)
+ if (objfile->minimal_symbol_count > 0)
{
+ msymbol = objfile->msymbols;
lo = 0;
hi = objfile->minimal_symbol_count - 1;
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 48e4bf52a4a..d2578d7229e 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -283,6 +283,8 @@ allocate_objfile (bfd *abfd, int flags)
obstack_specify_allocation (&objfile->type_obstack, 0, 0, xmalloc,
xfree);
flags &= ~OBJF_MAPPED;
+
+ terminate_minimal_symbol_table (objfile);
}
/* Update the per-objfile information that comes from the bfd, ensuring
@@ -339,6 +341,31 @@ allocate_objfile (bfd *abfd, int flags)
return (objfile);
}
+/* Create the terminating entry of OBJFILE's minimal symbol table.
+ If OBJFILE->msymbols is zero, allocate a single entry from
+ OBJFILE->symbol_obstack; otherwise, just initialize
+ OBJFILE->msymbols[OBJFILE->minimal_symbol_count]. */
+void
+terminate_minimal_symbol_table (struct objfile *objfile)
+{
+ if (! objfile->msymbols)
+ objfile->msymbols = ((struct minimal_symbol *)
+ obstack_alloc (&objfile->symbol_obstack,
+ sizeof (objfile->msymbols[0])));
+
+ {
+ struct minimal_symbol *m
+ = &objfile->msymbols[objfile->minimal_symbol_count];
+
+ memset (m, 0, sizeof (*m));
+ SYMBOL_NAME (m) = NULL;
+ SYMBOL_VALUE_ADDRESS (m) = 0;
+ MSYMBOL_INFO (m) = NULL;
+ MSYMBOL_TYPE (m) = mst_unknown;
+ SYMBOL_INIT_LANGUAGE_SPECIFIC (m, language_unknown);
+ }
+}
+
/* Put OBJFILE at the front of the list. */
void
@@ -644,15 +671,12 @@ objfile_relocate (struct objfile *objfile, struct section_offsets *new_offsets)
}
}
- if (objfile->msymbols != NULL)
- {
- struct minimal_symbol *msym;
- ALL_OBJFILE_MSYMBOLS (objfile, msym)
- if (SYMBOL_SECTION (msym) >= 0)
- SYMBOL_VALUE_ADDRESS (msym)
- += ANOFFSET (delta, SYMBOL_SECTION (msym));
- }
-
+ {
+ struct minimal_symbol *msym;
+ ALL_OBJFILE_MSYMBOLS (objfile, msym)
+ if (SYMBOL_SECTION (msym) >= 0)
+ SYMBOL_VALUE_ADDRESS (msym) += ANOFFSET (delta, SYMBOL_SECTION (msym));
+ }
/* Relocating different sections by different amounts may cause the symbols
to be out of order. */
msymbols_sort (objfile);
@@ -783,7 +807,7 @@ have_minimal_symbols (void)
ALL_OBJFILES (ofp)
{
- if (ofp->msymbols != NULL)
+ if (ofp->minimal_symbol_count > 0)
{
return 1;
}
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index ea82a4166c3..a082cb081de 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -300,12 +300,6 @@ struct objfile
null symbol. The array itself, as well as all the data that it points
to, should be allocated on the symbol_obstack for this file. */
- /* NOTE: carlton/2003-01-27: For a newly-created objfile, msymbols
- is set to NULL, rather than a one-element array ending in a
- null symbol. ALL_MSYMBOLS already guarded against that case,
- so that seems to be a valid possibility; it can be useful if
- you like to create artificial objfiles. */
-
struct minimal_symbol *msymbols;
int minimal_symbol_count;
@@ -511,6 +505,8 @@ extern struct objfile *allocate_objfile (bfd *, int);
extern int build_objfile_section_table (struct objfile *);
+extern void terminate_minimal_symbol_table (struct objfile *objfile);
+
extern void objfile_to_front (struct objfile *);
extern void unlink_objfile (struct objfile *);
@@ -570,10 +566,6 @@ extern int is_in_import_list (char *, struct objfile *);
/* Traverse all minimal symbols in one objfile. */
-/* NOTE: carlton/2003-01-27: Don't call this macro unless
- objfile->msymbols is non-NULL. See NOTE above in the declaration
- of 'struct objfile'. */
-
#define ALL_OBJFILE_MSYMBOLS(objfile, m) \
for ((m) = (objfile) -> msymbols; SYMBOL_NAME(m) != NULL; (m)++)
@@ -593,8 +585,7 @@ extern int is_in_import_list (char *, struct objfile *);
#define ALL_MSYMBOLS(objfile, m) \
ALL_OBJFILES (objfile) \
- if ((objfile)->msymbols) \
- ALL_OBJFILE_MSYMBOLS (objfile, m)
+ ALL_OBJFILE_MSYMBOLS (objfile, m)
#define ALL_OBJFILE_OSECTIONS(objfile, osect) \
for (osect = objfile->sections; osect < objfile->sections_end; osect++)
diff --git a/gdb/solib-sunos.c b/gdb/solib-sunos.c
index ae115673c2b..25682e02caa 100644
--- a/gdb/solib-sunos.c
+++ b/gdb/solib-sunos.c
@@ -184,6 +184,7 @@ solib_add_common_symbols (CORE_ADDR rtc_symp)
xmalloc, xfree);
rt_common_objfile->minimal_symbol_count = 0;
rt_common_objfile->msymbols = NULL;
+ terminate_minimal_symbol_table (rt_common_objfile);
}
init_minimal_symbol_collection ();
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 37a0d20dba9..6372aa4c987 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1756,6 +1756,7 @@ reread_symbols (void)
error ("Can't find the file sections in `%s': %s",
objfile->name, bfd_errmsg (bfd_get_error ()));
}
+ terminate_minimal_symbol_table (objfile);
/* We use the same section offsets as from last time. I'm not
sure whether that is always correct for shared libraries. */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 3b83aeba4b7..332eb16973c 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -167,6 +167,15 @@ static void symtab_symbol_info (char *, namespace_enum, int);
static void overload_list_add_symbol (struct symbol *sym,
const char *oload_name);
+static void make_symbol_overload_list_using (const char *func_name,
+ const char *namespace_name,
+ int namespace_len,
+ const struct block *block);
+
+static void make_symbol_overload_list_qualified (const char *func_name);
+
+static void read_in_psymtabs (const char *oload_name);
+
void _initialize_symtab (void);
/* */
@@ -1293,7 +1302,7 @@ lookup_symbol_namespace (const char *namespace_name,
else
{
char *concatenated_name
- = xmalloc (namespace_len + 2 + strlen (name) + 1);
+ = alloca (namespace_len + 2 + strlen (name) + 1);
strncpy (concatenated_name, namespace_name, namespace_len);
strcpy (concatenated_name + namespace_len, "::");
strcpy (concatenated_name + namespace_len + 2, name);
@@ -1302,7 +1311,6 @@ lookup_symbol_namespace (const char *namespace_name,
cp_is_anonymous (namespace_name,
namespace_len));
- xfree (concatenated_name);
return sym;
}
}
@@ -3959,88 +3967,137 @@ overload_list_add_symbol (struct symbol *sym, const char *oload_name)
used in finding all overloaded instances of a function name. This
has been modified from make_symbol_completion_list. */
+/* FIXME: carlton/2003-01-30: Should BLOCK be here? Maybe it's better
+ to use get_selected_block (0). */
+
struct symbol **
make_symbol_overload_list (const char *func_name,
const char *namespace_name,
int namespace_len, const struct block *block)
{
- 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. */
- const char *oload_name = func_name;
+ struct cleanup *old_cleanups;
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 = xmalloc ((sym_return_val_size + 1) *
+ sizeof (struct symbol *));
sym_return_val[0] = NULL;
- /* Look through the partial symtabs for all symbols which begin
- by matching OLOAD_NAME. Make sure we read that symbol table in. */
+ old_cleanups = make_cleanup (xfree, sym_return_val);
- ALL_PSYMTABS (objfile, ps)
- {
- struct partial_symbol **psym;
+ make_symbol_overload_list_using (func_name, namespace_name,
+ namespace_len, block);
- /* If the psymtab's been read in we'll get it when we search
- through the blockvector. */
- if (ps->readin)
- continue;
+ discard_cleanups (old_cleanups);
- for (psym = objfile->global_psymbols.list + ps->globals_offset;
- psym < (objfile->global_psymbols.list + ps->globals_offset
- + ps->n_global_syms); psym++)
- {
- /* If interrupted, then quit. */
- QUIT;
- /* This will cause the symbol table to be read if it has not yet been */
- s = PSYMTAB_TO_SYMTAB (ps);
- }
+ return sym_return_val;
+}
- for (psym = objfile->static_psymbols.list + ps->statics_offset;
- psym < (objfile->static_psymbols.list + ps->statics_offset
- + ps->n_static_syms); psym++)
- {
- QUIT;
- /* This will cause the symbol table to be read if it has not yet been */
- s = PSYMTAB_TO_SYMTAB (ps);
- }
- }
+/* This applies the using directives to add namespaces to search in,
+ and then searches for overloads in all of those namespaces. It
+ adds the symbols found to sym_return_val. Arguments are as in
+ make_symbol_overload_list. */
+
+static void
+make_symbol_overload_list_using (const char *func_name,
+ const char *namespace_name,
+ int namespace_len,
+ const struct block *block)
+{
+ struct block_using_iterator iter;
+ const struct using_direct *current;
+
+ /* First, go through the using directives. If any of them apply,
+ look in the appropriate namespaces for new functions to match
+ on. */
+
+ for (current = block_using_iterator_first (block, &iter);
+ current != NULL;
+ current = block_using_iterator_next (&iter))
+ {
+ if (namespace_len == current->outer_length
+ && strncmp (namespace_name, current->name, namespace_len) == 0)
+ {
+ make_symbol_overload_list_using (func_name,
+ current->name,
+ current->inner_length,
+ block);
+ }
+ }
+
+ /* Now, add names for this namespace. */
+
+ if (namespace_len == 0)
+ {
+ make_symbol_overload_list_qualified (func_name);
+ }
+ else
+ {
+ char *concatenated_name
+ = alloca (namespace_len + 2 + strlen (func_name) + 1);
+ strncpy (concatenated_name, namespace_name, namespace_len);
+ strcpy (concatenated_name + namespace_len, "::");
+ strcpy (concatenated_name + namespace_len + 2, func_name);
+ make_symbol_overload_list_qualified (concatenated_name);
+ }
+}
+
+/* This does the bulk of the work of finding overloaded symbols.
+ FUNC_NAME is the name of the overloaded function we're looking for
+ (possibly including namespace info); NEW_LIST is 1 if we should
+ allocate a new list of overloads and 0 if we should continue using
+ the same old list. */
+
+static void
+make_symbol_overload_list_qualified (const char *func_name)
+{
+ struct symbol *sym;
+ struct symtab *s;
+ struct objfile *objfile;
+ const struct block *b, *surrounding_static_block = 0;
+ struct dict_iterator iter;
+ const struct dictionary *dict;
+
+ /* Look through the partial symtabs for all symbols which begin
+ by matching FUNC_NAME. Make sure we read that symbol table in. */
+
+ read_in_psymtabs (func_name);
/* 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))
+ dict = BLOCK_DICT (b);
+
+ for (sym = dict_iter_name_first (dict, func_name, &iter);
+ sym;
+ sym = dict_iter_name_next (func_name, &iter))
{
- surrounding_static_block = b; /* For elimination of dups */
+ overload_list_add_symbol (sym, func_name);
}
-
- /* 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);
- }
}
+ surrounding_static_block = block_static_block (get_selected_block (0));
+
/* Go through the symtabs and check the externs and statics for
symbols which match. */
+ /* FIXME: carlton/2003-01-30: Why are we checking all the statics?
+ Also, this shouldn't check all the globals if there's an
+ anonymous namespace involved somewhere. */
+
ALL_SYMTABS (objfile, s)
{
QUIT;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
- ALL_BLOCK_SYMBOLS (b, iter, sym)
+ dict = BLOCK_DICT (b);
+
+ for (sym = dict_iter_name_first (dict, func_name, &iter);
+ sym;
+ sym = dict_iter_name_next (func_name, &iter))
{
- overload_list_add_symbol (sym, oload_name);
+ overload_list_add_symbol (sym, func_name);
}
}
@@ -4051,13 +4108,36 @@ make_symbol_overload_list (const char *func_name,
/* Don't do this block twice. */
if (b == surrounding_static_block)
continue;
- ALL_BLOCK_SYMBOLS (b, iter, sym)
+ dict = BLOCK_DICT (b);
+
+ for (sym = dict_iter_name_first (dict, func_name, &iter);
+ sym;
+ sym = dict_iter_name_next (func_name, &iter))
{
- overload_list_add_symbol (sym, oload_name);
+ overload_list_add_symbol (sym, func_name);
}
}
+}
+
+/* Look through the partial symtabs for all symbols which begin
+ by matching FUNC_NAME. Make sure we read that symbol table in. */
+
+/* FIXME: carlton/2003-01-30. Lies, all lies. The function does
+ nothing of the kind: it just reads in every single partial symtab.
+ (It used to do it in a particularly amusing way, but I've fixed
+ that.) */
+
+static void
+read_in_psymtabs (const char *func_name)
+{
+ struct partial_symtab *ps;
+ struct objfile *objfile;
- return (sym_return_val);
+ ALL_PSYMTABS (objfile, ps)
+ {
+ if (!ps->readin)
+ psymtab_to_symtab (ps);
+ }
}
/* End of overload resolution functions */
diff --git a/gdb/valops.c b/gdb/valops.c
index 4a6e3ac498b..39eafaacdc9 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -64,7 +64,22 @@ static struct value *search_struct_method (char *, struct value **,
struct value **,
int, int *, struct type *);
-enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE };
+static int find_oload_champ_namespace (struct type **arg_types, int nargs,
+ const struct block *current_block,
+ const char *func_name,
+ const char *qualified_name,
+ struct symbol ***oload_syms,
+ struct badness_vector **oload_champ_bv);
+
+static
+int find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
+ const struct block *current_block,
+ const char *func_name,
+ const char *qualified_name,
+ int namespace_len,
+ struct symbol ***oload_syms,
+ struct badness_vector **oload_champ_bv,
+ int *oload_champ);
static int find_oload_champ (struct type **arg_types, int nargs, int method,
int num_fns,
@@ -75,6 +90,8 @@ static int find_oload_champ (struct type **arg_types, int nargs, int method,
static int oload_method_static (int method, struct fn_field *fns_ptr,
int index);
+enum oload_classification { STANDARD, NON_STANDARD, INCOMPATIBLE };
+
static enum
oload_classification classify_oload_match (struct badness_vector
* oload_champ_bv,
@@ -2846,11 +2863,13 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
been resolved by find_method_list via value_find_oload_method_list
above. */
gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
+ oload_champ = find_oload_champ (arg_types, nargs, method, num_fns,
+ fns_ptr, oload_syms, &oload_champ_bv);
}
else
{
- int i = -1;
- func_name = remove_params (SYMBOL_CPLUS_DEMANGLED_NAME (fsym));
+ const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+ func_name = cp_func_name (qualified_name);
/* If the name is NULL this must be a C-style function.
Just return the same symbol. */
@@ -2861,16 +2880,14 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
}
old_cleanups = make_cleanup (xfree, func_name);
- oload_syms = make_symbol_overload_list (func_name, "", 0, current_block);
- make_cleanup (xfree, oload_syms);
- while (oload_syms[++i])
- num_fns++;
- if (!num_fns)
- error ("Couldn't find function %s", func_name);
- }
- oload_champ = find_oload_champ (arg_types, nargs, method, num_fns, fns_ptr,
- oload_syms, &oload_champ_bv);
+ oload_champ = find_oload_champ_namespace (arg_types, nargs,
+ current_block,
+ func_name,
+ qualified_name,
+ &oload_syms,
+ &oload_champ_bv);
+ }
/* NOTE: dan/2000-03-10: Seems to be a better idea to just pick one
if they have the exact same goodness. This is because there is no
@@ -2957,6 +2974,143 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
}
}
+/* This finds the best overload, searching for FUNC_NAME in namespaces
+ contained in QUALIFIED_NAME until it either finds a good match or
+ runs out of namespaces. It stores the overloaded functions in
+ *OLOAD_SYMS, and the badness vector in *OLOAD_CHAMP_BV. The
+ calling function is responsible for freeing *OLOAD_SYMS. */
+
+static int
+find_oload_champ_namespace (struct type **arg_types, int nargs,
+ const struct block *current_block,
+ const char *func_name,
+ const char *qualified_name,
+ struct symbol ***oload_syms,
+ struct badness_vector **oload_champ_bv)
+{
+ int oload_champ;
+
+ find_oload_champ_namespace_loop (arg_types, nargs,
+ current_block, func_name,
+ qualified_name, 0,
+ oload_syms, oload_champ_bv,
+ &oload_champ);
+
+ return oload_champ;
+}
+
+/* Helper function for find_oload_champ_namespace; NAMESPACE_LEN is
+ how deep we've looked for namespaces, and the champ is stored in
+ OLOAD_CHAMP. The return value is 1 if the champ is a good one, 0
+ if it isn't. */
+
+/* FIXME: carlton/2003-01-30: This isn't the cleanest function I've
+ ever written, to put it mildly. All this overloading stuff could
+ use some refactoring. */
+
+static int
+find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
+ const struct block *current_block,
+ const char *func_name,
+ const char *qualified_name,
+ int namespace_len,
+ struct symbol ***oload_syms,
+ struct badness_vector **oload_champ_bv,
+ int *oload_champ)
+{
+ int modified_namespace_len = namespace_len;
+ int next_namespace_len;
+ int searched_deeper = 0;
+ int num_fns = 0;
+ struct cleanup *old_cleanups;
+ int new_oload_champ;
+ struct symbol **new_oload_syms;
+ struct badness_vector *new_oload_champ_bv;
+
+ if (modified_namespace_len != 0)
+ {
+ gdb_assert (qualified_name[modified_namespace_len] == ':');
+ modified_namespace_len += 2;
+ }
+ next_namespace_len
+ = (cp_find_first_component (qualified_name + modified_namespace_len)
+ - qualified_name);
+
+ /* First, see if we have a deeper namespace we can search in. If we
+ get a good match there, use it. */
+
+ if (qualified_name[next_namespace_len] == ':')
+ {
+ searched_deeper = 1;
+
+ if (find_oload_champ_namespace_loop (arg_types, nargs, current_block,
+ func_name, qualified_name,
+ next_namespace_len,
+ oload_syms, oload_champ_bv,
+ oload_champ))
+ {
+ return 1;
+ }
+ };
+
+ /* If we reach here, either we're in the deepest namespace or we
+ didn't find a good match in a deeper namespace. But, in the
+ latter case, we still have a bad match in a deeper namespace;
+ note that we might not find any match at all in the current
+ namespace. (There's always a match in the deepest namespace,
+ because this overload mechanism only gets called if there's a
+ function symbol to start off with.) */
+
+ old_cleanups = make_cleanup (xfree, *oload_syms);
+ new_oload_syms = make_symbol_overload_list (func_name,
+ qualified_name,
+ namespace_len,
+ current_block);
+ old_cleanups = make_cleanup (xfree, new_oload_syms);
+ while (new_oload_syms[num_fns])
+ ++num_fns;
+ if (!num_fns)
+ error ("Couldn't find function %s", func_name);
+
+ new_oload_champ = find_oload_champ (arg_types, nargs, 0, num_fns,
+ NULL, new_oload_syms,
+ &new_oload_champ_bv);
+
+ /* Case 1: We found a good match. Free earlier matches (if any),
+ and return it. Case 2: We didn't find a good match, but we're
+ not the deepest function. Then go with the bad match that the
+ deeper function found. Case 3: We found a bad match, and we're
+ the deepest function. Then return what we found, even though
+ it's a bad match. */
+
+ if (new_oload_champ != -1
+ && classify_oload_match (new_oload_champ_bv, nargs, 0) == STANDARD)
+ {
+ if (searched_deeper)
+ xfree (*oload_syms);
+ *oload_syms = new_oload_syms;
+ *oload_champ = new_oload_champ;
+ *oload_champ_bv = new_oload_champ_bv;
+ discard_cleanups (old_cleanups);
+ return 1;
+ }
+ else if (searched_deeper)
+ {
+ xfree (new_oload_syms);
+ discard_cleanups (old_cleanups);
+ return 0;
+ }
+ else
+ {
+ gdb_assert (new_oload_champ != -1);
+ *oload_syms = new_oload_syms;
+ *oload_champ = new_oload_champ;
+ *oload_champ_bv = new_oload_champ_bv;
+ discard_cleanups (old_cleanups);
+ return 0;
+ }
+}
+
/* Look for a function to take NARGS args of types ARG_TYPES. Find
the best match from among the overloaded methods or functions
(depending on METHOD) given by FNS_PTR or OLOAD_SYMS, respectively.