aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiva Chandra Reddy <sivachandra@sourceware.org>2012-03-22 08:10:44 +0000
committerSiva Chandra Reddy <sivachandra@sourceware.org>2012-03-22 08:10:44 +0000
commit7b282c5acc13f099b11a670de50fd52a0d81ea40 (patch)
treee5bac62553f4956c81aeeb122242d209be04e978
parent0c83539f7ebce5901201956bebd1bef925e5c5f4 (diff)
downloadgdb-7b282c5acc13f099b11a670de50fd52a0d81ea40.zip
gdb-7b282c5acc13f099b11a670de50fd52a0d81ea40.tar.gz
gdb-7b282c5acc13f099b11a670de50fd52a0d81ea40.tar.bz2
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/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.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/NEWS3
-rw-r--r--gdb/doc/ChangeLog7
-rw-r--r--gdb/doc/gdb.texinfo73
-rw-r--r--gdb/python/py-value.c43
-rw-r--r--gdb/testsuite/ChangeLog8
-rw-r--r--gdb/testsuite/gdb.python/Makefile.in2
-rw-r--r--gdb/testsuite/gdb.python/py-value-cc.exp48
-rw-r--r--gdb/testsuite/gdb.python/py-value.cc39
9 files changed, 233 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3380c2b..7c653be 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
2012-03-22 Siva Chandra Reddy <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.
+
+2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
+
* MAINTAINERS (Write After Approval): Add myself to the list.
2012-03-21 Kevin Buettner <kevinb@redhat.com>
diff --git a/gdb/NEWS b/gdb/NEWS
index d23a773..696de32 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -25,6 +25,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 --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 92e3e1b..ff7786f 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,10 @@
+2012-03-22 Siva Chandra Reddy <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.
+
2012-03-19 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (File Options): Describe --init-command=FILE, -ix and
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 677af3b..dbf1a71 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -22136,6 +22136,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 --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 44443e0..58513d8 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -192,6 +192,47 @@ valpy_dereference (PyObject *self, PyObject *args)
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 if by the C++\n\
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 --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 0c05576..32d5289 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2012-03-22 Siva Chandra Reddy <sivachandra@google.com>
+
+ * gdb.python/py-value.cc: Add test case for testing the
+ methodology exposing C++ values to Python.
+ * gdb.python/py-value-cc.exp: Add tests testing the methodology
+ exposing C++ values to Python.
+ * gdb.python/Makefile.in: Add py-value-cc to EXECUTABLES.
+
2012-03-19 Jan Kratochvil <jan.kratochvil@redhat.com>
Siddhesh Poyarekar <siddhesh@redhat.com>
diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in
index 5890191..cf9c142 100644
--- a/gdb/testsuite/gdb.python/Makefile.in
+++ b/gdb/testsuite/gdb.python/Makefile.in
@@ -5,7 +5,7 @@ EXECUTABLES = py-type py-value py-prettyprint py-template py-block \
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 --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp
new file mode 100644
index 0000000..0388613
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-value-cc.exp
@@ -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"
diff --git a/gdb/testsuite/gdb.python/py-value.cc b/gdb/testsuite/gdb.python/py-value.cc
new file mode 100644
index 0000000..65a784c
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-value.cc
@@ -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);
+}