Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
@ 2012-03-13 11:54 Siva Chandra
  2012-03-13 19:11 ` Eli Zaretskii
  2012-03-14 15:48 ` Tom Tromey
  0 siblings, 2 replies; 9+ messages in thread
From: Siva Chandra @ 2012-03-13 11:54 UTC (permalink / raw)
  To: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2056 bytes --]

Hi all,

Per Tom's suggestion in another thread (see for reference
http://sourceware.org/ml/gdb-patches/2012-03/msg00417.html), I have
added a new method to gdb.Value. I am starting a new mail thread as
the subject line, and the patch, have changed quite a bit from last
time.

I could not think of a better name than 'referenced_value' for this
method. Hence, I have implemented it to deference pointer as well as
reference values as the name of the method suggests. I have tried to
document the similarities (and differences) between this new method
and the method Value.dereference wherever reasonable. I have used
Tom's example of a reference to a pointer to describe the differences.

About using prepare_for_testing, I notice that compilation fails with
this as gcc is being used to compile the test case and not g++. So, I
have not changed the exp file in this patch.

Code Changelog:

2012-03-13 Siva Chandra <sivachandra@google.com>

        Python scripting: Add new method Value.referenced_value to
        gdb.Value which can dereference pointer as well as reference
        values.
        * NEWS: Add entry under 'Python scripting' about the new method
        Value.referenced_value on gdb.Value objects.
        * python/py-value.c (valpy_referenced_value): New function
        defining a new method on gdb.Value objects which can dereference
        pointer and reference values.
        * testsuite/gdb.python/py-value.cc: Add test case for
        testing the methodology exposing C++ values to Python.
        * testsuite/gdb.python/py-value-cc.exp: Add tests testing the
        methodology exposing C++ values to Python.
        * testsuite/gdb.python/Makefile.in: Add py-value-cc to
        EXECUTABLES.

Docs Changelog:

2012-03-13 Siva Chandra <sivachandra@google.com>

        * gdb.texinfo (Python API/Values From Inferior): Add description
        about the new method Value.referenced_value.  Add description on
        how Value.dereference is different (and similar) to
        Value.referenced_value.

Thanks,
Siva Chandra

[-- Attachment #2: value_referenced_value_patch_v1.txt --]
[-- Type: text/plain, Size: 10816 bytes --]

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-13 16:47:11.078158317 +0530
@@ -22137,6 +22137,77 @@ 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 behaviour of @code{Value.dereference}
+differs with @code{Value.referenced_value} by the fact that the
+behaviour of @code{Value.dereference} is identical to applying the C
+unary @code{*} operator on a given value.  For example, consider a
+reference to a pointer @code{ptrref}, declared in your C++ 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} on 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 @code{*} operator can be legally applied
+to the corresponding C value.  For those cases where applying both
+@code{Value.dereference} and @code{Value.referenced_value} is legal, 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++ 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++ program as
+
+@smallexample
+int val = 10;
+int &ref = val;
+@end smallexample
+
+then applying @code{Value.dereference} on 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-13 16:46:07.708160558 +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 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 <http://www.gnu.org/licenses/>.  */
+
+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-13 11:00:50.468158714 +0530
@@ -0,0 +1,57 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# 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 { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
+	  {debug c++}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_load ${binfile}
+
+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"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-13 11:54 [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs) Siva Chandra
@ 2012-03-13 19:11 ` Eli Zaretskii
  2012-03-14 10:28   ` Siva Chandra
  2012-03-14 15:48 ` Tom Tromey
  1 sibling, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2012-03-13 19:11 UTC (permalink / raw)
  To: Siva Chandra; +Cc: gdb-patches

> Date: Tue, 13 Mar 2012 17:23:54 +0530
> From: Siva Chandra <sivachandra@google.com>
> 
> Per Tom's suggestion in another thread (see for reference
> http://sourceware.org/ml/gdb-patches/2012-03/msg00417.html), I have
> added a new method to gdb.Value. I am starting a new mail thread as
> the subject line, and the patch, have changed quite a bit from last
> time.

Thanks.

> +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 behaviour of @code{Value.dereference}
                          ^^^^^^^^^
Please use the US spelling ("behavior"), here and elsewhere in your
patch.

> +differs with @code{Value.referenced_value} by the fact that the
   ^^^^^^^^^^^^
"differs from"

> +behaviour of @code{Value.dereference} is identical to applying the C
> +unary @code{*} operator on a given value.  For example, consider a
   ^^^^^^^^^^^^^^^^^^^^^^^
"unary operator `*'" sounds better.  (There are more occurrences of
this in the patch.)

> +reference to a pointer @code{ptrref}, declared in your C++ program as

We use C@t{++} instead of C++, the former looks better in print.

> +@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} on the @code{gdb.Value} object corresponding
                            ^^
"apply ... to"

> +corresponding to @code{ptr}.  In general, @code{Value.dereference} can
> +be applied whenever the C unary @code{*} operator can be legally applied
> +to the corresponding C value.

GNU coding standards frown on using "legally" for anything that
doesn't refer to laws.  Please just drop that word, it doesn't add any
important information in this context.

>                                       For those cases where applying both
> +@code{Value.dereference} and @code{Value.referenced_value} is legal, the
                                                                 ^^^^^
Here, I would use "allowed" or "possible" instead of "legal".

> +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++ program.
                                                       ^^^
C@t{++}

> +values.  For example, consider a reference to an @code{int}, declared
> +in your C++ program as

And here.

> +@smallexample
> +int val = 10;
> +int &ref = val;
> +@end smallexample
> +
> +then applying @code{Value.dereference} on the @code{gdb.Value} object
                                          ^^
You want @noindent before this line.  And "to", not "on".

OK with those changes, as far as the documentation is concerned.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-13 19:11 ` Eli Zaretskii
@ 2012-03-14 10:28   ` Siva Chandra
  2012-03-14 17:52     ` Eli Zaretskii
  0 siblings, 1 reply; 9+ messages in thread
From: Siva Chandra @ 2012-03-14 10:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Eli Zaretskii

[-- Attachment #1: Type: text/plain, Size: 1337 bytes --]

I have modified according to Eli's suggestions. Thanks Eli, for the review.

Attached is the patch with the modifications. Below are the Changelog entries.

Code Changelog:

2012-03-14 Siva Chandra <sivachandra@google.com>

        Python scripting: Add new method Value.referenced_value to
        gdb.Value which can dereference pointer as well as reference
        values.
        * NEWS: Add entry under 'Python scripting' about the new method
        Value.referenced_value on gdb.Value objects.
        * python/py-value.c (valpy_referenced_value): New function
        defining a new method on gdb.Value objects which can dereference
        pointer and reference values.
        * testsuite/gdb.python/py-value.cc: Add test case for
        testing the methodology exposing C++ values to Python.
        * testsuite/gdb.python/py-value-cc.exp: Add tests testing the
        methodology exposing C++ values to Python.
        * testsuite/gdb.python/Makefile.in: Add py-value-cc to
        EXECUTABLES.

Docs Changelog:

2012-03-14 Siva Chandra <sivachandra@google.com>

        * gdb.texinfo (Python API/Values From Inferior): Add description
        about the new method Value.referenced_value.  Add description on
        how Value.dereference is different (and similar) to
        Value.referenced_value.

Thanks,
Siva Chandra

[-- Attachment #2: value_referenced_value_patch_v2.txt --]
[-- Type: text/plain, Size: 10822 bytes --]

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 15:40:55.890983628 +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 `*' 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 `*' 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-13 16:46:07.708160558 +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 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 <http://www.gnu.org/licenses/>.  */
+
+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-13 11:00:50.468158714 +0530
@@ -0,0 +1,57 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# 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 { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable \
+	  {debug c++}] != "" } {
+    untested "Couldn't compile ${srcfile}"
+    return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# Skip all tests if Python scripting is not enabled.
+if { [skip_python_tests] } { continue }
+
+gdb_load ${binfile}
+
+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"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-13 11:54 [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs) Siva Chandra
  2012-03-13 19:11 ` Eli Zaretskii
@ 2012-03-14 15:48 ` Tom Tromey
  2012-03-14 17:26   ` Siva Chandra
  1 sibling, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2012-03-14 15:48 UTC (permalink / raw)
  To: Siva Chandra; +Cc: gdb-patches

>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:

Siva> I could not think of a better name than 'referenced_value' for this
Siva> method.

Seems reasonable to me.

Siva> About using prepare_for_testing, I notice that compilation fails with
Siva> this as gcc is being used to compile the test case and not g++. So, I
Siva> have not changed the exp file in this patch.

You can do it by passing the "c++" option, e.g. from dispcxx.exp:

if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {

The code bits are ok with this fixed.

Tom


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-14 15:48 ` Tom Tromey
@ 2012-03-14 17:26   ` Siva Chandra
  0 siblings, 0 replies; 9+ messages in thread
From: Siva Chandra @ 2012-03-14 17:26 UTC (permalink / raw)
  To: gdb-patches; +Cc: Tom Tromey

[-- Attachment #1: Type: text/plain, Size: 2062 bytes --]

Thank you Tom for the review. I have modified the test according to
the example you have pointed. The new patch is attached. The
changelogs are below.

Code Changelog:

2012-03-14 Siva Chandra <sivachandra@google.com>

        Python scripting: Add new method Value.referenced_value to
        gdb.Value which can dereference pointer as well as reference
        values.
        * NEWS: Add entry under 'Python scripting' about the new method
        Value.referenced_value on gdb.Value objects.
        * python/py-value.c (valpy_referenced_value): New function
        defining a new method on gdb.Value objects which can dereference
        pointer and reference values.
        * testsuite/gdb.python/py-value.cc: Add test case for
        testing the methodology exposing C++ values to Python.
        * testsuite/gdb.python/py-value-cc.exp: Add tests testing the
        methodology exposing C++ values to Python.
        * testsuite/gdb.python/Makefile.in: Add py-value-cc to
        EXECUTABLES.

Docs Changelog:

2012-03-14 Siva Chandra <sivachandra@google.com>

        * gdb.texinfo (Python API/Values From Inferior): Add description
        about the new method Value.referenced_value.  Add description on
        how Value.dereference is different (and similar) to
        Value.referenced_value.

OK to commit? If yes, I think someone should commit it for me.

Thanks,
Siva Chandra

On Wed, Mar 14, 2012 at 9:18 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:
>
> Siva> I could not think of a better name than 'referenced_value' for this
> Siva> method.
>
> Seems reasonable to me.
>
> Siva> About using prepare_for_testing, I notice that compilation fails with
> Siva> this as gcc is being used to compile the test case and not g++. So, I
> Siva> have not changed the exp file in this patch.
>
> You can do it by passing the "c++" option, e.g. from dispcxx.exp:
>
> if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
>
> The code bits are ok with this fixed.
>
> Tom

[-- Attachment #2: value_referenced_value_patch_v3.txt --]
[-- Type: text/plain, Size: 10654 bytes --]

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 15:40:55.890983628 +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 `*' 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 `*' 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 <http://www.gnu.org/licenses/>.  */
+
+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 <http://www.gnu.org/licenses/>.
+
+# 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"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-14 10:28   ` Siva Chandra
@ 2012-03-14 17:52     ` Eli Zaretskii
  2012-03-14 18:07       ` Siva Chandra
  0 siblings, 1 reply; 9+ messages in thread
From: Eli Zaretskii @ 2012-03-14 17:52 UTC (permalink / raw)
  To: Siva Chandra; +Cc: gdb-patches

> Date: Wed, 14 Mar 2012 15:58:37 +0530
> From: Siva Chandra <sivachandra@google.com>
> Cc: Eli Zaretskii <eliz@gnu.org>
> 
> +unary operator `*' on a given value.  For example, consider a

Please use "@code{*}" instead of "`*'" (here and elsewhere).
Otherwise, this version of documentation is fine with me.

Thanks.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-14 17:52     ` Eli Zaretskii
@ 2012-03-14 18:07       ` Siva Chandra
  2012-03-15 20:51         ` Tom Tromey
  0 siblings, 1 reply; 9+ messages in thread
From: Siva Chandra @ 2012-03-14 18:07 UTC (permalink / raw)
  To: gdb-patches; +Cc: Eli Zaretskii

[-- Attachment #1: Type: text/plain, Size: 1367 bytes --]

Eli> Please use "@code{*}" instead of "`*'" (here and elsewhere).
Eli> Otherwise, this version of documentation is fine with me.

OK, done. Patch is attached. Changelogs are below.

Code Changelog:

2012-03-14 Siva Chandra <sivachandra@google.com>

        Python scripting: Add new method Value.referenced_value to
        gdb.Value which can dereference pointer as well as reference
        values.
        * NEWS: Add entry under 'Python scripting' about the new method
        Value.referenced_value on gdb.Value objects.
        * python/py-value.c (valpy_referenced_value): New function
        defining a new method on gdb.Value objects which can dereference
        pointer and reference values.
        * testsuite/gdb.python/py-value.cc: Add test case for
        testing the methodology exposing C++ values to Python.
        * testsuite/gdb.python/py-value-cc.exp: Add tests testing the
        methodology exposing C++ values to Python.
        * testsuite/gdb.python/Makefile.in: Add py-value-cc to
        EXECUTABLES.

Docs Changelog:

2012-03-14 Siva Chandra <sivachandra@google.com>

        * gdb.texinfo (Python API/Values From Inferior): Add description
        about the new method Value.referenced_value.  Add description on
        how Value.dereference is different (and similar) to
        Value.referenced_value.

OK?

Thanks,
Siva Chandra

[-- Attachment #2: value_referenced_value_patch_v4.txt --]
[-- Type: text/plain, Size: 10664 bytes --]

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 <http://www.gnu.org/licenses/>.  */
+
+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 <http://www.gnu.org/licenses/>.
+
+# 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"

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-14 18:07       ` Siva Chandra
@ 2012-03-15 20:51         ` Tom Tromey
  2012-03-22  9:12           ` Siva Chandra
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2012-03-15 20:51 UTC (permalink / raw)
  To: Siva Chandra; +Cc: gdb-patches, Eli Zaretskii

>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:

Siva> OK?

Yes, thanks.

Contact me off-list and I can hook you up with write-after-approval
access.

Tom


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs)
  2012-03-15 20:51         ` Tom Tromey
@ 2012-03-22  9:12           ` Siva Chandra
  0 siblings, 0 replies; 9+ messages in thread
From: Siva Chandra @ 2012-03-22  9:12 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Eli Zaretskii

On Fri, Mar 16, 2012 at 2:21 AM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Siva" == Siva Chandra <sivachandra@google.com> writes:
>
>Siva> OK?

Tom> Yes, thanks.

Commited.

Thanks,
Siva Chandra


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-03-22  9:12 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-13 11:54 [RFC - Python Scripting] New method Value.referenced_value to dereference pointer as well as reference values (with docs) Siva Chandra
2012-03-13 19:11 ` Eli Zaretskii
2012-03-14 10:28   ` Siva Chandra
2012-03-14 17:52     ` Eli Zaretskii
2012-03-14 18:07       ` Siva Chandra
2012-03-15 20:51         ` Tom Tromey
2012-03-22  9:12           ` Siva Chandra
2012-03-14 15:48 ` Tom Tromey
2012-03-14 17:26   ` Siva Chandra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox