public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Siva Chandra <sivachandra@google.com>
To: gdb-patches <gdb-patches@sourceware.org>
Subject: [Patch] PR python/15464 and python/16113
Date: Fri, 27 Dec 2013 22:38:00 -0000	[thread overview]
Message-ID: <CAGyQ6gyT_vfZaFPSbBMVn5oZ+awqzEiMXGD5-ffowDdWMPv3uA@mail.gmail.com> (raw)

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

I was not aware of "unnamed fields" until I saw Tom's update to 15464
today. Playing with them and my previous patch for 16113, I realized
that my patch does not handle unnamed fields thoroughly. It does
however work for the example posted with the 15464 report.

[I probably would have looked up unnamed fields when working on my
earlier patch, but the documentation for gdb.Field.name only says
this: "The name of the field, or None for anonymous fields." I know
anonymous fields exist in Go, and they show up with a name behind the
scenes. Hence, I considered the documentation to be incorrect. I had
made a note to ask about this or fix this, but missed getting back to
it.]

Unnamed fields have a name equal to an empty string (""). Hence, if
there were only one unnamed field, my previous patch works as it looks
up a field by name. It fails when there are more than one unnamed
fields. The attached patch fixes this by looking up unnamed fields
using 'bitpos' instead of the field name.

2013-12-27  Siva Chandra Reddy  <sivachandra@google.com>

        PR python/15464
        PR python/16133
        * valops.c (value_struct_elt_bitpos): New function
        * python/py-value.c (valpy_getitem): Use 'bitpos' attribute to
        look for a field when 'name' is 'None' or empty.

        testsuite/
        * gdb.python/py-value-cc.cc: Enhance test case.
        * gdb.python/py-value-cc.exp: Add new tests.

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

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 87701b4..5c9c003 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2013-12-27  Siva Chandra Reddy  <sivachandra@google.com>
+
+	PR python/15464
+	PR python/16133
+	* valops.c (value_struct_elt_bitpos): New function
+	* python/py-value.c (valpy_getitem): Use 'bitpos' attribute to
+	look for a field when 'name' is 'None' or empty.
+
 2013-12-23  Sterling Augustine  <saugustine@google.com>
 
 	* linespec.c (add_sal_to_sals): Use "<unknown>" when a symbol
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index df25179..60a916d 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -573,6 +573,7 @@ valpy_getitem (PyObject *self, PyObject *key)
   value_object *self_value = (value_object *) self;
   char *field = NULL;
   PyObject *base_class_type_object = NULL;
+  long bitpos = -1;
   volatile struct gdb_exception except;
   PyObject *result = NULL;
 
@@ -614,10 +615,40 @@ valpy_getitem (PyObject *self, PyObject *key)
 	  if (name_obj == NULL)
 	    return NULL;
 
-	  field = python_string_to_host_string (name_obj);
-	  Py_DECREF (name_obj);
-	  if (field == NULL)
-	    return NULL;
+	  if (name_obj != Py_None)
+	    {
+	      field = python_string_to_host_string (name_obj);
+	      Py_DECREF (name_obj);
+	      name_obj = NULL;
+	      if (field == NULL)
+		return NULL;
+	    }
+
+	  if (name_obj == Py_None || field[0] == '\0')
+	    {
+	      PyObject *bitpos_obj;
+	      int valid;
+
+	      Py_XDECREF (name_obj); /* We do not need NAME_OBJ anymore.  */
+
+	      if (!PyObject_HasAttrString (key, "bitpos"))
+		{
+		  xfree (field);
+		  PyErr_SetString (PyExc_AttributeError,
+				   _("gdb.Field object has no name and no "
+                                     "'bitpos' attribute."));
+
+		  return NULL;
+		}
+	      bitpos_obj = PyObject_GetAttrString (key, "bitpos");
+	      if (bitpos_obj == NULL)
+		return NULL;
+
+	      valid = gdb_py_int_as_long (bitpos_obj, &bitpos);
+	      Py_DECREF (bitpos_obj);
+	      if (!valid)
+		return NULL;
+	    }
 	}
     }
 
@@ -627,7 +658,9 @@ valpy_getitem (PyObject *self, PyObject *key)
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
       struct value *res_val = NULL;
 
-      if (field)
+      if (bitpos >= 0)
+	res_val = value_struct_elt_bitpos (&tmp, bitpos, "struct/class/union");
+      else if (field)
 	res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
       else if (base_class_type_object != NULL)
 	{
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 97ad49b..4502a3c 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2013-12-27  Siva Chandra Reddy  <sivachandra@google.com>
+
+	PR python/15464
+	PR python/16133
+	* gdb.python/py-value-cc.cc: Enhance test case.
+	* gdb.python/py-value-cc.exp: Add new tests.
+
 2013-12-19  Sergio Durigan Junior  <sergiodj@redhat.com>
 
 	PR breakpoints/16297
diff --git a/gdb/testsuite/gdb.python/py-value-cc.cc b/gdb/testsuite/gdb.python/py-value-cc.cc
index 80094ec..8b9aa5a 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.cc
+++ b/gdb/testsuite/gdb.python/py-value-cc.cc
@@ -30,8 +30,15 @@ class B : public A {
   char a;
 };
 
+struct X
+{
+  union { int x; char y; };
+  union { int a; char b; };
+};
+
 typedef B Btd;
 typedef int *int_ptr;
+typedef X Xtd;
 
 int
 func (const A &a)
@@ -57,6 +64,13 @@ func (const A &a)
   U u;
   u.a = 99;
 
+  X x;
+  x.x = 101;
+  x.a = 102;
+
+  X *x_ptr = &x;
+  Xtd *xtd = &x;
+
   return 0; /* Break here.  */
 }
 
diff --git a/gdb/testsuite/gdb.python/py-value-cc.exp b/gdb/testsuite/gdb.python/py-value-cc.exp
index eacaf2e..08dc462 100644
--- a/gdb/testsuite/gdb.python/py-value-cc.exp
+++ b/gdb/testsuite/gdb.python/py-value-cc.exp
@@ -53,6 +53,12 @@ gdb_test_no_output "python b_ref = gdb.parse_and_eval('b_ref')" "init b_ref"
 gdb_test_no_output "python b_td = gdb.parse_and_eval('b_td')" "init b_td"
 gdb_test_no_output "python u = gdb.parse_and_eval('u')" "init u"
 gdb_test_no_output "python u_fields = u.type.fields()" "init u_fields"
+gdb_test_no_output "python x = gdb.parse_and_eval('x')" "init x"
+gdb_test_no_output "python x_fields = x.type.fields()" "init x_fields"
+gdb_test_no_output "python x_ptr = gdb.parse_and_eval('x_ptr')" "init x_ptr"
+gdb_test_no_output "python xtd = gdb.parse_and_eval('xtd')" "init xtd"
+
+gdb_test "python print(b\[b_fields\[1\]\])" "97 'a'" "b.a via field"
 
 gdb_test "python print(b\[b_fields\[1\]\])" "97 'a'" "b.a via field"
 gdb_test "python print(b\[b_fields\[0\]\].type)" "A" \
@@ -79,3 +85,11 @@ gdb_test "python print(b_td\[b_fields\[0\]\]\['a'\])" "100" \
 
 gdb_test "python print(u\[u_fields\[0\]\])" "99.*" "u's first field via field"
 gdb_test "python print(u\[u_fields\[1\]\])" "99.*" "u's second field via field"
+
+gdb_test "python print len(x_fields)" "2" "number for fields in u"
+gdb_test "python print x\[x_fields\[0\]\]\['x'\]" "101" "x.x via field"
+gdb_test "python print x\[x_fields\[1\]\]\['a'\]" "102" "x.a via field"
+gdb_test "python print x_ptr\[x_fields\[0\]\]\['x'\]" "101" "x_ptr->x via field"
+gdb_test "python print x_ptr\[x_fields\[1\]\]\['a'\]" "102" "x_ptr->a via field"
+gdb_test "python print xtd\[x_fields\[0\]\]\['x'\]" "101" "xtd->x via field"
+gdb_test "python print xtd\[x_fields\[1\]\]\['a'\]" "102" "xtd->a via field"
diff --git a/gdb/valops.c b/gdb/valops.c
index d43c758..f147854 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2248,6 +2248,49 @@ value_struct_elt (struct value **argp, struct value **args,
   return v;
 }
 
+/* Given *ARGP, a value of type structure or union, or a pointer/reference
+   to a structure or union, extract and return its component (field) at the
+   specified BITPOS.
+   Returns NULL if BITPOS is invalid.  */
+
+struct value *
+value_struct_elt_bitpos (struct value **argp, int bitpos, const char *err)
+{
+  struct type *t;
+  struct value *v;
+  int i;
+  int nbases;
+
+  *argp = coerce_array (*argp);
+
+  t = check_typedef (value_type (*argp));
+
+  while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+    {
+      *argp = value_ind (*argp);
+      if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
+	*argp = coerce_array (*argp);
+      t = check_typedef (value_type (*argp));
+    }
+
+  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+      && TYPE_CODE (t) != TYPE_CODE_UNION)
+    error (_("Attempt to extract a component of a value that is not a %s."),
+	   err);
+
+  for (i = TYPE_N_BASECLASSES (t); i < TYPE_NFIELDS (t); i++)
+    {
+      if (!field_is_static (&TYPE_FIELD (t, i))
+	  && bitpos == TYPE_FIELD_BITPOS (t, i))
+	return value_primitive_field (*argp, 0, i, t);
+    }
+
+  error (_("Attempt to extract a component with an invalid bitpos."));
+
+  /* Never hit.  */
+  return NULL;
+}
+
 /* Search through the methods of an object (and its bases) to find a
    specified method.  Return the pointer to the fn_field list of
    overloaded instances.
diff --git a/gdb/value.h b/gdb/value.h
index 6b158df..a279803 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -670,6 +670,10 @@ extern struct value *value_struct_elt (struct value **argp,
 				       const char *name, int *static_memfuncp,
 				       const char *err);
 
+extern struct value *value_struct_elt_bitpos (struct value **argp,
+					      int bitpos,
+					      const char *err);
+
 extern struct value *value_aggregate_elt (struct type *curtype,
 					  char *name,
 					  struct type *expect_type,

             reply	other threads:[~2013-12-27 22:38 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-27 22:38 Siva Chandra [this message]
2013-12-30 14:27 ` Siva Chandra
2014-01-06 20:50   ` Tom Tromey
2014-01-07 14:28     ` Siva Chandra
2014-01-13 21:12       ` Tom Tromey
2014-01-14  1:51         ` Siva Chandra
2014-01-14 14:48         ` Siva Chandra
2014-01-14 14:50           ` Tom Tromey
2014-01-15 12:46             ` Joel Brobecker
2014-01-15 13:19               ` Siva Chandra
2014-01-06 20:36 ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAGyQ6gyT_vfZaFPSbBMVn5oZ+awqzEiMXGD5-ffowDdWMPv3uA@mail.gmail.com \
    --to=sivachandra@google.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).