diff options
Diffstat (limited to 'gdb/valarith.c')
-rw-r--r-- | gdb/valarith.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/gdb/valarith.c b/gdb/valarith.c index 745d960..0c40905 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -31,6 +31,7 @@ #include "dfp.h" #include <math.h> #include "infcall.h" +#include "exceptions.h" /* Define whether or not the C operator '/' truncates towards zero for differently signed operands (truncation direction is undefined in C). */ @@ -319,6 +320,67 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1) } } +/* Try to find an operator named OPERATOR which takes NARGS arguments + specified in ARGS. If the operator found is a static member operator + *STATIC_MEMFUNP will be set to 1, and otherwise 0. + The search if performed through find_overload_match which will handle + member operators, non member operators, operators imported implicitly or + explicitly, and perform correct overload resolution in all of the above + situations or combinations thereof. */ + +static struct value * +value_user_defined_cpp_op (struct value **args, int nargs, char *operator, + int *static_memfuncp) +{ + + struct symbol *symp = NULL; + struct value *valp = NULL; + struct type **arg_types; + int i; + + arg_types = (struct type **) alloca (nargs * (sizeof (struct type *))); + /* Prepare list of argument types for overload resolution */ + for (i = 0; i < nargs; i++) + arg_types[i] = value_type (args[i]); + + find_overload_match (arg_types, nargs, operator, BOTH /* could be method */, + 0 /* strict match */, &args[0], /* objp */ + NULL /* pass NULL symbol since symbol is unknown */, + &valp, &symp, static_memfuncp, 0); + + if (valp) + return valp; + + if (symp) + { + /* This is a non member function and does not + expect a reference as its first argument + rather the explicit structure. */ + args[0] = value_ind (args[0]); + return value_of_variable (symp, 0); + } + + error (_("Could not find %s."), operator); +} + +/* Lookup user defined operator NAME. Return a value representing the + function, otherwise return NULL. */ + +static struct value * +value_user_defined_op (struct value **argp, struct value **args, char *name, + int *static_memfuncp, int nargs) +{ + struct value *result = NULL; + + if (current_language->la_language == language_cplus) + result = value_user_defined_cpp_op (args, nargs, name, static_memfuncp); + else + result = value_struct_elt (argp, args, name, static_memfuncp, + "structure"); + + return result; +} + /* We know either arg1 or arg2 is a structure, so try to find the right user defined function. Create an argument vector that calls arg1.operator @ (arg1,arg2) and return that value (where '@' is any @@ -459,7 +521,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, error (_("Invalid binary operation specified.")); } - argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure"); + argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr, + &static_memfuncp, 2); if (argvec[0]) { @@ -557,7 +620,8 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) error (_("Invalid unary operation specified.")); } - argvec[0] = value_struct_elt (&arg1, argvec + 1, tstr, &static_memfuncp, "structure"); + argvec[0] = value_user_defined_op (&arg1, argvec + 1, tstr, + &static_memfuncp, nargs); if (argvec[0]) { |