2004-02-02 David Carlton <carlton@kealia.com>

* valops.c (enum oload_classification): New.
	(find_overload_match): Break implementation into separate
	functions; delete #if 0'd code; look for symbols within
	namespaces.
	(find_oload_champ_namespace,find_oload_champ_namespace_loop)
	(find_oload_champ,oload_method_static,classify_oload_match): New.
	* cp-support.h: Add declaration for cp_func_name; update
	declaration for make_symbol_overload_list.
	* cp-support.c (cp_func_name): New.
	(overload_list_add_symbol): Fix comment, use
	SYMBOL_LINKAGE_NAME and SYMBOL_NATURAL_NAME.
	(make_symbol_overload_list): Take a function name and a namespace
	instead of a symbol; change implementation.
	(make_symbol_overload_list_using): New.
	(make_symbol_overload_list_qualified, read_in_psymtabs): New.

2004-02-02  David Carlton  <carlton@kealia.com>

	* gdb.cp/overload.exp: Add overloadNamespace tests.
	* gdb.cp/overload.cc (dummyClass, dummyInstance): New.
	(overloadNamespace, XXX): New.
	(main): Call XXX::marker2.
This commit is contained in:
David Carlton 2004-02-02 20:44:53 +00:00
parent 15390fef31
commit 8d577d328a
7 changed files with 542 additions and 184 deletions

View File

@ -1,3 +1,21 @@
2004-02-02 David Carlton <carlton@kealia.com>
* valops.c (enum oload_classification): New.
(find_overload_match): Break implementation into separate
functions; delete #if 0'd code; look for symbols within
namespaces.
(find_oload_champ_namespace,find_oload_champ_namespace_loop)
(find_oload_champ,oload_method_static,classify_oload_match): New.
* cp-support.h: Add declaration for cp_func_name; update
declaration for make_symbol_overload_list.
* cp-support.c (cp_func_name): New.
(overload_list_add_symbol): Fix comment, use
SYMBOL_LINKAGE_NAME and SYMBOL_NATURAL_NAME.
(make_symbol_overload_list): Take a function name and a namespace
instead of a symbol; change implementation.
(make_symbol_overload_list_using): New.
(make_symbol_overload_list_qualified, read_in_psymtabs): New.
2004-02-02 Fred Fish <fnf@redhat.com>
* main.c (gdb_stdtarg): Move definition to group with other

View File

@ -52,7 +52,15 @@ 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);
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);
static void make_symbol_overload_list_qualified (const char *func_name);
static void read_in_psymtabs (const char *oload_name);
/* The list of "maint cplus" commands. */
@ -386,6 +394,34 @@ cp_entire_prefix_len (const char *name)
return previous_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. The
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 = (previous_component
+ cp_find_first_component (previous_component));
*next_component == ':';
next_component = (previous_component
+ cp_find_first_component (previous_component)))
{
/* Skip '::'. */
previous_component = next_component + 2;
}
return remove_params (previous_component);
}
/* Overload resolution functions. */
static char *
@ -430,12 +466,12 @@ remove_params (const char *demangled_name)
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. */
/* Test to see if SYM is a symbol that we haven't seen corresponding
to a function named OLOAD_NAME. If so, add it to the current
completion list. */
static void
overload_list_add_symbol (struct symbol *sym, char *oload_name)
overload_list_add_symbol (struct symbol *sym, const char *oload_name)
{
int newsize;
int i;
@ -447,11 +483,12 @@ overload_list_add_symbol (struct symbol *sym, char *oload_name)
/* 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])))
if (strcmp (SYMBOL_LINKAGE_NAME (sym),
SYMBOL_LINKAGE_NAME (sym_return_val[i])) == 0)
return;
/* Get the demangled name without parameters */
sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
sym_name = remove_params (SYMBOL_NATURAL_NAME (sym));
if (!sym_name)
return;
@ -476,82 +513,108 @@ overload_list_add_symbol (struct symbol *sym, char *oload_name)
}
/* 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. */
are named FUNC_NAME and are visible within NAMESPACE. */
struct symbol **
make_symbol_overload_list (struct symbol *fsym)
make_symbol_overload_list (const char *func_name,
const char *namespace)
{
struct symbol *sym;
struct symtab *s;
struct partial_symtab *ps;
struct objfile *objfile;
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);
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;
/* Read in all partial symtabs containing a partial symbol named
OLOAD_NAME. */
old_cleanups = make_cleanup (xfree, sym_return_val);
ALL_PSYMTABS (objfile, ps)
{
struct partial_symbol **psym;
make_symbol_overload_list_using (func_name, namespace);
/* 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);
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);
}
return sym_return_val;
}
/* 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)
{
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 (get_selected_block (0));
current != NULL;
current = current->next)
{
if (strcmp (namespace, current->outer) == 0)
{
make_symbol_overload_list_using (func_name,
current->inner);
}
}
/* Now, add names for this namespace. */
if (namespace[0] == '\0')
{
make_symbol_overload_list_qualified (func_name);
}
else
{
char *concatenated_name
= alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
strcpy (concatenated_name, namespace);
strcat (concatenated_name, "::");
strcat (concatenated_name, 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). */
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))
{
surrounding_static_block = b; /* For elimination of dups */
}
dict = BLOCK_DICT (b);
/* 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)
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);
}
}
surrounding_static_block = block_static_block (get_selected_block (0));
/* Go through the symtabs and check the externs and statics for
symbols which match. */
@ -559,10 +622,14 @@ make_symbol_overload_list (struct symbol *fsym)
{
QUIT;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
ALL_BLOCK_SYMBOLS (b, iter, sym)
{
overload_list_add_symbol (sym, oload_name);
}
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, func_name);
}
}
ALL_SYMTABS (objfile, s)
@ -572,15 +639,37 @@ make_symbol_overload_list (struct symbol *fsym)
/* 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);
}
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, func_name);
}
}
}
xfree (oload_name);
/* Look through the partial symtabs for all symbols which begin
by matching FUNC_NAME. Make sure we read that symbol table in. */
return (sym_return_val);
static void
read_in_psymtabs (const char *func_name)
{
struct partial_symtab *ps;
struct objfile *objfile;
ALL_PSYMTABS (objfile, ps)
{
if (ps->readin)
continue;
if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN)
!= NULL)
|| (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN)
!= NULL))
psymtab_to_symtab (ps);
}
}
/* Lookup the rtti type for a class name. */

View File

@ -60,7 +60,10 @@ extern unsigned int cp_find_first_component (const char *name);
extern unsigned int cp_entire_prefix_len (const char *name);
extern struct symbol **make_symbol_overload_list (struct symbol *);
extern char *cp_func_name (const char *full_name);
extern struct symbol **make_symbol_overload_list (const char *,
const char *);
extern struct type *cp_lookup_rtti_type (const char *name,
struct block *block);

View File

@ -1,3 +1,10 @@
2004-02-02 David Carlton <carlton@kealia.com>
* gdb.cp/overload.exp: Add overloadNamespace tests.
* gdb.cp/overload.cc (dummyClass, dummyInstance): New.
(overloadNamespace, XXX): New.
(main): Call XXX::marker2.
2004-02-01 Fred Fish <fnf@redhat.com>
* gdb.base/dump.exp: Use runto_main instead of "runto main".

View File

@ -53,6 +53,31 @@ int intToChar (char c)
void marker1()
{}
// Now test how overloading and namespaces interact.
class dummyClass {};
dummyClass dummyInstance;
int overloadNamespace(int i)
{
return 1;
}
int overloadNamespace(dummyClass d)
{
return 2;
}
namespace XXX {
int overloadNamespace (char c)
{
return 3;
}
void marker2() {}
}
int main ()
{
char arg2 = 2;
@ -81,7 +106,8 @@ int main ()
intToChar(1);
marker1(); // marker1-returns-here
return 0; // marker1-returns-here
XXX::marker2(); // marker1-returns-here
return 0;
}
foo::foo (int i) { ifoo = i; ccpfoo = NULL; }

View File

@ -296,6 +296,21 @@ gdb_test "list \"foo::overloadfnarg(int, int (*)(int))\"" \
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
"list overloaded function with function ptr args - quotes around argument"
# Now some tests to see how overloading and namespaces interact.
gdb_test "print overloadNamespace(1)" ".\[0-9\]* = 1"
gdb_test "print overloadNamespace('a')" ".\[0-9\]* = 1"
gdb_test "print overloadNamespace(dummyInstance)" ".\[0-9\]* = 2"
if ![runto 'XXX::marker2'] then {
perror "couldn't run to XXX::marker2"
continue
}
gdb_test "print overloadNamespace(1)" ".\[0-9\]* = 3" "print overloadNamespace(1) in XXX"
gdb_test "print overloadNamespace('a')" ".\[0-9\]* = 3" "print overloadNamespace('a') in XXX"
gdb_test "print overloadNamespace(dummyInstance)" ".\[0-9\]* = 2" "print overloadNamespace(dummyInstance) in XXX"
# One last mysterious test.
# I wonder what this is for?

View File

@ -62,6 +62,38 @@ static struct value *search_struct_method (char *, struct value **,
struct value **,
int, int *, struct type *);
static int find_oload_champ_namespace (struct type **arg_types, int nargs,
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 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,
struct fn_field *fns_ptr,
struct symbol **oload_syms,
struct badness_vector **oload_champ_bv);
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,
int nargs,
int static_offset);
static int check_field_in (struct type *, const char *);
static struct value *value_struct_elt_for_reference (struct type *domain,
@ -1893,19 +1925,10 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
int lax, struct value **objp, struct symbol *fsym,
struct value **valp, struct symbol **symp, int *staticp)
{
int nparms;
struct type **parm_types;
int champ_nparms = 0;
struct value *obj = (objp ? *objp : NULL);
short oload_champ = -1; /* Index of best overloaded function */
short oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
/* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
short oload_ambig_champ = -1; /* 2nd contender for best match */
short oload_non_standard = 0; /* did we have to use non-standard conversions? */
short oload_incompatible = 0; /* are args supplied incompatible with any function? */
int oload_champ; /* Index of best overloaded function */
struct badness_vector *bv; /* A measure of how good an overloaded instance is */
struct badness_vector *oload_champ_bv = NULL; /* The measure for the current best match */
struct value *temp = obj;
@ -1914,13 +1937,13 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
int num_fns = 0; /* Number of overloaded instances being considered */
struct type *basetype = NULL;
int boffset;
int jj;
int ix;
int static_offset;
struct cleanup *cleanups = NULL;
struct cleanup *old_cleanups = NULL;
char *obj_type_name = NULL;
const char *obj_type_name = NULL;
char *func_name = NULL;
enum oload_classification match_quality;
/* Get the list of overloaded methods or functions */
if (method)
@ -1944,38 +1967,269 @@ 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 = cplus_demangle (DEPRECATED_SYMBOL_NAME (fsym), DMGL_NO_OPTS);
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. */
if (!func_name)
if (func_name == NULL)
{
*symp = fsym;
return 0;
}
oload_syms = make_symbol_overload_list (fsym);
cleanups = make_cleanup (xfree, oload_syms);
while (oload_syms[++i])
num_fns++;
if (!num_fns)
error ("Couldn't find function %s", func_name);
old_cleanups = make_cleanup (xfree, func_name);
make_cleanup (xfree, oload_syms);
make_cleanup (xfree, oload_champ_bv);
oload_champ = find_oload_champ_namespace (arg_types, nargs,
func_name,
qualified_name,
&oload_syms,
&oload_champ_bv);
}
oload_champ_bv = NULL;
/* Check how bad the best match is. */
match_quality
= classify_oload_match (oload_champ_bv, nargs,
oload_method_static (method, fns_ptr,
oload_champ));
if (match_quality == INCOMPATIBLE)
{
if (method)
error ("Cannot resolve method %s%s%s to any overloaded instance",
obj_type_name,
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
error ("Cannot resolve function %s to any overloaded instance",
func_name);
}
else if (match_quality == NON_STANDARD)
{
if (method)
warning ("Using non-standard conversion to match method %s%s%s to supplied arguments",
obj_type_name,
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
warning ("Using non-standard conversion to match function %s to supplied arguments",
func_name);
}
if (method)
{
if (staticp != NULL)
*staticp = oload_method_static (method, fns_ptr, oload_champ);
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
*valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
else
*valp = value_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
}
else
{
*symp = oload_syms[oload_champ];
}
if (objp)
{
if (TYPE_CODE (VALUE_TYPE (temp)) != TYPE_CODE_PTR
&& TYPE_CODE (VALUE_TYPE (*objp)) == TYPE_CODE_PTR)
{
temp = value_addr (temp);
}
*objp = temp;
}
if (old_cleanups != NULL)
do_cleanups (old_cleanups);
switch (match_quality)
{
case INCOMPATIBLE:
return 100;
case NON_STANDARD:
return 10;
default: /* STANDARD */
return 0;
}
}
/* Find the best overload match, 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 and
*OLOAD_CHAMP_BV. */
static int
find_oload_champ_namespace (struct type **arg_types, int nargs,
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,
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.
It is the caller's responsibility to free *OLOAD_SYMS and
*OLOAD_CHAMP_BV. */
static int
find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
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 next_namespace_len = 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;
char *new_namespace;
if (next_namespace_len != 0)
{
gdb_assert (qualified_name[next_namespace_len] == ':');
next_namespace_len += 2;
}
next_namespace_len
+= cp_find_first_component (qualified_name + next_namespace_len);
/* Initialize these to values that can safely be xfree'd. */
*oload_syms = NULL;
*oload_champ_bv = NULL;
/* 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,
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);
old_cleanups = make_cleanup (xfree, *oload_champ_bv);
new_namespace = alloca (namespace_len + 1);
strncpy (new_namespace, qualified_name, namespace_len);
new_namespace[namespace_len] = '\0';
new_oload_syms = make_symbol_overload_list (func_name,
new_namespace);
while (new_oload_syms[num_fns])
++num_fns;
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)
{
*oload_syms = new_oload_syms;
*oload_champ = new_oload_champ;
*oload_champ_bv = new_oload_champ_bv;
do_cleanups (old_cleanups);
return 1;
}
else if (searched_deeper)
{
xfree (new_oload_syms);
xfree (new_oload_champ_bv);
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.
The number of methods/functions in the list is given by NUM_FNS.
Return the index of the best match; store an indication of the
quality of the match in OLOAD_CHAMP_BV.
It is the caller's responsibility to free *OLOAD_CHAMP_BV. */
static int
find_oload_champ (struct type **arg_types, int nargs, int method,
int num_fns, struct fn_field *fns_ptr,
struct symbol **oload_syms,
struct badness_vector **oload_champ_bv)
{
int ix;
struct badness_vector *bv; /* A measure of how good an overloaded instance is */
int oload_champ = -1; /* Index of best overloaded function */
int oload_ambiguous = 0; /* Current ambiguity state for overload resolution */
/* 0 => no ambiguity, 1 => two good funcs, 2 => incomparable funcs */
*oload_champ_bv = NULL;
/* Consider each candidate in turn */
for (ix = 0; ix < num_fns; ix++)
{
static_offset = 0;
int jj;
int static_offset = oload_method_static (method, fns_ptr, ix);
int nparms;
struct type **parm_types;
if (method)
{
if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
static_offset = 1;
nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
}
else
@ -1996,30 +2250,25 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
bv = rank_function (parm_types, nparms, arg_types + static_offset,
nargs - static_offset);
if (!oload_champ_bv)
if (!*oload_champ_bv)
{
oload_champ_bv = bv;
*oload_champ_bv = bv;
oload_champ = 0;
champ_nparms = nparms;
}
else
/* See whether current candidate is better or worse than previous best */
switch (compare_badness (bv, oload_champ_bv))
switch (compare_badness (bv, *oload_champ_bv))
{
case 0:
oload_ambiguous = 1; /* top two contenders are equally good */
oload_ambig_champ = ix;
break;
case 1:
oload_ambiguous = 2; /* incomparable top contenders */
oload_ambig_champ = ix;
break;
case 2:
oload_champ_bv = bv; /* new champion, record details */
*oload_champ_bv = bv; /* new champion, record details */
oload_ambiguous = 0;
oload_champ = ix;
oload_ambig_champ = -1;
champ_nparms = nparms;
break;
case 3:
default:
@ -2036,90 +2285,41 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
fprintf_filtered (gdb_stderr,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
}
} /* end loop over all candidates */
/* 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
way to differentiate based on return type, which we need to in
cases like overloads of .begin() <It's both const and non-const> */
#if 0
if (oload_ambiguous)
{
if (method)
error ("Cannot resolve overloaded method %s%s%s to unique instance; disambiguate by specifying function signature",
obj_type_name,
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
error ("Cannot resolve overloaded function %s to unique instance; disambiguate by specifying function signature",
func_name);
}
#endif
/* Check how bad the best match is. */
static_offset = 0;
if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
static_offset = 1;
return oload_champ;
}
/* Return 1 if we're looking at a static method, 0 if we're looking at
a non-static method or a function that isn't a method. */
static int
oload_method_static (int method, struct fn_field *fns_ptr, int index)
{
if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, index))
return 1;
else
return 0;
}
/* Check how good an overload match OLOAD_CHAMP_BV represents. */
static enum oload_classification
classify_oload_match (struct badness_vector *oload_champ_bv,
int nargs,
int static_offset)
{
int ix;
for (ix = 1; ix <= nargs - static_offset; ix++)
{
if (oload_champ_bv->rank[ix] >= 100)
oload_incompatible = 1; /* truly mismatched types */
return INCOMPATIBLE; /* truly mismatched types */
else if (oload_champ_bv->rank[ix] >= 10)
oload_non_standard = 1; /* non-standard type conversions needed */
}
if (oload_incompatible)
{
if (method)
error ("Cannot resolve method %s%s%s to any overloaded instance",
obj_type_name,
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
error ("Cannot resolve function %s to any overloaded instance",
func_name);
}
else if (oload_non_standard)
{
if (method)
warning ("Using non-standard conversion to match method %s%s%s to supplied arguments",
obj_type_name,
(obj_type_name && *obj_type_name) ? "::" : "",
name);
else
warning ("Using non-standard conversion to match function %s to supplied arguments",
func_name);
return NON_STANDARD; /* non-standard type conversions needed */
}
if (method)
{
if (staticp && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
*staticp = 1;
else if (staticp)
*staticp = 0;
if (TYPE_FN_FIELD_VIRTUAL_P (fns_ptr, oload_champ))
*valp = value_virtual_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
else
*valp = value_fn_field (&temp, fns_ptr, oload_champ, basetype, boffset);
}
else
{
*symp = oload_syms[oload_champ];
xfree (func_name);
}
if (objp)
{
if (TYPE_CODE (VALUE_TYPE (temp)) != TYPE_CODE_PTR
&& TYPE_CODE (VALUE_TYPE (*objp)) == TYPE_CODE_PTR)
{
temp = value_addr (temp);
}
*objp = temp;
}
if (cleanups != NULL)
do_cleanups (cleanups);
return oload_incompatible ? 100 : (oload_non_standard ? 10 : 0);
return STANDARD; /* Only standard conversions needed. */
}
/* C++: return 1 is NAME is a legitimate name for the destructor