mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
Add ADL support
2010-05-07 Sami Wagiaalla <swagiaal@redhat.com> PR C++/7943: * valops.c (find_overload_match): Handle fsym == NULL case. Add int no_adl argument. (find_oload_champ_namespace_loop): Call make_symbol_overload_list_adl when appropriate. Add int no_adl argument. (find_oload_champ_namespace): Add int no_adl argument. * parse.c (operator_length_standard): Return length for OP_ADL_FUNC expression. * expprint.c (op_name_standard): Added string for OP_ADL_FUNC case. * eval.c (evaluate_subexp_standard): Added OP_ADL_FUNC case. Evaluate arguments and use them to perform ADL lookup. Pass no_adl argument to find_overload_match. Disable adl lookup when evaluating a fully qualified OP_FUNCALL. * cp-support.h: Added prototype for make_symbol_overload_list_namespace. * cp-support.c (make_symbol_overload_list_namespace): New function. (make_symbol_overload_list_adl_namespace): New function. (make_symbol_overload_list_adl): New function. (make_symbol_overload_list_using): Moved code to add function to overload set to make_symbol_overload_list_namespace. * c-exp.y: create UNKNOWN_CPP_NAME token. Add parse rule for ADL functions. (classify_name): Recognize an UNKNOWN_CPP_NAME. 2010-05-07 Sami Wagiaalla <swagiaal@redhat.com> * gdb.cp/koenig.exp: New test. * gdb.cp/koenig.cc: New test program.
This commit is contained in:
@@ -52,7 +52,7 @@ static void demangled_name_complaint (const char *name);
|
||||
|
||||
/* Functions/variables related to overload resolution. */
|
||||
|
||||
static int sym_return_val_size;
|
||||
static int sym_return_val_size = -1;
|
||||
static int sym_return_val_index;
|
||||
static struct symbol **sym_return_val;
|
||||
|
||||
@@ -709,6 +709,87 @@ make_symbol_overload_list (const char *func_name,
|
||||
return sym_return_val;
|
||||
}
|
||||
|
||||
/* Adds the function FUNC_NAME from NAMESPACE to the overload set. */
|
||||
|
||||
static void
|
||||
make_symbol_overload_list_namespace (const char *func_name,
|
||||
const char *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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Search the namespace of the given type and namespace of and public base
|
||||
types. */
|
||||
|
||||
static void
|
||||
make_symbol_overload_list_adl_namespace (struct type *type,
|
||||
const char *func_name)
|
||||
{
|
||||
char *namespace;
|
||||
char *type_name;
|
||||
int i, prefix_len;
|
||||
|
||||
while (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF
|
||||
|| TYPE_CODE (type) == TYPE_CODE_ARRAY
|
||||
|| TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||
{
|
||||
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
|
||||
type = check_typedef(type);
|
||||
else
|
||||
type = TYPE_TARGET_TYPE (type);
|
||||
}
|
||||
|
||||
type_name = TYPE_NAME (type);
|
||||
|
||||
prefix_len = cp_entire_prefix_len (type_name);
|
||||
|
||||
if (prefix_len != 0)
|
||||
{
|
||||
namespace = alloca (prefix_len + 1);
|
||||
strncpy (namespace, type_name, prefix_len);
|
||||
namespace[prefix_len] = '\0';
|
||||
|
||||
make_symbol_overload_list_namespace (func_name, namespace);
|
||||
}
|
||||
|
||||
/* Check public base type */
|
||||
if (TYPE_CODE (type) == TYPE_CODE_CLASS)
|
||||
for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
|
||||
{
|
||||
if (BASETYPE_VIA_PUBLIC (type, i))
|
||||
make_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type, i),
|
||||
func_name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds the the overload list overload candidates for FUNC_NAME found through
|
||||
argument dependent lookup. */
|
||||
|
||||
struct symbol **
|
||||
make_symbol_overload_list_adl (struct type **arg_types, int nargs,
|
||||
const char *func_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
gdb_assert (sym_return_val_size != -1);
|
||||
|
||||
for (i = 1; i <= nargs; i++)
|
||||
make_symbol_overload_list_adl_namespace (arg_types[i - 1], func_name);
|
||||
|
||||
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
|
||||
@@ -736,20 +817,7 @@ make_symbol_overload_list_using (const char *func_name,
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
make_symbol_overload_list_namespace (func_name, namespace);
|
||||
}
|
||||
|
||||
/* This does the bulk of the work of finding overloaded symbols.
|
||||
|
||||
Reference in New Issue
Block a user