diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9de4746..7c4bf4e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,15 @@ 2008-11-16 Tom Tromey + * python/python-type.c (type_object_type): Add extra fields. + (gdbpy_initialize_types): Don't set tp_new. Ready new type. + (pyty_field_object): New type. + (field_object_type): New global. + (field_dealloc): New function. + (field_new): Likewise. + (convert_field): Create field objects. + +2008-11-16 Tom Tromey + * python/python-type.c (typy_code): New function. (struct pyty_code): New type. (ENTRY): New define. diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 0b85f5c..e205dea 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -2,6 +2,10 @@ * gdb.texinfo (Types From Inferior): Update. +2008-11-16 Tom Tromey + + * gdb.texinfo (Types From Inferior): Update. + 2008-11-13 Tom Tromey * gdb.texinfo (Basic Python): Document gdb.get_objfiles and diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 6a38009..eb24ece 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -17937,28 +17937,25 @@ Return the type code for this type. The type code will be one of the @end defmethod @defmethod Type fields -Return a sequence of all fields of this type. If this type has no -fields, the sequence will be empty. - For structure and union types, this method returns the fields. Range types have two fields, the minimum and maximum values. Enum types have one field per enum constant. Function and method types have one field per parameter. The base types of C++ classes are also -represented as fields. +represented as fields. If the type has no fields, or does not fit +into one of these categories, an empty sequence will be returned. -Each field is a dictionary, with some pre-defined elements: +Each field is an object, with some pre-defined attributes: @table @code @item bitpos -This element is not available for @code{static} fields. For +This attribute is not available for @code{static} fields. For non-@code{static} fields, the value is the bit position of the field. @item name -The name of the field. This element is not available for anonymous -fields. +The name of the field, or @code{None} for anonymous fields. @item artificial This is @code{True} if the field is artificial, usually meaning that -it was provided by the compiler and not the user. This value is +it was provided by the compiler and not the user. This attribute is always provided, and is @code{False} if the field is not artificial. @item bitsize diff --git a/gdb/python/python-type.c b/gdb/python/python-type.c index f24a023..31af1ed 100644 --- a/gdb/python/python-type.c +++ b/gdb/python/python-type.c @@ -50,6 +50,17 @@ typedef struct pyty_type_object static PyTypeObject type_object_type; +/* A Field object. */ +typedef struct pyty_field_object +{ + PyObject_HEAD + + /* Dictionary holding our attributes. */ + PyObject *dict; +} field_object; + +static PyTypeObject field_object_type; + /* This is used to initialize various gdb.TYPE_ constants. */ struct pyty_code { @@ -96,6 +107,31 @@ static struct pyty_code pyty_codes[] = +static void +field_dealloc (PyObject *obj) +{ + field_object *f = (field_object *) obj; + Py_XDECREF (f->dict); +} + +static PyObject * +field_new (void) +{ + field_object *result = PyObject_New (field_object, &field_object_type); + if (result) + { + result->dict = PyDict_New (); + if (!result->dict) + { + Py_DECREF (result); + result = NULL; + } + } + return (PyObject *) result; +} + + + /* Return the code for this type. */ static PyObject * typy_code (PyObject *self, PyObject *args) @@ -109,10 +145,10 @@ typy_code (PyObject *self, PyObject *args) static PyObject * convert_field (PyObject *self, struct type *type, int field) { - PyObject *dict = PyDict_New (); + PyObject *result = field_new (); PyObject *arg; - if (!dict) + if (!result) return NULL; if (!TYPE_FIELD_STATIC (type, field)) @@ -121,42 +157,45 @@ convert_field (PyObject *self, struct type *type, int field) if (!arg) goto fail; - if (PyDict_SetItemString (dict, "bitpos", arg) < 0) + if (PyObject_SetAttrString (result, "bitpos", arg) < 0) goto failarg; } if (TYPE_FIELD_NAME (type, field)) + arg = PyString_FromString (TYPE_FIELD_NAME (type, field)); + else { - arg = PyString_FromString (TYPE_FIELD_NAME (type, field)); - if (!arg) - goto fail; - if (PyDict_SetItemString (dict, "name", arg) < 0) - goto failarg; + arg = Py_None; + Py_INCREF (arg); } + if (!arg) + goto fail; + if (PyObject_SetAttrString (result, "name", arg) < 0) + goto failarg; arg = TYPE_FIELD_ARTIFICIAL (type, field) ? Py_True : Py_False; Py_INCREF (arg); - if (PyDict_SetItemString (dict, "artificial", arg) < 0) + if (PyObject_SetAttrString (result, "artificial", arg) < 0) goto failarg; arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field)); if (!arg) goto fail; - if (PyDict_SetItemString (dict, "bitsize", arg) < 0) + if (PyObject_SetAttrString (result, "bitsize", arg) < 0) goto failarg; arg = type_to_type_object (self, TYPE_FIELD_TYPE (type, field)); if (!arg) goto fail; - if (PyDict_SetItemString (dict, "type", arg) < 0) + if (PyObject_SetAttrString (result, "type", arg) < 0) goto failarg; - return dict; + return result; failarg: Py_DECREF (arg); fail: - Py_DECREF (dict); + Py_DECREF (result); return NULL; } @@ -169,6 +208,9 @@ typy_fields (PyObject *self, PyObject *args) int i; struct type *type = ((type_object *) self)->type; + /* We would like to make a tuple here, make fields immutable, and + then memoize the result (and perhaps make Field.type() lazy). + However, that can lead to cycles. */ result = PyList_New (0); for (i = 0; i < TYPE_NFIELDS (type); ++i) @@ -624,9 +666,10 @@ gdbpy_initialize_types (void) typy_objfile_data_key = register_objfile_data_with_cleanup (clean_up_objfile_types); - type_object_type.tp_new = typy_new; if (PyType_Ready (&type_object_type) < 0) return; + if (PyType_Ready (&field_object_type) < 0) + return; for (i = 0; pyty_codes[i].name; ++i) { @@ -691,5 +734,58 @@ static PyTypeObject type_object_type = 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - type_object_methods /* tp_methods */ + type_object_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + typy_new, /* tp_new */ +}; + +static PyTypeObject field_object_type = +{ + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ + "gdb.Field", /*tp_name*/ + sizeof (field_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + field_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/ + "GDB field object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof (field_object, dict), /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ };