diff options
author | Sami Wagiaalla <swagiaal@redhat.com> | 2010-06-07 16:11:35 +0000 |
---|---|---|
committer | Sami Wagiaalla <swagiaal@redhat.com> | 2010-06-07 16:11:35 +0000 |
commit | 4c3376c84943b8102da4237141dab7f1595912ca (patch) | |
tree | fc4936a3a61d60b2a60379e534e7081099969bb2 /gdb/valarith.c | |
parent | 0f32ea4ce3309801590068305e7c8d7aeb495f2f (diff) | |
download | gdb-4c3376c84943b8102da4237141dab7f1595912ca.zip gdb-4c3376c84943b8102da4237141dab7f1595912ca.tar.gz gdb-4c3376c84943b8102da4237141dab7f1595912ca.tar.bz2 |
Test and support all cpp operator types.
2010-06-07 Sami Wagiaalla <swagiaal@redhat.com>
* value.h: Created oload_search_type enum.
(find_overload_match): Use oload_search_type enum.
* valops.c (find_overload_match): Support combined member and
non-member search.
* eval.c (evaluate_subexp_standard): Calls to
find_overload_match now use oload_search_type enum.
(oload_method_static): Verify index is a proper value.
* valarith.c (value_user_defined_cpp_op): Search for and handle
both member and non-member operators.
(value_user_defined_cpp_op): New function.
(value_user_defined_op): New function.
(value_x_unop): Use value_user_defined_op.
(value_x_binop): Ditto.
* cp-support.c (make_symbol_overload_list_using): Added block
iteration.
Add check for namespace aliases and imported declarations.
2010-06-07 Sami Wagiaalla <swagiaal@redhat.com>
* gdb.cp/koenig.exp: Test for ADL operators.
* gdb.cp/koenig.cc: Added ADL operators.
* gdb.cp/operator.exp: New test.
* gdb.cp/operator.cc: New test.
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]) { |