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:
parent
15390fef31
commit
8d577d328a
|
@ -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>
|
2004-02-02 Fred Fish <fnf@redhat.com>
|
||||||
|
|
||||||
* main.c (gdb_stdtarg): Move definition to group with other
|
* main.c (gdb_stdtarg): Move definition to group with other
|
||||||
|
|
231
gdb/cp-support.c
231
gdb/cp-support.c
|
@ -52,7 +52,15 @@ static struct symbol **sym_return_val;
|
||||||
|
|
||||||
static char *remove_params (const char *demangled_name);
|
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. */
|
/* The list of "maint cplus" commands. */
|
||||||
|
|
||||||
|
@ -386,6 +394,34 @@ cp_entire_prefix_len (const char *name)
|
||||||
return previous_len;
|
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. */
|
/* Overload resolution functions. */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -430,12 +466,12 @@ remove_params (const char *demangled_name)
|
||||||
return new_name;
|
return new_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test to see if the symbol specified by SYMNAME (which is already
|
/* Test to see if SYM is a symbol that we haven't seen corresponding
|
||||||
demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
|
to a function named OLOAD_NAME. If so, add it to the current
|
||||||
characters. If so, add it to the current completion list. */
|
completion list. */
|
||||||
|
|
||||||
static void
|
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 newsize;
|
||||||
int i;
|
int i;
|
||||||
|
@ -447,11 +483,12 @@ overload_list_add_symbol (struct symbol *sym, char *oload_name)
|
||||||
|
|
||||||
/* skip any symbols that we've already considered. */
|
/* skip any symbols that we've already considered. */
|
||||||
for (i = 0; i < sym_return_val_index; ++i)
|
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;
|
return;
|
||||||
|
|
||||||
/* Get the demangled name without parameters */
|
/* 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)
|
if (!sym_name)
|
||||||
return;
|
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
|
/* Return a null-terminated list of pointers to function symbols that
|
||||||
* match name of the supplied symbol FSYM.
|
are named FUNC_NAME and are visible within NAMESPACE. */
|
||||||
* This is used in finding all overloaded instances of a function name.
|
|
||||||
* This has been modified from make_symbol_completion_list. */
|
|
||||||
|
|
||||||
|
|
||||||
struct symbol **
|
struct symbol **
|
||||||
make_symbol_overload_list (struct symbol *fsym)
|
make_symbol_overload_list (const char *func_name,
|
||||||
|
const char *namespace)
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct cleanup *old_cleanups;
|
||||||
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);
|
|
||||||
|
|
||||||
sym_return_val_size = 100;
|
sym_return_val_size = 100;
|
||||||
sym_return_val_index = 0;
|
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;
|
sym_return_val[0] = NULL;
|
||||||
|
|
||||||
/* Read in all partial symtabs containing a partial symbol named
|
old_cleanups = make_cleanup (xfree, sym_return_val);
|
||||||
OLOAD_NAME. */
|
|
||||||
|
|
||||||
ALL_PSYMTABS (objfile, ps)
|
make_symbol_overload_list_using (func_name, namespace);
|
||||||
{
|
|
||||||
struct partial_symbol **psym;
|
|
||||||
|
|
||||||
/* If the psymtab's been read in we'll get it when we search
|
discard_cleanups (old_cleanups);
|
||||||
through the blockvector. */
|
|
||||||
if (ps->readin)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((lookup_partial_symbol (ps, oload_name, NULL, 1, VAR_DOMAIN)
|
return sym_return_val;
|
||||||
!= NULL)
|
}
|
||||||
|| (lookup_partial_symbol (ps, oload_name, NULL, 0, VAR_DOMAIN)
|
|
||||||
!= NULL))
|
/* This applies the using directives to add namespaces to search in,
|
||||||
PSYMTAB_TO_SYMTAB (ps);
|
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
|
/* Search upwards from currently selected frame (so that we can
|
||||||
complete on local vars. */
|
complete on local vars. */
|
||||||
|
|
||||||
for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
|
for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
|
||||||
{
|
{
|
||||||
if (!BLOCK_SUPERBLOCK (b))
|
dict = BLOCK_DICT (b);
|
||||||
{
|
|
||||||
surrounding_static_block = b; /* For elimination of dups */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Also catch fields of types defined in this places which match our
|
for (sym = dict_iter_name_first (dict, func_name, &iter);
|
||||||
text string. Only complete on types visible from current context. */
|
sym;
|
||||||
|
sym = dict_iter_name_next (func_name, &iter))
|
||||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
|
||||||
{
|
{
|
||||||
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
|
/* Go through the symtabs and check the externs and statics for
|
||||||
symbols which match. */
|
symbols which match. */
|
||||||
|
|
||||||
|
@ -559,10 +622,14 @@ make_symbol_overload_list (struct symbol *fsym)
|
||||||
{
|
{
|
||||||
QUIT;
|
QUIT;
|
||||||
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
|
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
|
||||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
dict = BLOCK_DICT (b);
|
||||||
{
|
|
||||||
overload_list_add_symbol (sym, oload_name);
|
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)
|
ALL_SYMTABS (objfile, s)
|
||||||
|
@ -572,15 +639,37 @@ make_symbol_overload_list (struct symbol *fsym)
|
||||||
/* Don't do this block twice. */
|
/* Don't do this block twice. */
|
||||||
if (b == surrounding_static_block)
|
if (b == surrounding_static_block)
|
||||||
continue;
|
continue;
|
||||||
ALL_BLOCK_SYMBOLS (b, iter, sym)
|
dict = BLOCK_DICT (b);
|
||||||
{
|
|
||||||
overload_list_add_symbol (sym, oload_name);
|
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. */
|
/* Lookup the rtti type for a class name. */
|
||||||
|
|
|
@ -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 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,
|
extern struct type *cp_lookup_rtti_type (const char *name,
|
||||||
struct block *block);
|
struct block *block);
|
||||||
|
|
|
@ -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>
|
2004-02-01 Fred Fish <fnf@redhat.com>
|
||||||
|
|
||||||
* gdb.base/dump.exp: Use runto_main instead of "runto main".
|
* gdb.base/dump.exp: Use runto_main instead of "runto main".
|
||||||
|
|
|
@ -53,6 +53,31 @@ int intToChar (char c)
|
||||||
void marker1()
|
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 ()
|
int main ()
|
||||||
{
|
{
|
||||||
char arg2 = 2;
|
char arg2 = 2;
|
||||||
|
@ -81,7 +106,8 @@ int main ()
|
||||||
intToChar(1);
|
intToChar(1);
|
||||||
|
|
||||||
marker1(); // marker1-returns-here
|
marker1(); // marker1-returns-here
|
||||||
return 0; // marker1-returns-here
|
XXX::marker2(); // marker1-returns-here
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
foo::foo (int i) { ifoo = i; ccpfoo = NULL; }
|
foo::foo (int i) { ifoo = i; ccpfoo = NULL; }
|
||||||
|
|
|
@ -296,6 +296,21 @@ gdb_test "list \"foo::overloadfnarg(int, int (*)(int))\"" \
|
||||||
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
|
"int foo::overloadfnarg.*\\(int arg, int \\(\\*foo\\) \\(int\\)\\).*" \
|
||||||
"list overloaded function with function ptr args - quotes around argument"
|
"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.
|
# One last mysterious test.
|
||||||
# I wonder what this is for?
|
# I wonder what this is for?
|
||||||
|
|
||||||
|
|
422
gdb/valops.c
422
gdb/valops.c
|
@ -62,6 +62,38 @@ static struct value *search_struct_method (char *, struct value **,
|
||||||
struct value **,
|
struct value **,
|
||||||
int, int *, struct type *);
|
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 int check_field_in (struct type *, const char *);
|
||||||
|
|
||||||
static struct value *value_struct_elt_for_reference (struct type *domain,
|
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,
|
int lax, struct value **objp, struct symbol *fsym,
|
||||||
struct value **valp, struct symbol **symp, int *staticp)
|
struct value **valp, struct symbol **symp, int *staticp)
|
||||||
{
|
{
|
||||||
int nparms;
|
|
||||||
struct type **parm_types;
|
|
||||||
int champ_nparms = 0;
|
|
||||||
struct value *obj = (objp ? *objp : NULL);
|
struct value *obj = (objp ? *objp : NULL);
|
||||||
|
|
||||||
short oload_champ = -1; /* Index of best overloaded function */
|
int oload_champ; /* 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? */
|
|
||||||
|
|
||||||
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 badness_vector *oload_champ_bv = NULL; /* The measure for the current best match */
|
||||||
|
|
||||||
struct value *temp = obj;
|
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 */
|
int num_fns = 0; /* Number of overloaded instances being considered */
|
||||||
struct type *basetype = NULL;
|
struct type *basetype = NULL;
|
||||||
int boffset;
|
int boffset;
|
||||||
int jj;
|
|
||||||
int ix;
|
int ix;
|
||||||
int static_offset;
|
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;
|
char *func_name = NULL;
|
||||||
|
enum oload_classification match_quality;
|
||||||
|
|
||||||
/* Get the list of overloaded methods or functions */
|
/* Get the list of overloaded methods or functions */
|
||||||
if (method)
|
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
|
been resolved by find_method_list via value_find_oload_method_list
|
||||||
above. */
|
above. */
|
||||||
gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
|
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
|
else
|
||||||
{
|
{
|
||||||
int i = -1;
|
const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
|
||||||
func_name = cplus_demangle (DEPRECATED_SYMBOL_NAME (fsym), DMGL_NO_OPTS);
|
func_name = cp_func_name (qualified_name);
|
||||||
|
|
||||||
/* If the name is NULL this must be a C-style function.
|
/* If the name is NULL this must be a C-style function.
|
||||||
Just return the same symbol. */
|
Just return the same symbol. */
|
||||||
if (!func_name)
|
if (func_name == NULL)
|
||||||
{
|
{
|
||||||
*symp = fsym;
|
*symp = fsym;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
oload_syms = make_symbol_overload_list (fsym);
|
old_cleanups = make_cleanup (xfree, func_name);
|
||||||
cleanups = make_cleanup (xfree, oload_syms);
|
make_cleanup (xfree, oload_syms);
|
||||||
while (oload_syms[++i])
|
make_cleanup (xfree, oload_champ_bv);
|
||||||
num_fns++;
|
|
||||||
if (!num_fns)
|
oload_champ = find_oload_champ_namespace (arg_types, nargs,
|
||||||
error ("Couldn't find function %s", func_name);
|
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 */
|
/* Consider each candidate in turn */
|
||||||
for (ix = 0; ix < num_fns; ix++)
|
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 (method)
|
||||||
{
|
{
|
||||||
if (TYPE_FN_FIELD_STATIC_P (fns_ptr, ix))
|
|
||||||
static_offset = 1;
|
|
||||||
nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
|
nparms = TYPE_NFIELDS (TYPE_FN_FIELD_TYPE (fns_ptr, ix));
|
||||||
}
|
}
|
||||||
else
|
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,
|
bv = rank_function (parm_types, nparms, arg_types + static_offset,
|
||||||
nargs - static_offset);
|
nargs - static_offset);
|
||||||
|
|
||||||
if (!oload_champ_bv)
|
if (!*oload_champ_bv)
|
||||||
{
|
{
|
||||||
oload_champ_bv = bv;
|
*oload_champ_bv = bv;
|
||||||
oload_champ = 0;
|
oload_champ = 0;
|
||||||
champ_nparms = nparms;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* See whether current candidate is better or worse than previous best */
|
/* 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:
|
case 0:
|
||||||
oload_ambiguous = 1; /* top two contenders are equally good */
|
oload_ambiguous = 1; /* top two contenders are equally good */
|
||||||
oload_ambig_champ = ix;
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
oload_ambiguous = 2; /* incomparable top contenders */
|
oload_ambiguous = 2; /* incomparable top contenders */
|
||||||
oload_ambig_champ = ix;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
oload_champ_bv = bv; /* new champion, record details */
|
*oload_champ_bv = bv; /* new champion, record details */
|
||||||
oload_ambiguous = 0;
|
oload_ambiguous = 0;
|
||||||
oload_champ = ix;
|
oload_champ = ix;
|
||||||
oload_ambig_champ = -1;
|
|
||||||
champ_nparms = nparms;
|
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
default:
|
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,"...Badness @ %d : %d\n", jj, bv->rank[jj]);
|
||||||
fprintf_filtered (gdb_stderr,"Overload resolution champion is %d, ambiguous? %d\n", oload_champ, oload_ambiguous);
|
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. */
|
return oload_champ;
|
||||||
static_offset = 0;
|
}
|
||||||
if (method && TYPE_FN_FIELD_STATIC_P (fns_ptr, oload_champ))
|
|
||||||
static_offset = 1;
|
/* 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++)
|
for (ix = 1; ix <= nargs - static_offset; ix++)
|
||||||
{
|
{
|
||||||
if (oload_champ_bv->rank[ix] >= 100)
|
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)
|
else if (oload_champ_bv->rank[ix] >= 10)
|
||||||
oload_non_standard = 1; /* non-standard type conversions needed */
|
return NON_STANDARD; /* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method)
|
return STANDARD; /* Only standard conversions needed. */
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* C++: return 1 is NAME is a legitimate name for the destructor
|
/* C++: return 1 is NAME is a legitimate name for the destructor
|
||||||
|
|
Loading…
Reference in New Issue