diff -rupN src/gdb/doc/gdb.texinfo src_ref/gdb/doc/gdb.texinfo --- src/gdb/doc/gdb.texinfo 2012-03-08 00:55:37.000000000 +0530 +++ src_ref/gdb/doc/gdb.texinfo 2012-03-14 23:28:48.087128459 +0530 @@ -22137,6 +22137,79 @@ bar = foo.dereference () The result @code{bar} will be a @code{gdb.Value} object holding the value pointed to by @code{foo}. + +A similar function @code{Value.referenced_value} exists which also +returns @code{gdb.Value} objects corresonding to the values pointed to +by pointer values (and additionally, values referenced by reference +values). However, the behavior of @code{Value.dereference} +differs from @code{Value.referenced_value} by the fact that the +behavior of @code{Value.dereference} is identical to applying the C +unary operator @code{*} on a given value. For example, consider a +reference to a pointer @code{ptrref}, declared in your C@t{++} program +as + +@smallexample +typedef int *intptr; +... +int val = 10; +intptr ptr = &val; +intptr &ptrref = ptr; +@end smallexample + +Though @code{ptrref} is a reference value, one can apply the method +@code{Value.dereference} to the @code{gdb.Value} object corresponding +to it and obtain a @code{gdb.Value} which is identical to that +corresponding to @code{val}. However, if you apply the method +@code{Value.referenced_value}, the result would be a @code{gdb.Value} +object identical to that corresponding to @code{ptr}. + +@smallexample +py_ptrref = gdb.parse_and_eval ("ptrref") +py_val = py_ptrref.dereference () +py_ptr = py_ptrref.referenced_value () +@end smallexample + +The @code{gdb.Value} object @code{py_val} is identical to that +corresponding to @code{val}, and @code{py_ptr} is identical to that +corresponding to @code{ptr}. In general, @code{Value.dereference} can +be applied whenever the C unary operator @code{*} can be applied +to the corresponding C value. For those cases where applying both +@code{Value.dereference} and @code{Value.referenced_value} is allowed, +the results obtained need not be identical (as we have seen in the above +example). The results are however identical when applied on +@code{gdb.Value} objects corresponding to pointers (@code{gdb.Value} +objects with type code @code{TYPE_CODE_PTR}) in a C/C@t{++} program. +@end defun + +@defun Value.referenced_value () +For pointer or reference data types, this method returns a new +@code{gdb.Value} object corresponding to the value referenced by the +pointer/reference value. For pointer data types, +@code{Value.dereference} and @code{Value.referenced_value} produce +identical results. The difference between these methods is that +@code{Value.dereference} cannot get the values referenced by reference +values. For example, consider a reference to an @code{int}, declared +in your C@t{++} program as + +@smallexample +int val = 10; +int &ref = val; +@end smallexample + +@noindent +then applying @code{Value.dereference} to the @code{gdb.Value} object +corresponding to @code{ref} will result in an error, while applying +@code{Value.referenced_value} will result in a @code{gdb.Value} object +identical to that corresponding to @code{val}. + +@smallexample +py_ref = gdb.parse_and_eval ("ref") +er_ref = py_ref.dereference () # Results in error +py_val = py_ref.referenced_value () # Returns the referenced value +@end smallexample + +The @code{gdb.Value} object @code{py_val} is identical to that +corresponding to @code{val}. @end defun @defun Value.dynamic_cast (type) diff -rupN src/gdb/NEWS src_ref/gdb/NEWS --- src/gdb/NEWS 2012-03-08 00:55:36.000000000 +0530 +++ src_ref/gdb/NEWS 2012-03-13 16:57:53.278158455 +0530 @@ -23,6 +23,9 @@ frame in order to compute its value, and the latter computes the symbol's value. + ** A new method 'referenced_value' on gdb.Value objects which can + dereference pointer as well as C++ reference values. + * GDBserver now supports stdio connections. E.g. (gdb) target remote | ssh myhost gdbserver - hello diff -rupN src/gdb/python/py-value.c src_ref/gdb/python/py-value.c --- src/gdb/python/py-value.c 2012-03-02 02:36:54.000000000 +0530 +++ src_ref/gdb/python/py-value.c 2012-03-14 22:42:17.299833293 +0530 @@ -192,6 +192,47 @@ valpy_dereference (PyObject *self, PyObj return result; } +/* Given a value of a pointer type or a reference type, return the value + referenced. The difference between this function and valpy_dereference is + that the latter applies * unary operator to a value, which need not always + result in the value referenced. For example, for a value which is a reference + to an 'int' pointer ('int *'), valpy_dereference will result in a value of + type 'int' while valpy_referenced_value will result in a value of type + 'int *'. */ + +static PyObject * +valpy_referenced_value (PyObject *self, PyObject *args) +{ + volatile struct gdb_exception except; + PyObject *result = NULL; + + TRY_CATCH (except, RETURN_MASK_ALL) + { + struct value *self_val, *res_val; + struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); + + self_val = ((value_object *) self)->value; + switch (TYPE_CODE (check_typedef (value_type (self_val)))) + { + case TYPE_CODE_PTR: + res_val = value_ind (self_val); + break; + case TYPE_CODE_REF: + res_val = coerce_ref (self_val); + break; + default: + error(_("Trying to get the referenced value from a value which is " + "neither a pointer nor a reference.")); + } + + result = value_to_value_object (res_val); + do_cleanups (cleanup); + } + GDB_PY_HANDLE_EXCEPTION (except); + + return result; +} + /* Return "&value". */ static PyObject * valpy_get_address (PyObject *self, void *closure) @@ -1379,6 +1420,8 @@ Cast the value to the supplied type, as reinterpret_cast operator." }, { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." }, + { "referenced_value", valpy_referenced_value, METH_NOARGS, + "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." }, { "lazy_string", (PyCFunction) valpy_lazy_string, METH_VARARGS | METH_KEYWORDS, "lazy_string ([encoding] [, length]) -> lazy_string\n\ diff -rupN src/gdb/testsuite/gdb.python/Makefile.in src_ref/gdb/testsuite/gdb.python/Makefile.in --- src/gdb/testsuite/gdb.python/Makefile.in 2011-12-23 22:36:16.000000000 +0530 +++ src_ref/gdb/testsuite/gdb.python/Makefile.in 2012-03-11 00:40:36.902953529 +0530 @@ -5,7 +5,7 @@ EXECUTABLES = py-type py-value py-pretty py-symbol py-mi py-breakpoint py-inferior py-infthread \ py-shared python lib-types py-events py-evthreads py-frame \ py-mi py-pp-maint py-progspace py-section-script py-objfile \ - py-finish-breakpoint py-finish-breakpoint2 + py-finish-breakpoint py-finish-breakpoint2 py-value-cc MISCELLANEOUS = py-shared-sl.sl py-events-shlib.so py-events-shlib-nodebug.so diff -rupN src/gdb/testsuite/gdb.python/py-value.cc src_ref/gdb/testsuite/gdb.python/py-value.cc --- src/gdb/testsuite/gdb.python/py-value.cc 1970-01-01 05:30:00.000000000 +0530 +++ src_ref/gdb/testsuite/gdb.python/py-value.cc 2012-03-13 12:24:28.858190392 +0530 @@ -0,0 +1,39 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 A { +}; + +typedef int *int_ptr; + +int +func (const A &a) +{ + int val = 10; + int &int_ref = val; + int_ptr ptr = &val; + int_ptr &int_ptr_ref = ptr; + + return 0; /* Break here. */ +} + +int +main () +{ + A obj; + return func (obj); +} diff -rupN src/gdb/testsuite/gdb.python/py-value-cc.exp src_ref/gdb/testsuite/gdb.python/py-value-cc.exp --- src/gdb/testsuite/gdb.python/py-value-cc.exp 1970-01-01 05:30:00.000000000 +0530 +++ src_ref/gdb/testsuite/gdb.python/py-value-cc.exp 2012-03-14 22:31:00.769628405 +0530 @@ -0,0 +1,48 @@ +# Copyright (C) 2012 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 . + +# This file is part of the GDB testsuite. It tests the mechanism +# exposing values to Python. + +if { [skip_cplus_tests] } { continue } + +set testfile "py-value" +set srcfile ${testfile}.cc +set binfile ${objdir}/${subdir}/${testfile} + +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} { + return -1 +} + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +if ![runto_main] { + return -1 +} + +gdb_breakpoint [gdb_get_line_number "Break here."] +gdb_continue_to_breakpoint "Break here" ".*Break here.*" + +gdb_test "python print str(gdb.parse_and_eval(\"a\").type)" "const A &" +gdb_test "python print str(gdb.parse_and_eval(\"a\").referenced_value().type)" "const A" +gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").type)" "int &" +gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").referenced_value().type)" "int" +gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").referenced_value())" "10" + +gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").dereference().type)" "int" +gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().type)" "int_ptr" +gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().dereference())" "10" +gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().referenced_value())" "10"