gdb/python/py-type.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "value.h"
- #include "python-internal.h"
- #include "charset.h"
- #include "gdbtypes.h"
- #include "cp-support.h"
- #include "demangle.h"
- #include "objfiles.h"
- #include "language.h"
- #include "vec.h"
- #include "typeprint.h"
- typedef struct pyty_type_object
- {
- PyObject_HEAD
- struct type *type;
-
- struct pyty_type_object *prev;
- struct pyty_type_object *next;
- } type_object;
- static PyTypeObject type_object_type
- CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("type_object");
- typedef struct pyty_field_object
- {
- PyObject_HEAD
-
- PyObject *dict;
- } field_object;
- static PyTypeObject field_object_type
- CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("field_object");
- typedef struct {
- PyObject_HEAD
-
- int field;
-
- enum gdbpy_iter_kind kind;
-
- struct pyty_type_object *source;
- } typy_iterator_object;
- static PyTypeObject type_iterator_object_type
- CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("typy_iterator_object");
- struct pyty_code
- {
-
- enum type_code code;
-
- const char *name;
- };
- static PyObject *typy_make_iter (PyObject *self, enum gdbpy_iter_kind kind);
- #define ENTRY(X) { X, #X }
- static struct pyty_code pyty_codes[] =
- {
- ENTRY (TYPE_CODE_BITSTRING),
- ENTRY (TYPE_CODE_PTR),
- ENTRY (TYPE_CODE_ARRAY),
- ENTRY (TYPE_CODE_STRUCT),
- ENTRY (TYPE_CODE_UNION),
- ENTRY (TYPE_CODE_ENUM),
- ENTRY (TYPE_CODE_FLAGS),
- ENTRY (TYPE_CODE_FUNC),
- ENTRY (TYPE_CODE_INT),
- ENTRY (TYPE_CODE_FLT),
- ENTRY (TYPE_CODE_VOID),
- ENTRY (TYPE_CODE_SET),
- ENTRY (TYPE_CODE_RANGE),
- ENTRY (TYPE_CODE_STRING),
- ENTRY (TYPE_CODE_ERROR),
- ENTRY (TYPE_CODE_METHOD),
- ENTRY (TYPE_CODE_METHODPTR),
- ENTRY (TYPE_CODE_MEMBERPTR),
- ENTRY (TYPE_CODE_REF),
- ENTRY (TYPE_CODE_CHAR),
- ENTRY (TYPE_CODE_BOOL),
- ENTRY (TYPE_CODE_COMPLEX),
- ENTRY (TYPE_CODE_TYPEDEF),
- ENTRY (TYPE_CODE_NAMESPACE),
- ENTRY (TYPE_CODE_DECFLOAT),
- ENTRY (TYPE_CODE_INTERNAL_FUNCTION),
- { TYPE_CODE_UNDEF, NULL }
- };
- static void
- field_dealloc (PyObject *obj)
- {
- field_object *f = (field_object *) obj;
- Py_XDECREF (f->dict);
- Py_TYPE (obj)->tp_free (obj);
- }
- 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;
- }
- int
- gdbpy_is_field (PyObject *obj)
- {
- return PyObject_TypeCheck (obj, &field_object_type);
- }
- static PyObject *
- typy_get_code (PyObject *self, void *closure)
- {
- struct type *type = ((type_object *) self)->type;
- return PyInt_FromLong (TYPE_CODE (type));
- }
- static PyObject *
- convert_field (struct type *type, int field)
- {
- PyObject *result = field_new ();
- PyObject *arg;
- if (!result)
- return NULL;
- arg = type_to_type_object (type);
- if (arg == NULL)
- goto fail;
- if (PyObject_SetAttrString (result, "parent_type", arg) < 0)
- goto failarg;
- Py_DECREF (arg);
- if (!field_is_static (&TYPE_FIELD (type, field)))
- {
- const char *attrstring;
- if (TYPE_CODE (type) == TYPE_CODE_ENUM)
- {
- arg = gdb_py_long_from_longest (TYPE_FIELD_ENUMVAL (type, field));
- attrstring = "enumval";
- }
- else
- {
- arg = gdb_py_long_from_longest (TYPE_FIELD_BITPOS (type, field));
- attrstring = "bitpos";
- }
- if (!arg)
- goto fail;
-
- if (PyObject_SetAttrString (result, (char *) attrstring, arg) < 0)
- goto failarg;
- Py_DECREF (arg);
- }
- arg = NULL;
- if (TYPE_FIELD_NAME (type, field))
- {
- const char *field_name = TYPE_FIELD_NAME (type, field);
- if (field_name[0] != '\0')
- {
- arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
- if (arg == NULL)
- goto fail;
- }
- }
- if (arg == NULL)
- {
- arg = Py_None;
- Py_INCREF (arg);
- }
- if (PyObject_SetAttrString (result, "name", arg) < 0)
- goto failarg;
- Py_DECREF (arg);
- arg = TYPE_FIELD_ARTIFICIAL (type, field) ? Py_True : Py_False;
- Py_INCREF (arg);
- if (PyObject_SetAttrString (result, "artificial", arg) < 0)
- goto failarg;
- Py_DECREF (arg);
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
- arg = field < TYPE_N_BASECLASSES (type) ? Py_True : Py_False;
- else
- arg = Py_False;
- Py_INCREF (arg);
- if (PyObject_SetAttrString (result, "is_base_class", arg) < 0)
- goto failarg;
- Py_DECREF (arg);
- arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field));
- if (!arg)
- goto fail;
- if (PyObject_SetAttrString (result, "bitsize", arg) < 0)
- goto failarg;
- Py_DECREF (arg);
-
- if (TYPE_FIELD_TYPE (type, field) == NULL)
- {
- arg = Py_None;
- Py_INCREF (arg);
- }
- else
- arg = type_to_type_object (TYPE_FIELD_TYPE (type, field));
- if (!arg)
- goto fail;
- if (PyObject_SetAttrString (result, "type", arg) < 0)
- goto failarg;
- Py_DECREF (arg);
- return result;
- failarg:
- Py_DECREF (arg);
- fail:
- Py_DECREF (result);
- return NULL;
- }
- static PyObject *
- field_name (struct type *type, int field)
- {
- PyObject *result;
- if (TYPE_FIELD_NAME (type, field))
- result = PyString_FromString (TYPE_FIELD_NAME (type, field));
- else
- {
- result = Py_None;
- Py_INCREF (result);
- }
- return result;
- }
- static PyObject *
- make_fielditem (struct type *type, int i, enum gdbpy_iter_kind kind)
- {
- PyObject *item = NULL, *key = NULL, *value = NULL;
- switch (kind)
- {
- case iter_items:
- key = field_name (type, i);
- if (key == NULL)
- goto fail;
- value = convert_field (type, i);
- if (value == NULL)
- goto fail;
- item = PyTuple_New (2);
- if (item == NULL)
- goto fail;
- PyTuple_SET_ITEM (item, 0, key);
- PyTuple_SET_ITEM (item, 1, value);
- break;
- case iter_keys:
- item = field_name (type, i);
- break;
- case iter_values:
- item = convert_field (type, i);
- break;
- default:
- gdb_assert_not_reached ("invalid gdbpy_iter_kind");
- }
- return item;
- fail:
- Py_XDECREF (key);
- Py_XDECREF (value);
- Py_XDECREF (item);
- return NULL;
- }
- static PyObject *
- typy_fields_items (PyObject *self, enum gdbpy_iter_kind kind)
- {
- PyObject *py_type = self;
- PyObject *result = NULL, *iter = NULL;
- volatile struct gdb_exception except;
- struct type *type = ((type_object *) py_type)->type;
- struct type *checked_type = type;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- CHECK_TYPEDEF (checked_type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- if (checked_type != type)
- py_type = type_to_type_object (checked_type);
- iter = typy_make_iter (py_type, kind);
- if (checked_type != type)
- {
-
- Py_DECREF (py_type);
- }
- if (iter != NULL)
- {
- result = PySequence_List (iter);
- Py_DECREF (iter);
- }
- return result;
- }
- static PyObject *
- typy_values (PyObject *self, PyObject *args)
- {
- return typy_fields_items (self, iter_values);
- }
- static PyObject *
- typy_fields (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- PyObject *r, *rl;
- if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
- return typy_fields_items (self, iter_values);
-
- r = convert_field (type, 0);
- if (r == NULL)
- return NULL;
- rl = Py_BuildValue ("[O]", r);
- Py_DECREF (r);
- return rl;
- }
- static PyObject *
- typy_field_names (PyObject *self, PyObject *args)
- {
- return typy_fields_items (self, iter_keys);
- }
- static PyObject *
- typy_items (PyObject *self, PyObject *args)
- {
- return typy_fields_items (self, iter_items);
- }
- static PyObject *
- typy_get_name (PyObject *self, void *closure)
- {
- struct type *type = ((type_object *) self)->type;
- if (TYPE_NAME (type) == NULL)
- Py_RETURN_NONE;
- return PyString_FromString (TYPE_NAME (type));
- }
- static PyObject *
- typy_get_tag (PyObject *self, void *closure)
- {
- struct type *type = ((type_object *) self)->type;
- if (!TYPE_TAG_NAME (type))
- Py_RETURN_NONE;
- return PyString_FromString (TYPE_TAG_NAME (type));
- }
- static PyObject *
- typy_strip_typedefs (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = check_typedef (type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (type);
- }
- static struct type *
- typy_get_composite (struct type *type)
- {
- volatile struct gdb_exception except;
- for (;;)
- {
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- CHECK_TYPEDEF (type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- if (TYPE_CODE (type) != TYPE_CODE_PTR
- && TYPE_CODE (type) != TYPE_CODE_REF)
- break;
- type = TYPE_TARGET_TYPE (type);
- }
-
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT
- && TYPE_CODE (type) != TYPE_CODE_UNION
- && TYPE_CODE (type) != TYPE_CODE_ENUM)
- {
- PyErr_SetString (PyExc_TypeError,
- "Type is not a structure, union, or enum type.");
- return NULL;
- }
- return type;
- }
- static PyObject *
- typy_array_1 (PyObject *self, PyObject *args, int is_vector)
- {
- long n1, n2;
- PyObject *n2_obj = NULL;
- struct type *array = NULL;
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- if (! PyArg_ParseTuple (args, "l|O", &n1, &n2_obj))
- return NULL;
- if (n2_obj)
- {
- if (!PyInt_Check (n2_obj))
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Array bound must be an integer"));
- return NULL;
- }
- if (! gdb_py_int_as_long (n2_obj, &n2))
- return NULL;
- }
- else
- {
- n2 = n1;
- n1 = 0;
- }
- if (n2 < n1 - 1)
- {
- PyErr_SetString (PyExc_ValueError,
- _("Array length must not be negative"));
- return NULL;
- }
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- array = lookup_array_range_type (type, n1, n2);
- if (is_vector)
- make_vector_type (array);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (array);
- }
- static PyObject *
- typy_array (PyObject *self, PyObject *args)
- {
- return typy_array_1 (self, args, 0);
- }
- static PyObject *
- typy_vector (PyObject *self, PyObject *args)
- {
- return typy_array_1 (self, args, 1);
- }
- static PyObject *
- typy_pointer (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = lookup_pointer_type (type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (type);
- }
- static PyObject *
- typy_range (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- PyObject *result;
- PyObject *low_bound = NULL, *high_bound = NULL;
-
- LONGEST low = 0, high = 0;
- if (TYPE_CODE (type) != TYPE_CODE_ARRAY
- && TYPE_CODE (type) != TYPE_CODE_STRING
- && TYPE_CODE (type) != TYPE_CODE_RANGE)
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("This type does not have a range."));
- return NULL;
- }
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_STRING:
- low = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type));
- high = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (type));
- break;
- case TYPE_CODE_RANGE:
- low = TYPE_LOW_BOUND (type);
- high = TYPE_HIGH_BOUND (type);
- break;
- }
- low_bound = PyLong_FromLong (low);
- if (!low_bound)
- goto failarg;
- high_bound = PyLong_FromLong (high);
- if (!high_bound)
- goto failarg;
- result = PyTuple_New (2);
- if (!result)
- goto failarg;
- if (PyTuple_SetItem (result, 0, low_bound) != 0)
- {
- Py_DECREF (result);
- goto failarg;
- }
- if (PyTuple_SetItem (result, 1, high_bound) != 0)
- {
- Py_DECREF (high_bound);
- Py_DECREF (result);
- return NULL;
- }
- return result;
- failarg:
- Py_XDECREF (high_bound);
- Py_XDECREF (low_bound);
- return NULL;
- }
- static PyObject *
- typy_reference (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = lookup_reference_type (type);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (type);
- }
- static PyObject *
- typy_target (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- if (!TYPE_TARGET_TYPE (type))
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Type does not have a target."));
- return NULL;
- }
- return type_to_type_object (TYPE_TARGET_TYPE (type));
- }
- static PyObject *
- typy_const (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = make_cv_type (1, 0, type, NULL);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (type);
- }
- static PyObject *
- typy_volatile (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = make_cv_type (0, 1, type, NULL);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (type);
- }
- static PyObject *
- typy_unqualified (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = make_cv_type (0, 0, type, NULL);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type_to_type_object (type);
- }
- static PyObject *
- typy_get_sizeof (PyObject *self, void *closure)
- {
- struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- check_typedef (type);
- }
-
- return gdb_py_long_from_longest (TYPE_LENGTH (type));
- }
- static struct type *
- typy_lookup_typename (const char *type_name, const struct block *block)
- {
- struct type *type = NULL;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- if (!strncmp (type_name, "struct ", 7))
- type = lookup_struct (type_name + 7, NULL);
- else if (!strncmp (type_name, "union ", 6))
- type = lookup_union (type_name + 6, NULL);
- else if (!strncmp (type_name, "enum ", 5))
- type = lookup_enum (type_name + 5, NULL);
- else
- type = lookup_typename (python_language, python_gdbarch,
- type_name, block, 0);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return type;
- }
- static struct type *
- typy_lookup_type (struct demangle_component *demangled,
- const struct block *block)
- {
- struct type *type, *rtype = NULL;
- char *type_name = NULL;
- enum demangle_component_type demangled_type;
- volatile struct gdb_exception except;
-
- demangled_type = demangled->type;
- if (demangled_type == DEMANGLE_COMPONENT_POINTER
- || demangled_type == DEMANGLE_COMPONENT_REFERENCE
- || demangled_type == DEMANGLE_COMPONENT_CONST
- || demangled_type == DEMANGLE_COMPONENT_VOLATILE)
- {
- type = typy_lookup_type (demangled->u.s_binary.left, block);
- if (! type)
- return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
-
- switch (demangled_type)
- {
- case DEMANGLE_COMPONENT_REFERENCE:
- rtype = lookup_reference_type (type);
- break;
- case DEMANGLE_COMPONENT_POINTER:
- rtype = lookup_pointer_type (type);
- break;
- case DEMANGLE_COMPONENT_CONST:
- rtype = make_cv_type (1, 0, type, NULL);
- break;
- case DEMANGLE_COMPONENT_VOLATILE:
- rtype = make_cv_type (0, 1, type, NULL);
- break;
- }
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- }
-
- if (rtype)
- return rtype;
-
- type_name = cp_comp_to_string (demangled, 10);
- type = typy_lookup_typename (type_name, block);
- xfree (type_name);
- return type;
- }
- static PyObject *
- typy_legacy_template_argument (struct type *type, const struct block *block,
- int argno)
- {
- int i;
- struct demangle_component *demangled;
- struct demangle_parse_info *info = NULL;
- const char *err;
- struct type *argtype;
- struct cleanup *cleanup;
- volatile struct gdb_exception except;
- if (TYPE_NAME (type) == NULL)
- {
- PyErr_SetString (PyExc_RuntimeError, _("Null type name."));
- return NULL;
- }
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
-
- info = cp_demangled_name_to_comp (TYPE_NAME (type), &err);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- if (! info)
- {
- PyErr_SetString (PyExc_RuntimeError, err);
- return NULL;
- }
- demangled = info->tree;
- cleanup = make_cleanup_cp_demangled_name_parse_free (info);
-
- while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME
- || demangled->type == DEMANGLE_COMPONENT_LOCAL_NAME)
- demangled = demangled->u.s_binary.right;
- if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE)
- {
- do_cleanups (cleanup);
- PyErr_SetString (PyExc_RuntimeError, _("Type is not a template."));
- return NULL;
- }
-
- demangled = demangled->u.s_binary.right;
- for (i = 0; demangled && i < argno; ++i)
- demangled = demangled->u.s_binary.right;
- if (! demangled)
- {
- do_cleanups (cleanup);
- PyErr_Format (PyExc_RuntimeError, _("No argument %d in template."),
- argno);
- return NULL;
- }
- argtype = typy_lookup_type (demangled->u.s_binary.left, block);
- do_cleanups (cleanup);
- if (! argtype)
- return NULL;
- return type_to_type_object (argtype);
- }
- static PyObject *
- typy_template_argument (PyObject *self, PyObject *args)
- {
- int argno;
- struct type *type = ((type_object *) self)->type;
- const struct block *block = NULL;
- PyObject *block_obj = NULL;
- struct symbol *sym;
- struct value *val = NULL;
- volatile struct gdb_exception except;
- if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj))
- return NULL;
- if (block_obj)
- {
- block = block_object_to_block (block_obj);
- if (! block)
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Second argument must be block."));
- return NULL;
- }
- }
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- type = check_typedef (type);
- if (TYPE_CODE (type) == TYPE_CODE_REF)
- type = check_typedef (TYPE_TARGET_TYPE (type));
- }
- GDB_PY_HANDLE_EXCEPTION (except);
-
- if (! TYPE_N_TEMPLATE_ARGUMENTS (type))
- return typy_legacy_template_argument (type, block, argno);
- if (argno >= TYPE_N_TEMPLATE_ARGUMENTS (type))
- {
- PyErr_Format (PyExc_RuntimeError, _("No argument %d in template."),
- argno);
- return NULL;
- }
- sym = TYPE_TEMPLATE_ARGUMENT (type, argno);
- if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
- return type_to_type_object (SYMBOL_TYPE (sym));
- else if (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT)
- {
- PyErr_Format (PyExc_RuntimeError,
- _("Template argument is optimized out"));
- return NULL;
- }
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- val = value_of_variable (sym, block);
- }
- GDB_PY_HANDLE_EXCEPTION (except);
- return value_to_value_object (val);
- }
- static PyObject *
- typy_str (PyObject *self)
- {
- volatile struct gdb_exception except;
- char *thetype = NULL;
- long length = 0;
- PyObject *result;
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- struct cleanup *old_chain;
- struct ui_file *stb;
- stb = mem_fileopen ();
- old_chain = make_cleanup_ui_file_delete (stb);
- LA_PRINT_TYPE (type_object_to_type (self), "", stb, -1, 0,
- &type_print_raw_options);
- thetype = ui_file_xstrdup (stb, &length);
- do_cleanups (old_chain);
- }
- if (except.reason < 0)
- {
- xfree (thetype);
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- result = PyUnicode_Decode (thetype, length, host_charset (), NULL);
- xfree (thetype);
- return result;
- }
- static PyObject *
- typy_richcompare (PyObject *self, PyObject *other, int op)
- {
- int result = Py_NE;
- struct type *type1 = type_object_to_type (self);
- struct type *type2 = type_object_to_type (other);
- volatile struct gdb_exception except;
-
- if (type2 == NULL || (op != Py_EQ && op != Py_NE))
- {
- Py_INCREF (Py_NotImplemented);
- return Py_NotImplemented;
- }
- if (type1 == type2)
- result = Py_EQ;
- else
- {
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- result = types_deeply_equal (type1, type2);
- }
-
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- if (op == (result ? Py_EQ : Py_NE))
- Py_RETURN_TRUE;
- Py_RETURN_FALSE;
- }
- static const struct objfile_data *typy_objfile_data_key;
- static void
- save_objfile_types (struct objfile *objfile, void *datum)
- {
- type_object *obj = datum;
- htab_t copied_types;
- struct cleanup *cleanup;
- if (!gdb_python_initialized)
- return;
-
- cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
- copied_types = create_copied_types_hash (objfile);
- while (obj)
- {
- type_object *next = obj->next;
- htab_empty (copied_types);
- obj->type = copy_type_recursive (objfile, obj->type, copied_types);
- obj->next = NULL;
- obj->prev = NULL;
- obj = next;
- }
- htab_delete (copied_types);
- do_cleanups (cleanup);
- }
- static void
- set_type (type_object *obj, struct type *type)
- {
- obj->type = type;
- obj->prev = NULL;
- if (type && TYPE_OBJFILE (type))
- {
- struct objfile *objfile = TYPE_OBJFILE (type);
- obj->next = objfile_data (objfile, typy_objfile_data_key);
- if (obj->next)
- obj->next->prev = obj;
- set_objfile_data (objfile, typy_objfile_data_key, obj);
- }
- else
- obj->next = NULL;
- }
- static void
- typy_dealloc (PyObject *obj)
- {
- type_object *type = (type_object *) obj;
- if (type->prev)
- type->prev->next = type->next;
- else if (type->type && TYPE_OBJFILE (type->type))
- {
-
- struct objfile *objfile = TYPE_OBJFILE (type->type);
- if (objfile)
- set_objfile_data (objfile, typy_objfile_data_key, type->next);
- }
- if (type->next)
- type->next->prev = type->prev;
- Py_TYPE (type)->tp_free (type);
- }
- static Py_ssize_t
- typy_length (PyObject *self)
- {
- struct type *type = ((type_object *) self)->type;
- type = typy_get_composite (type);
- if (type == NULL)
- return -1;
- return TYPE_NFIELDS (type);
- }
- static int
- typy_nonzero (PyObject *self)
- {
- return 1;
- }
- static PyObject *
- typy_getitem (PyObject *self, PyObject *key)
- {
- struct type *type = ((type_object *) self)->type;
- char *field;
- int i;
- field = python_string_to_host_string (key);
- if (field == NULL)
- return NULL;
-
- type = typy_get_composite (type);
- if (type == NULL)
- return NULL;
- for (i = 0; i < TYPE_NFIELDS (type); i++)
- {
- const char *t_field_name = TYPE_FIELD_NAME (type, i);
- if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
- {
- return convert_field (type, i);
- }
- }
- PyErr_SetObject (PyExc_KeyError, key);
- return NULL;
- }
- static PyObject *
- typy_get (PyObject *self, PyObject *args)
- {
- PyObject *key, *defval = Py_None, *result;
- if (!PyArg_UnpackTuple (args, "get", 1, 2, &key, &defval))
- return NULL;
- result = typy_getitem (self, key);
- if (result != NULL)
- return result;
-
- if (!PyErr_ExceptionMatches (PyExc_KeyError))
- return NULL;
- PyErr_Clear ();
- Py_INCREF (defval);
- return defval;
- }
- static PyObject *
- typy_has_key (PyObject *self, PyObject *args)
- {
- struct type *type = ((type_object *) self)->type;
- const char *field;
- int i;
- if (!PyArg_ParseTuple (args, "s", &field))
- return NULL;
-
- type = typy_get_composite (type);
- if (type == NULL)
- return NULL;
- for (i = 0; i < TYPE_NFIELDS (type); i++)
- {
- const char *t_field_name = TYPE_FIELD_NAME (type, i);
- if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
- Py_RETURN_TRUE;
- }
- Py_RETURN_FALSE;
- }
- static PyObject *
- typy_make_iter (PyObject *self, enum gdbpy_iter_kind kind)
- {
- typy_iterator_object *typy_iter_obj;
-
- if (typy_get_composite (((type_object *) self)->type) == NULL)
- return NULL;
- typy_iter_obj = PyObject_New (typy_iterator_object,
- &type_iterator_object_type);
- if (typy_iter_obj == NULL)
- return NULL;
- typy_iter_obj->field = 0;
- typy_iter_obj->kind = kind;
- Py_INCREF (self);
- typy_iter_obj->source = (type_object *) self;
- return (PyObject *) typy_iter_obj;
- }
- static PyObject *
- typy_iteritems (PyObject *self, PyObject *args)
- {
- return typy_make_iter (self, iter_items);
- }
- static PyObject *
- typy_iterkeys (PyObject *self, PyObject *args)
- {
- return typy_make_iter (self, iter_keys);
- }
- static PyObject *
- typy_iter (PyObject *self)
- {
- return typy_make_iter (self, iter_keys);
- }
- static PyObject *
- typy_itervalues (PyObject *self, PyObject *args)
- {
- return typy_make_iter (self, iter_values);
- }
- static PyObject *
- typy_iterator_iter (PyObject *self)
- {
- Py_INCREF (self);
- return self;
- }
- static PyObject *
- typy_iterator_iternext (PyObject *self)
- {
- typy_iterator_object *iter_obj = (typy_iterator_object *) self;
- struct type *type = iter_obj->source->type;
- PyObject *result;
- if (iter_obj->field < TYPE_NFIELDS (type))
- {
- result = make_fielditem (type, iter_obj->field, iter_obj->kind);
- if (result != NULL)
- iter_obj->field++;
- return result;
- }
- return NULL;
- }
- static void
- typy_iterator_dealloc (PyObject *obj)
- {
- typy_iterator_object *iter_obj = (typy_iterator_object *) obj;
- Py_DECREF (iter_obj->source);
- }
- PyObject *
- type_to_type_object (struct type *type)
- {
- type_object *type_obj;
- type_obj = PyObject_New (type_object, &type_object_type);
- if (type_obj)
- set_type (type_obj, type);
- return (PyObject *) type_obj;
- }
- struct type *
- type_object_to_type (PyObject *obj)
- {
- if (! PyObject_TypeCheck (obj, &type_object_type))
- return NULL;
- return ((type_object *) obj)->type;
- }
- PyObject *
- gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
- {
- static char *keywords[] = { "name", "block", NULL };
- const char *type_name = NULL;
- struct type *type = NULL;
- PyObject *block_obj = NULL;
- const struct block *block = NULL;
- if (! PyArg_ParseTupleAndKeywords (args, kw, "s|O", keywords,
- &type_name, &block_obj))
- return NULL;
- if (block_obj)
- {
- block = block_object_to_block (block_obj);
- if (! block)
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("'block' argument must be a Block."));
- return NULL;
- }
- }
- type = typy_lookup_typename (type_name, block);
- if (! type)
- return NULL;
- return (PyObject *) type_to_type_object (type);
- }
- int
- gdbpy_initialize_types (void)
- {
- int i;
- typy_objfile_data_key
- = register_objfile_data_with_cleanup (save_objfile_types, NULL);
- if (PyType_Ready (&type_object_type) < 0)
- return -1;
- if (PyType_Ready (&field_object_type) < 0)
- return -1;
- if (PyType_Ready (&type_iterator_object_type) < 0)
- return -1;
- for (i = 0; pyty_codes[i].name; ++i)
- {
- if (PyModule_AddIntConstant (gdb_module,
-
- (char *) pyty_codes[i].name,
- pyty_codes[i].code) < 0)
- return -1;
- }
- if (gdb_pymodule_addobject (gdb_module, "Type",
- (PyObject *) &type_object_type) < 0)
- return -1;
- if (gdb_pymodule_addobject (gdb_module, "TypeIterator",
- (PyObject *) &type_iterator_object_type) < 0)
- return -1;
- return gdb_pymodule_addobject (gdb_module, "Field",
- (PyObject *) &field_object_type);
- }
- static PyGetSetDef type_object_getset[] =
- {
- { "code", typy_get_code, NULL,
- "The code for this type.", NULL },
- { "name", typy_get_name, NULL,
- "The name for this type, or None.", NULL },
- { "sizeof", typy_get_sizeof, NULL,
- "The size of this type, in bytes.", NULL },
- { "tag", typy_get_tag, NULL,
- "The tag name for this type, or None.", NULL },
- { NULL }
- };
- static PyMethodDef type_object_methods[] =
- {
- { "array", typy_array, METH_VARARGS,
- "array ([LOW_BOUND,] HIGH_BOUND) -> Type\n\
- Return a type which represents an array of objects of this type.\n\
- The bounds of the array are [LOW_BOUND, HIGH_BOUND] inclusive.\n\
- If LOW_BOUND is omitted, a value of zero is used." },
- { "vector", typy_vector, METH_VARARGS,
- "vector ([LOW_BOUND,] HIGH_BOUND) -> Type\n\
- Return a type which represents a vector of objects of this type.\n\
- The bounds of the array are [LOW_BOUND, HIGH_BOUND] inclusive.\n\
- If LOW_BOUND is omitted, a value of zero is used.\n\
- Vectors differ from arrays in that if the current language has C-style\n\
- arrays, vectors don't decay to a pointer to the first element.\n\
- They are first class values." },
- { "__contains__", typy_has_key, METH_VARARGS,
- "T.__contains__(k) -> True if T has a field named k, else False" },
- { "const", typy_const, METH_NOARGS,
- "const () -> Type\n\
- Return a const variant of this type." },
- { "fields", typy_fields, METH_NOARGS,
- "fields () -> list\n\
- Return a list holding all the fields of this type.\n\
- Each field is a gdb.Field object." },
- { "get", typy_get, METH_VARARGS,
- "T.get(k[,default]) -> returns field named k in T, if it exists;\n\
- otherwise returns default, if supplied, or None if not." },
- { "has_key", typy_has_key, METH_VARARGS,
- "T.has_key(k) -> True if T has a field named k, else False" },
- { "items", typy_items, METH_NOARGS,
- "items () -> list\n\
- Return a list of (name, field) pairs of this type.\n\
- Each field is a gdb.Field object." },
- { "iteritems", typy_iteritems, METH_NOARGS,
- "iteritems () -> an iterator over the (name, field)\n\
- pairs of this type. Each field is a gdb.Field object." },
- { "iterkeys", typy_iterkeys, METH_NOARGS,
- "iterkeys () -> an iterator over the field names of this type." },
- { "itervalues", typy_itervalues, METH_NOARGS,
- "itervalues () -> an iterator over the fields of this type.\n\
- Each field is a gdb.Field object." },
- { "keys", typy_field_names, METH_NOARGS,
- "keys () -> list\n\
- Return a list holding all the fields names of this type." },
- { "pointer", typy_pointer, METH_NOARGS,
- "pointer () -> Type\n\
- Return a type of pointer to this type." },
- { "range", typy_range, METH_NOARGS,
- "range () -> tuple\n\
- Return a tuple containing the lower and upper range for this type."},
- { "reference", typy_reference, METH_NOARGS,
- "reference () -> Type\n\
- Return a type of reference to this type." },
- { "strip_typedefs", typy_strip_typedefs, METH_NOARGS,
- "strip_typedefs () -> Type\n\
- Return a type formed by stripping this type of all typedefs."},
- { "target", typy_target, METH_NOARGS,
- "target () -> Type\n\
- Return the target type of this type." },
- { "template_argument", typy_template_argument, METH_VARARGS,
- "template_argument (arg, [block]) -> Type\n\
- Return the type of a template argument." },
- { "unqualified", typy_unqualified, METH_NOARGS,
- "unqualified () -> Type\n\
- Return a variant of this type without const or volatile attributes." },
- { "values", typy_values, METH_NOARGS,
- "values () -> list\n\
- Return a list holding all the fields of this type.\n\
- Each field is a gdb.Field object." },
- { "volatile", typy_volatile, METH_NOARGS,
- "volatile () -> Type\n\
- Return a volatile variant of this type" },
- { NULL }
- };
- static PyNumberMethods type_object_as_number = {
- NULL,
- NULL,
- NULL,
- #ifndef IS_PY3K
- NULL,
- #endif
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- typy_nonzero,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- #ifdef IS_PY3K
- NULL,
- NULL,
- #else
- NULL,
- NULL,
- NULL,
- #endif
- NULL,
- #ifndef IS_PY3K
- NULL,
- NULL
- #endif
- };
- static PyMappingMethods typy_mapping = {
- typy_length,
- typy_getitem,
- NULL
- };
- static PyTypeObject type_object_type =
- {
- PyVarObject_HEAD_INIT (NULL, 0)
- "gdb.Type",
- sizeof (type_object),
- 0,
- typy_dealloc,
- 0,
- 0,
- 0,
- 0,
- 0,
- &type_object_as_number,
- 0,
- &typy_mapping,
- 0,
- 0,
- typy_str,
- 0,
- 0,
- 0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
- "GDB type object",
- 0,
- 0,
- typy_richcompare,
- 0,
- typy_iter,
- 0,
- type_object_methods,
- 0,
- type_object_getset,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- };
- static PyGetSetDef field_object_getset[] =
- {
- { "__dict__", gdb_py_generic_dict, NULL,
- "The __dict__ for this field.", &field_object_type },
- { NULL }
- };
- static PyTypeObject field_object_type =
- {
- PyVarObject_HEAD_INIT (NULL, 0)
- "gdb.Field",
- sizeof (field_object),
- 0,
- field_dealloc,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
- "GDB field object",
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- field_object_getset,
- 0,
- 0,
- 0,
- 0,
- offsetof (field_object, dict),
- 0,
- 0,
- 0,
- };
- static PyTypeObject type_iterator_object_type = {
- PyVarObject_HEAD_INIT (NULL, 0)
- "gdb.TypeIterator",
- sizeof (typy_iterator_object),
- 0,
- typy_iterator_dealloc,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,
- "GDB type iterator object",
- 0,
- 0,
- 0,
- 0,
- typy_iterator_iter,
- typy_iterator_iternext,
- 0
- };