This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v3] gdb/python: add missing handling for anonymous members of struct and union


gdb.Type.fields() missed handling for anonymous members.

This patch fix it, below are details:

Assume that we have a c source as below:

/////////////////////////////
struct A
{
	int a;
	union {
		int b0;
		int b1;
		union {
			int bb0;
			int bb1;
			union {
				int bbb0;
				int bbb1;
			};
		};
	};
	int c;
	union {
		union {
			int dd0;
			int dd1;
		};
		int d2;
		int d3;
	};
};

int main()
{
   struct A a;
}
////////////////////////////

And have a python gdb script as below:

##########################
v = gdb.parse_and_eval("a")
t = v.type
fields = t.fields()
for f in fields:
    print "[%s]" % f.name, v[f.name]
##########################

Without this patch, above script will print:

[a] -7616
[] {{dd0 = 0, dd1 = 0}, d2 = 0, d3 = 0}
[c] 0
[] {{dd0 = 0, dd1 = 0}, d2 = 0, d3 = 0}

With this patch, above script will print rightly:

[a] -7616
[b0] 32767
[b1] 32767
[bb0] 32767
[bb1] 32767
[bbb0] 32767
[bbb1] 32767
[c] 0
[dd0] 0
[dd1] 0
[d2] 0
[d3] 0

And please note that this patch assumed that Paul's patch in
http://sourceware.org/ml/gdb-patches/2011-09/msg00546.html is
applied first.

Thanks for Paul and Tom's feedback for first version of this patch.

The third version use recursion, as we discussed :)

And, I will add a new test case for this.

Signed-off-by: Li Yu <raise.sail@gmail.com>

gdb/python/:
2011-10-8  Li Yu  <raise.sail@gmail.com>

	* py-type.c: Add process for anonymous members of struct and union

 py-type.c |   43 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 8 deletions(-)

diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index c7fd25b..823f8d1 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -56,8 +56,11 @@ typedef struct pyty_field_object
 static PyTypeObject field_object_type;

 /* A type iterator object.  */
-typedef struct {
+typedef struct iterator_object
+{
   PyObject_HEAD
+  /* The iterators for support fields of anonymous field */
+  struct iterator_object *child;
   /* The current field index.  */
   int field;
   /* What to return.  */
@@ -1200,6 +1203,7 @@ typy_make_iter (PyObject *self, enum gdbpy_iter_kind kind)
   if (typy_iter_obj == NULL)
       return NULL;

+  typy_iter_obj->child = NULL;
   typy_iter_obj->field = 0;
   typy_iter_obj->kind = kind;
   Py_INCREF (self);
@@ -1257,19 +1261,42 @@ static PyObject *
 typy_iterator_iternext (PyObject *self)
 {
   typy_iterator_object *iter_obj = (typy_iterator_object *) self;
-  struct type *type = iter_obj->source->type;
-  int i;
-  PyObject *result;
-
-  if (iter_obj->field < TYPE_NFIELDS (type))
+  typy_iterator_object *child_iter_obj;
+  struct type *type;
+  PyObject *result, *child_pytype;
+  char *name;
+
+  if (iter_obj->child)
+    {
+      result = typy_iterator_iternext((PyObject*)iter_obj->child);
+      if (result)
+         return result;
+      Py_CLEAR(iter_obj->child);
+    }
+
+  type = iter_obj->source->type;
+
+restart:
+  if (iter_obj->field >= TYPE_NFIELDS (type))
+    return NULL;
+
+  name = TYPE_FIELD_NAME (type, iter_obj->field);
+  if (name[0])
     {
       result = make_fielditem (type, iter_obj->field, iter_obj->kind);
       if (result != NULL)
-	iter_obj->field++;
+        iter_obj->field++;
       return result;
     }

-  return NULL;
+  type = TYPE_FIELD_TYPE(type, iter_obj->field++);
+  child_pytype = type_to_type_object(type);
+  if (!child_pytype)
+    return NULL;
+  child_iter_obj = (typy_iterator_object*)typy_make_iter
(child_pytype, iter_obj->kind);
+  iter_obj->child = child_iter_obj;
+  iter_obj = child_iter_obj;
+  goto restart;
 }

 static void


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]