diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.cc b/gdb/testsuite/gdb.cp/namespace-koenig.cc index 6c2c01d..3c30cb2 100644 --- a/gdb/testsuite/gdb.cp/namespace-koenig.cc +++ b/gdb/testsuite/gdb.cp/namespace-koenig.cc @@ -129,6 +129,42 @@ namespace L { } //------------ + +namespace M { + class O{ + public: + int operator== (int){ + return 18; + } + + int operator== (float){ + return 19; + } + + int operator+ (float){ + return 22; + } + + }; + + int operator!= (O, int){ + return 20; + } + + int operator!= (O, double){ + return 21; + } + + int operator+ (O, int){ + return 23; + } + + int operator++ (O){ + return 24; + } + +} +//------------ int main () { @@ -180,7 +216,15 @@ main () L::A::B::O labo; foo (labo); - + + M::O o; + o == 5; + o == 5.0f; + o != 5; + o != 5.0f; + o + 5; + o + 5.0f; + return first (0, c) + foo (eo) + foo (eo, eo) + foo (eo, eo, 1) + foo (fo, eo) + foo (1 ,fo, eo) + diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.exp b/gdb/testsuite/gdb.cp/namespace-koenig.exp index 616b816..c73e239 100644 --- a/gdb/testsuite/gdb.cp/namespace-koenig.exp +++ b/gdb/testsuite/gdb.cp/namespace-koenig.exp @@ -93,3 +93,20 @@ gdb_test "p bar(ko,1)" "= -1" #test lookup of objects belonging to nested namespaces gdb_test "p foo(labo)" "= 17" + +# test lookup of namespace user-defined operators +# and overload resolution: + +# within class +gdb_test "p o == 5" "= 18" +gdb_test "p o == 5.0f" "= 19" + +# within namespace +gdb_test "p o != 5" "= 20" +gdb_test "p o != 5.0f" "= 21" + +# across namespace and class +gdb_test "p o + 5.0f" "= 22" +gdb_test "p o + 5" "= 23" + +gdb_test "p o++" "= 24" diff --git a/gdb/valarith.c b/gdb/valarith.c index ed76b09..c672a5b 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -31,6 +31,7 @@ #include "dfp.h" #include #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). */ @@ -298,6 +299,62 @@ unop_user_defined_p (enum exp_opcode op, struct value *arg1) } } +struct value * +value_user_defined_adl_op (struct value **args, int nargs, char *operator) +{ + + struct symbol *symp; + struct type **arg_types; + int i; + + /* This function, if found, will not be a member function + and does not expect a pointer as its first argument + rather the explicit structure. */ + args[0] = value_ind (args[0]); + + 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, 0 /* not method */, + 0 /* strict match */, NULL, + NULL /* pass NULL symbol since symbol is unknown */, + NULL, &symp, NULL); + + if (symp) + return value_of_variable (symp, 0); + + return NULL; +} + +struct value * +value_user_defined_op (struct value **argp, struct value **args, char *name, + int *static_memfuncp, int nargs) +{ + struct value *result = NULL; + volatile struct gdb_exception except; + + TRY_CATCH (except, RETURN_MASK_ERROR) + { + result = value_struct_elt (argp, args, name, static_memfuncp, + "structure"); + } + + if (except.reason < 0) + { + + if (current_language->la_language == language_cplus) + /* Try ADL. */ + result = value_user_defined_adl_op (args, nargs, name); + + if (!result) + error ("%s", except.message); + } + + 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 @@ -438,7 +495,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]) { @@ -535,7 +593,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, 1); if (argvec[0]) {