Add an objfile getter to gdb.Type

Message ID 20190523203227.260432-1-cbiesinger@google.com
State New, archived
Headers

Commit Message

Terekhov, Mikhail via Gdb-patches May 23, 2019, 8:32 p.m. UTC
  This allows users of the Python API to find the objfile where a type
was defined.

gdb/ChangeLog:

2019-05-22  Christian Biesinger  <cbiesinger@google.com>

	Add objfile property to gdb.Type
	* gdb/NEWS: Mention Python API addition
	* gdb/python/py-type.c (typy_get_objfile): New method

gdb/doc/ChangeLog:

2019-05-22  Christian Biesinger  <cbiesinger@google.com>

	* gdb/doc/python.texi: Document new gdb.Type.objfile property

gdb/testsuite/ChangeLog:

2019-05-22  Christian Biesinger  <cbiesinger@google.com>

	* gdb/testsuite/gdb.python/py-type.exp: Test for new
	  gdb.Type.objfile property

---
 gdb/NEWS                             |  3 +++
 gdb/doc/python.texi                  |  5 +++++
 gdb/python/py-type.c                 | 14 ++++++++++++++
 gdb/testsuite/gdb.python/py-type.exp |  4 ++++
 4 files changed, 26 insertions(+)
  

Comments

Simon Marchi May 23, 2019, 9:06 p.m. UTC | #1
Hi Christian,

Just some formatting nits (don't worry that's common when starting on a project, but you get used to it quickly).

On 2019-05-23 4:32 p.m., Christian Biesinger via gdb-patches wrote:
> This allows users of the Python API to find the objfile where a type
> was defined.
> 
> gdb/ChangeLog:
> 
> 2019-05-22  Christian Biesinger  <cbiesinger@google.com>
> 
> 	Add objfile property to gdb.Type
> 	* gdb/NEWS: Mention Python API addition
> 	* gdb/python/py-type.c (typy_get_objfile): New method
> 
> gdb/doc/ChangeLog:
> 
> 2019-05-22  Christian Biesinger  <cbiesinger@google.com>
> 
> 	* gdb/doc/python.texi: Document new gdb.Type.objfile property
> 
> gdb/testsuite/ChangeLog:
> 
> 2019-05-22  Christian Biesinger  <cbiesinger@google.com>
> 
> 	* gdb/testsuite/gdb.python/py-type.exp: Test for new
> 	  gdb.Type.objfile property

Use periods at the end of ChangeLog entries.

> 
> ---
>  gdb/NEWS                             |  3 +++
>  gdb/doc/python.texi                  |  5 +++++
>  gdb/python/py-type.c                 | 14 ++++++++++++++
>  gdb/testsuite/gdb.python/py-type.exp |  4 ++++
>  4 files changed, 26 insertions(+)
> 
> diff --git a/gdb/NEWS b/gdb/NEWS
> index 792548139e..c715bd6bca 100644
> --- a/gdb/NEWS
> +++ b/gdb/NEWS
> @@ -27,6 +27,9 @@
>       'array_indexes', 'symbols', 'unions', 'deref_refs', 'actual_objects',
>       'static_members', 'max_elements', 'repeat_threshold', and 'format'.
>  
> +  ** gdb.Type has a new property 'objfile' which returns the objfile the
> +     type was defined in.
> +
>  * New commands
>  
>  set may-call-functions [on|off]
> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
> index 98e52bb770..f769ad03a2 100644
> --- a/gdb/doc/python.texi
> +++ b/gdb/doc/python.texi
> @@ -1087,6 +1087,11 @@ languages have this concept.  If this type has no tag name, then
>  @code{None} is returned.
>  @end defvar
>  
> +@defvar Type.objfile
> +The @code{gdb.Objfile} that this type was defined in, or @code{None} if
> +there is no associated objfile.
> +@end defvar
> +
>  The following methods are provided:
>  
>  @defun Type.fields ()
> diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
> index 22cc658a8b..379038f8c6 100644
> --- a/gdb/python/py-type.c
> +++ b/gdb/python/py-type.c
> @@ -413,6 +413,18 @@ typy_get_tag (PyObject *self, void *closure)
>    return PyString_FromString (tagname);
>  }
>  
> +/* Return the type's objfile, or None.  */
> +static PyObject *
> +typy_get_objfile (PyObject *self, void *closure)
> +{
> +  struct type *type = ((type_object *) self)->type;
> +  struct objfile *objfile = TYPE_OBJFILE(type);

Ah, I forgot to explicitly mention to add a space after TYPE_OBJFILE.

> +
> +  if (objfile == nullptr)
> +    Py_RETURN_NONE;
> +  return objfile_to_objfile_object (objfile).release ();
> +}
> +
>  /* Return the type, stripped of typedefs. */
>  static PyObject *
>  typy_strip_typedefs (PyObject *self, PyObject *args)
> @@ -1419,6 +1431,8 @@ static gdb_PyGetSetDef type_object_getset[] =
>      "The size of this type, in bytes.", NULL },
>    { "tag", typy_get_tag, NULL,
>      "The tag name for this type, or None.", NULL },
> +  { "objfile", typy_get_objfile, NULL,
> +    "The objfile this type was defined in, or None.", NULL },
>    { NULL }
>  };
>  
> diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
> index 734f9b40fd..c299fa3410 100644
> --- a/gdb/testsuite/gdb.python/py-type.exp
> +++ b/gdb/testsuite/gdb.python/py-type.exp
> @@ -98,6 +98,8 @@ proc test_fields {lang} {
>      gdb_py_test_silent_cmd "print (st)" "print value (st)" 1
>      gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1
>      gdb_py_test_silent_cmd "python fields = st.type.fields()" "get fields from st.type" 1
> +    gdb_test "python print (st.type.objfile.filename == gdb.current_progspace().filename)" "True" \

Space after current_progspace as well.

> +      "Check type.objfile"

We use lower case letters for test names.

>      gdb_test "python print (len(fields))" "2" "check number of fields (st)"
>      gdb_test "python print (fields\[0\].name)" "a" "check structure field a name"
>      gdb_test "python print (fields\[1\].name)" "b" "check structure field b name"
> @@ -269,6 +271,8 @@ if { [build_inferior "${binfile}" "c"] == 0 } {
>    # Skip all tests if Python scripting is not enabled.
>    if { [skip_python_tests] } { continue }
>  
> +  gdb_test "python print(gdb.lookup_type('char').objfile)" "None"

Spaces before parentheses (even though there's a bad example just below).

Let's give a few days for others to comment if they want to.  With these fixed the patch LGTM.

Simon
  
Terekhov, Mikhail via Gdb-patches May 23, 2019, 9:25 p.m. UTC | #2
On Thu, May 23, 2019 at 4:06 PM Simon Marchi <simark@simark.ca> wrote:
> Just some formatting nits (don't worry that's common when starting on a project, but you get used to it quickly).

No problem! Will send a new version of the patch in a second.

> On 2019-05-23 4:32 p.m., Christian Biesinger via gdb-patches wrote:
> > diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
> > index 734f9b40fd..c299fa3410 100644
> > --- a/gdb/testsuite/gdb.python/py-type.exp
> > +++ b/gdb/testsuite/gdb.python/py-type.exp
> > @@ -98,6 +98,8 @@ proc test_fields {lang} {
> >      gdb_py_test_silent_cmd "print (st)" "print value (st)" 1
> >      gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1
> >      gdb_py_test_silent_cmd "python fields = st.type.fields()" "get fields from st.type" 1
> > +    gdb_test "python print (st.type.objfile.filename == gdb.current_progspace().filename)" "True" \
>
> Space after current_progspace as well.
>
> > +      "Check type.objfile"
>
> We use lower case letters for test names.

This file is super inconsistent about both of those :/
  

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index 792548139e..c715bd6bca 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -27,6 +27,9 @@ 
      'array_indexes', 'symbols', 'unions', 'deref_refs', 'actual_objects',
      'static_members', 'max_elements', 'repeat_threshold', and 'format'.
 
+  ** gdb.Type has a new property 'objfile' which returns the objfile the
+     type was defined in.
+
 * New commands
 
 set may-call-functions [on|off]
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 98e52bb770..f769ad03a2 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -1087,6 +1087,11 @@  languages have this concept.  If this type has no tag name, then
 @code{None} is returned.
 @end defvar
 
+@defvar Type.objfile
+The @code{gdb.Objfile} that this type was defined in, or @code{None} if
+there is no associated objfile.
+@end defvar
+
 The following methods are provided:
 
 @defun Type.fields ()
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 22cc658a8b..379038f8c6 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -413,6 +413,18 @@  typy_get_tag (PyObject *self, void *closure)
   return PyString_FromString (tagname);
 }
 
+/* Return the type's objfile, or None.  */
+static PyObject *
+typy_get_objfile (PyObject *self, void *closure)
+{
+  struct type *type = ((type_object *) self)->type;
+  struct objfile *objfile = TYPE_OBJFILE(type);
+
+  if (objfile == nullptr)
+    Py_RETURN_NONE;
+  return objfile_to_objfile_object (objfile).release ();
+}
+
 /* Return the type, stripped of typedefs. */
 static PyObject *
 typy_strip_typedefs (PyObject *self, PyObject *args)
@@ -1419,6 +1431,8 @@  static gdb_PyGetSetDef type_object_getset[] =
     "The size of this type, in bytes.", NULL },
   { "tag", typy_get_tag, NULL,
     "The tag name for this type, or None.", NULL },
+  { "objfile", typy_get_objfile, NULL,
+    "The objfile this type was defined in, or None.", NULL },
   { NULL }
 };
 
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index 734f9b40fd..c299fa3410 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -98,6 +98,8 @@  proc test_fields {lang} {
     gdb_py_test_silent_cmd "print (st)" "print value (st)" 1
     gdb_py_test_silent_cmd "python st = gdb.history (0)" "get value (st) from history" 1
     gdb_py_test_silent_cmd "python fields = st.type.fields()" "get fields from st.type" 1
+    gdb_test "python print (st.type.objfile.filename == gdb.current_progspace().filename)" "True" \
+      "Check type.objfile"
     gdb_test "python print (len(fields))" "2" "check number of fields (st)"
     gdb_test "python print (fields\[0\].name)" "a" "check structure field a name"
     gdb_test "python print (fields\[1\].name)" "b" "check structure field b name"
@@ -269,6 +271,8 @@  if { [build_inferior "${binfile}" "c"] == 0 } {
   # Skip all tests if Python scripting is not enabled.
   if { [skip_python_tests] } { continue }
 
+  gdb_test "python print(gdb.lookup_type('char').objfile)" "None"
+
   gdb_test "python print(gdb.lookup_type('char').array(1, 0))" \
       "char \\\[0\\\]"