From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6513 invoked by alias); 16 Aug 2010 20:31:37 -0000 Received: (qmail 6503 invoked by uid 22791); 16 Aug 2010 20:31:36 -0000 X-SWARE-Spam-Status: No, hits=-5.3 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_CP,TW_RG,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 16 Aug 2010 20:31:29 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o7GKVSxn017286 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 16 Aug 2010 16:31:28 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o7GKVRT1018866 for ; Mon, 16 Aug 2010 16:31:27 -0400 Received: from [10.15.16.129] (dhcp-10-15-16-129.yyz.redhat.com [10.15.16.129]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o7GKVRgn015717 for ; Mon, 16 Aug 2010 16:31:27 -0400 Message-ID: <4C69A00A.4000306@redhat.com> Date: Mon, 16 Aug 2010 20:31:00 -0000 From: sami wagiaalla User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100720 Fedora/3.1.1-1.fc13 Thunderbird/3.1.1 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: Re: [patch] smart pointer support References: <201008061648.o76Gmk3o008780@d12av02.megacenter.de.ibm.com> <4C5C7FAB.2090005@redhat.com> <4C6025EF.5080509@redhat.com> <4C60431F.4040705@redhat.com> <20100809182342.GA27392@host1.dyn.jankratochvil.net> In-Reply-To: <20100809182342.GA27392@host1.dyn.jankratochvil.net> Content-Type: multipart/mixed; boundary="------------010202030303080106040303" X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-08/txt/msg00246.txt.bz2 This is a multi-part message in MIME format. --------------010202030303080106040303 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1219 On 08/09/2010 02:23 PM, Jan Kratochvil wrote: > On Mon, 09 Aug 2010 20:04:15 +0200, sami wagiaalla wrote: >> + >> + /* 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) >> + break; > > What if some other error kind occurs? It would get hidden. Such as: > error (_("This target does not support function calls.")); > > In the case you want to go with the TRY_CATCH case you should IMO specialize > the error message you want to catch to some: > throw_error (THE_GREAT_NEW_KIND_OF_ERROR, that message); > > To correctly check just that specific error kind in EXCEPT (and throw it again > otherwise). > I have created a new error type SYMBOL_NOT_FOUND_ERROR and updated the needed throw locations and the catch statements. Patch attached. --------------010202030303080106040303 Content-Type: text/x-patch; name="smart_pointer.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="smart_pointer.patch" Content-length: 10490 Support overloading of 'operator->'. 2010-08-16 Sami Wagiaalla PR C++/11500: * valarith.c (value_x_unop): Handle STRUCTOP_PTR. * eval.c (evaluate_subexp_standard): Check for overload of 'operator->'. * exceptions.h: New error SYMBOL_NOT_FOUND_ERROR. * valarith.c (value_x_binop): Throw SYMBOL_NOT_FOUND_ERROR. (value_x_unop): Ditto. * valops.c: Include "exceptions.h". (find_overload_match): Throw SYMBOL_NOT_FOUND_ERROR. (value_struct_elt): Ditto. 2010-08-16 Sami Wagiaalla * gdb.cp/smartp.exp: New test. * gdb.cp/smartp.cc : New test. diff --git a/gdb/eval.c b/gdb/eval.c index ba75952..8b99dac 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1431,6 +1431,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 == SYMBOL_NOT_FOUND_ERROR) + break; + else + throw_exception (except); + } + arg2 = value; + } } /* Now, say which argument to start evaluating from */ tem = 2; @@ -1819,6 +1841,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 == SYMBOL_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/exceptions.h b/gdb/exceptions.h index 7d68a36..55263ed 100644 --- a/gdb/exceptions.h +++ b/gdb/exceptions.h @@ -78,6 +78,9 @@ enum errors { /* Feature is not supported in this copy of GDB. */ UNSUPPORTED_ERROR, + /* The requested symbol was not found. */ + SYMBOL_NOT_FOUND_ERROR, + /* Add more errors here. */ NR_ERRORS }; diff --git a/gdb/testsuite/gdb.cp/smartp.cc b/gdb/testsuite/gdb.cp/smartp.cc new file mode 100644 index 0000000..baa8f46 --- /dev/null +++ b/gdb/testsuite/gdb.cp/smartp.cc @@ -0,0 +1,163 @@ +/* This test script is part of GDB, the GNU debugger. + + Copyright 1999, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +class Type1{ + public: + int foo(){ + return 11; + } +}; + +class Type2{ + public: + int foo(){ + return 22; + } +}; + +class Type3{ + public: + int foo(int){ + return 33; + } + int foo(char){ + return 44; + } +}; + +class Type4 { + public: + int a; + int b; +}; + +int foo (Type3, float) +{ + return 55; +} + +class MyPointer{ + Type1 *p; + public: + MyPointer(Type1 *pointer){ + p = pointer; + } + + Type1 *operator->(){ + return p; + } +}; + +template class SmartPointer{ + T *p; + public: + SmartPointer(T *pointer){ + p = pointer; + } + + T *operator->(){ + return p; + } +}; + + +class A { + public: + int inta; + int foo() { return 66; } +}; + +class B { + public: + A a; + A* operator->(){ + return &a; + } +}; + +class C { + public: + B b; + B& operator->(){ + return b; + } +}; + +class C2 { + public: + B b; + B operator->(){ + return b; + } +}; + +int main(){ + Type1 mt1; + Type2 mt2; + Type3 mt3; + + Type4 mt4; + mt4.a = 11; + mt4.b = 12; + + MyPointer mp(&mt1); + Type1 *mtp = &mt1; + + SmartPointer sp1(&mt1); + SmartPointer sp2(&mt2); + SmartPointer sp3(&mt3); + SmartPointer sp4(&mt4); + + mp->foo(); + mtp->foo(); + + sp1->foo(); + sp2->foo(); + + sp3->foo(1); + sp3->foo('a'); + + sp4->a; + sp4->b; + + Type4 *mt4p = &mt4; + mt4p->a; + mt4p->b; + + A a; + B b; + C c; + C2 c2; + + a.inta = 77; + b.a = a; + c.b = b; + c2.b = b; + + a.foo(); + b->foo(); + c->foo(); + + b->inta = 77; + c->inta = 77; + c2->inta = 77; + + return 0; // end of main +} + diff --git a/gdb/testsuite/gdb.cp/smartp.exp b/gdb/testsuite/gdb.cp/smartp.exp new file mode 100644 index 0000000..2cea473 --- /dev/null +++ b/gdb/testsuite/gdb.cp/smartp.exp @@ -0,0 +1,77 @@ +# Copyright 2008 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +set testfile smartp +set srcfile ${testfile}.cc +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } { + return -1 +} + +############################################ + +if ![runto_main] then { + perror "couldn't run to breakpoint main" + continue +} + +gdb_breakpoint [gdb_get_line_number "end of main"] +gdb_continue_to_breakpoint "end of main" + +# Test that overloaded arrow operator works +gdb_test "p mp->foo()" "= 11" + +# Test that regular arrow operator still works +gdb_test "p mtp->foo()" "= 11" + +# Test that normal '.' operator still works. +gdb_test "p mt1.foo()" "= 11" + +# test that gdb extension '.' for pointers still works. +gdb_test "p mt4p.a" "= 11" + +# test that gdb extension '->' for structs still works. +gdb_test "p mt4->a" "= 11" + +# Test that templated smart pointers work +gdb_test "p sp1->foo()" "= 11" +gdb_test "p sp2->foo()" "= 22" + +# Test that overload resolution works properly +# with smart pointers +gdb_test "p sp3->foo(1)" "= 33" +gdb_test "p sp3->foo('a')" "= 44" + +# Test smart pointers work for member references +gdb_test "p sp4->a" "= 11" +gdb_test "p sp4->b" "= 12" + +# Test regular arrow operator still works for +# member references +gdb_test "p mt4p->a" "= 11" +gdb_test "p mt4p->b" "= 12" + +# Test that incorrect use of the arrow operator +# is still handled correctly. +gdb_test "p mt4->fake" "There is no member named fake." +gdb_test "p mt4->fake()" "Couldn't find method Type4::fake" + +# Test that overloading of -> works recursively +gdb_test "p b->foo()" "= 66" +gdb_test "p c->foo()" "= 66" +gdb_test "p c->inta" "= 77" + +setup_kfail "gdb/11606" "*-*-*" +gdb_test "p c2->inta" "= 77" + diff --git a/gdb/valarith.c b/gdb/valarith.c index 0c40905..f9ca51f 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 (SYMBOL_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 (SYMBOL_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 f1eb041..2ac99cb 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. */ @@ -2196,7 +2197,8 @@ value_struct_elt (struct value **argp, struct value **args, } if (!v) - error (_("Structure has no component named %s."), name); + throw_error (SYMBOL_NOT_FOUND_ERROR, + _("Structure has no component named %s."), name); return v; } @@ -2517,7 +2519,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 (SYMBOL_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 --------------010202030303080106040303--