From 79afc5ef5d41c629c2e26eee37aaceac4320b8d6 Mon Sep 17 00:00:00 2001 From: Sami Wagiaalla Date: Tue, 19 Oct 2010 20:53:15 +0000 Subject: [PATCH] Support overloading of 'operator->'. 2010-10-19 Sami Wagiaalla PR C++/11500: * valarith.c (value_x_unop): Handle STRUCTOP_PTR. * eval.c (evaluate_subexp_standard): Check for overload of 'operator->'. * valarith.c (value_x_binop): Throw NOT_FOUND_ERROR. (value_x_unop): Ditto. * valops.c: Include "exceptions.h". (find_overload_match): Throw NOT_FOUND_ERROR. (value_struct_elt): Ditto. 2010-10-19 Sami Wagiaalla * gdb.cp/smartp.exp: New test. * gdb.cp/smartp.cc : New test. --- gdb/ChangeLog | 12 ++++++++++++ gdb/eval.c | 43 +++++++++++++++++++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 5 +++++ gdb/valarith.c | 10 ++++++++-- gdb/valops.c | 8 ++++++-- 5 files changed, 74 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d2b0c897581..13336bad5e8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2010-10-19 Sami Wagiaalla + + PR C++/11500: + * valarith.c (value_x_unop): Handle STRUCTOP_PTR. + * eval.c (evaluate_subexp_standard): Check for overload of + 'operator->'. + * valarith.c (value_x_binop): Throw NOT_FOUND_ERROR. + (value_x_unop): Ditto. + * valops.c: Include "exceptions.h". + (find_overload_match): Throw NOT_FOUND_ERROR. + (value_struct_elt): Ditto. + 2010-10-19 Tom Tromey * python/py-cmd.c (cmdpy_function): Unreference exception state. diff --git a/gdb/eval.c b/gdb/eval.c index 635db34e22a..471dcd7a563 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1510,6 +1510,28 @@ evaluate_subexp_standard (struct type *expect_type, else { arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + + /* Check to see if the operator '->' has been overloaded. If the operator + has been overloaded replace arg2 with the value returned by the custom + operator and continue evaluation. */ + while (unop_user_defined_p (op, arg2)) + { + volatile struct gdb_exception except; + struct value *value = NULL; + TRY_CATCH (except, RETURN_MASK_ERROR) + { + value = value_x_unop (arg2, op, noside); + } + + if (except.reason < 0) + { + if (except.error == NOT_FOUND_ERROR) + break; + else + throw_exception (except); + } + arg2 = value; + } } /* Now, say which argument to start evaluating from */ tem = 2; @@ -1898,6 +1920,27 @@ evaluate_subexp_standard (struct type *expect_type, if (noside == EVAL_SKIP) goto nosideret; + /* Check to see if operator '->' has been overloaded. If so replace + arg1 with the value returned by evaluating operator->(). */ + while (unop_user_defined_p (op, arg1)) + { + volatile struct gdb_exception except; + struct value *value = NULL; + TRY_CATCH (except, RETURN_MASK_ERROR) + { + value = value_x_unop (arg1, op, noside); + } + + if (except.reason < 0) + { + if (except.error == NOT_FOUND_ERROR) + break; + else + throw_exception (except); + } + arg1 = value; + } + /* JYG: if print object is on we need to replace the base type with rtti type in order to continue on with successful lookup of member / method only available in the rtti type. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 824796e0659..2bdc9d01e06 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-10-19 Sami Wagiaalla + + * gdb.cp/smartp.exp: New test. + * gdb.cp/smartp.cc : New test. + 2010-10-19 Sami Wagiaalla * gdb.cp/converts.exp: Test pointer to bool conversion. diff --git a/gdb/valarith.c b/gdb/valarith.c index 554c4ff3a29..88f1448b0dd 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -541,7 +541,8 @@ value_x_binop (struct value *arg1, struct value *arg2, enum exp_opcode op, } return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); } - error (_("member function %s not found"), tstr); + throw_error (NOT_FOUND_ERROR, + _("member function %s not found"), tstr); #ifdef lint return call_function_by_hand (argvec[0], 2 - static_memfuncp, argvec + 1); #endif @@ -616,6 +617,9 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) case UNOP_IND: strcpy (ptr, "*"); break; + case STRUCTOP_PTR: + strcpy (ptr, "->"); + break; default: error (_("Invalid unary operation specified.")); } @@ -641,7 +645,9 @@ value_x_unop (struct value *arg1, enum exp_opcode op, enum noside noside) } return call_function_by_hand (argvec[0], nargs, argvec + 1); } - error (_("member function %s not found"), tstr); + throw_error (NOT_FOUND_ERROR, + _("member function %s not found"), tstr); + return 0; /* For lint -- never reached */ } diff --git a/gdb/valops.c b/gdb/valops.c index fe4576ec8ae..07b62a165c7 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -46,6 +46,7 @@ #include "observer.h" #include "objfiles.h" #include "symtab.h" +#include "exceptions.h" extern int overload_debug; /* Local functions. */ @@ -2215,7 +2216,8 @@ value_struct_elt (struct value **argp, struct value **args, } if (!v) - error (_("Structure has no component named %s."), name); + throw_error (NOT_FOUND_ERROR, + _("Structure has no component named %s."), name); return v; } @@ -2533,7 +2535,9 @@ find_overload_match (struct type **arg_types, int nargs, /* Did we find a match ? */ if (method_oload_champ == -1 && func_oload_champ == -1) - error (_("No symbol \"%s\" in current context."), name); + throw_error (NOT_FOUND_ERROR, + _("No symbol \"%s\" in current context."), + name); /* If we have found both a method match and a function match, find out which one is better, and calculate match -- 2.30.2