X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-type.c;h=7ad1a0c70e845d0743d122921a3a8acbbb7f6e85;hb=b5eba2d8c050b39943918057283470959a5d18c3;hp=8e82c99f2e213147f6819c5784ab540e1f7ae874;hpb=8503d6e1e564cb5ac61bc6e3f16c0b384c76661e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 8e82c99f2e..7ad1a0c70e 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -1,6 +1,6 @@ /* Python interface to types. - Copyright (C) 2008-2015 Free Software Foundation, Inc. + Copyright (C) 2008-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -26,7 +26,7 @@ #include "demangle.h" #include "objfiles.h" #include "language.h" -#include "vec.h" +#include "common/vec.h" #include "typeprint.h" typedef struct pyty_type_object @@ -41,7 +41,7 @@ typedef struct pyty_type_object struct pyty_type_object *next; } type_object; -static PyTypeObject type_object_type +extern PyTypeObject type_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("type_object"); /* A Field object. */ @@ -53,7 +53,7 @@ typedef struct pyty_field_object PyObject *dict; } field_object; -static PyTypeObject field_object_type +extern PyTypeObject field_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("field_object"); /* A type iterator object. */ @@ -67,7 +67,7 @@ typedef struct { struct pyty_type_object *source; } typy_iterator_object; -static PyTypeObject type_iterator_object_type +extern PyTypeObject type_iterator_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("typy_iterator_object"); /* This is used to initialize various gdb.TYPE_ constants. */ @@ -105,6 +105,7 @@ static struct pyty_code pyty_codes[] = ENTRY (TYPE_CODE_METHODPTR), ENTRY (TYPE_CODE_MEMBERPTR), ENTRY (TYPE_CODE_REF), + ENTRY (TYPE_CODE_RVALUE_REF), ENTRY (TYPE_CODE_CHAR), ENTRY (TYPE_CODE_BOOL), ENTRY (TYPE_CODE_COMPLEX), @@ -129,18 +130,16 @@ field_dealloc (PyObject *obj) static PyObject * field_new (void) { - field_object *result = PyObject_New (field_object, &field_object_type); + gdbpy_ref result (PyObject_New (field_object, + &field_object_type)); - if (result) + if (result != NULL) { result->dict = PyDict_New (); if (!result->dict) - { - Py_DECREF (result); - result = NULL; - } + return NULL; } - return (PyObject *) result; + return (PyObject *) result.release (); } @@ -165,21 +164,19 @@ typy_get_code (PyObject *self, void *closure) /* Helper function for typy_fields which converts a single field to a gdb.Field object. Returns NULL on error. */ -static PyObject * +static gdbpy_ref<> convert_field (struct type *type, int field) { - PyObject *result = field_new (); - PyObject *arg; + gdbpy_ref<> result (field_new ()); - if (!result) + if (result == NULL) return NULL; - arg = type_to_type_object (type); + gdbpy_ref<> arg (type_to_type_object (type)); if (arg == NULL) - goto fail; - if (PyObject_SetAttrString (result, "parent_type", arg) < 0) - goto failarg; - Py_DECREF (arg); + return NULL; + if (PyObject_SetAttrString (result.get (), "parent_type", arg.get ()) < 0) + return NULL; if (!field_is_static (&TYPE_FIELD (type, field))) { @@ -187,105 +184,89 @@ convert_field (struct type *type, int field) if (TYPE_CODE (type) == TYPE_CODE_ENUM) { - arg = gdb_py_long_from_longest (TYPE_FIELD_ENUMVAL (type, field)); + arg.reset (gdb_py_long_from_longest (TYPE_FIELD_ENUMVAL (type, + field))); attrstring = "enumval"; } else { - arg = gdb_py_long_from_longest (TYPE_FIELD_BITPOS (type, field)); + arg.reset (gdb_py_long_from_longest (TYPE_FIELD_BITPOS (type, + field))); attrstring = "bitpos"; } - if (!arg) - goto fail; + if (arg == NULL) + return NULL; /* At least python-2.4 had the second parameter non-const. */ - if (PyObject_SetAttrString (result, (char *) attrstring, arg) < 0) - goto failarg; - Py_DECREF (arg); + if (PyObject_SetAttrString (result.get (), (char *) attrstring, + arg.get ()) < 0) + return NULL; } - arg = NULL; + arg.reset (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)); + arg.reset (PyString_FromString (TYPE_FIELD_NAME (type, field))); if (arg == NULL) - goto fail; + return NULL; } } if (arg == NULL) - { - arg = Py_None; - Py_INCREF (arg); - } - if (PyObject_SetAttrString (result, "name", arg) < 0) - goto failarg; - Py_DECREF (arg); + arg = gdbpy_ref<>::new_reference (Py_None); - 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 (PyObject_SetAttrString (result.get (), "name", arg.get ()) < 0) + return NULL; + + arg = gdbpy_ref<>::new_reference (TYPE_FIELD_ARTIFICIAL (type, field) + ? Py_True : Py_False); + if (PyObject_SetAttrString (result.get (), "artificial", arg.get ()) < 0) + return NULL; if (TYPE_CODE (type) == TYPE_CODE_STRUCT) - arg = field < TYPE_N_BASECLASSES (type) ? Py_True : Py_False; + arg = gdbpy_ref<>::new_reference (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); + arg = gdbpy_ref<>::new_reference (Py_False); + if (PyObject_SetAttrString (result.get (), "is_base_class", arg.get ()) < 0) + return NULL; + + arg.reset (PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field))); + if (arg == NULL) + return NULL; + if (PyObject_SetAttrString (result.get (), "bitsize", arg.get ()) < 0) + return NULL; /* A field can have a NULL type in some situations. */ if (TYPE_FIELD_TYPE (type, field) == NULL) - { - arg = Py_None; - Py_INCREF (arg); - } + arg = gdbpy_ref<>::new_reference (Py_None); 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); + arg.reset (type_to_type_object (TYPE_FIELD_TYPE (type, field))); + if (arg == NULL) + return NULL; + if (PyObject_SetAttrString (result.get (), "type", arg.get ()) < 0) + return NULL; return result; - - failarg: - Py_DECREF (arg); - fail: - Py_DECREF (result); - return NULL; } /* Helper function to return the name of a field, as a gdb.Field object. If the field doesn't have a name, None is returned. */ -static PyObject * +static gdbpy_ref<> field_name (struct type *type, int field) { - PyObject *result; + gdbpy_ref<> result; if (TYPE_FIELD_NAME (type, field)) - result = PyString_FromString (TYPE_FIELD_NAME (type, field)); + result.reset (PyString_FromString (TYPE_FIELD_NAME (type, field))); else - { - result = Py_None; - Py_INCREF (result); - } + result = gdbpy_ref<>::new_reference (Py_None); + return result; } @@ -295,42 +276,32 @@ field_name (struct type *type, int field) the field, or a tuple consisting of field name and gdb.Field object. */ -static PyObject * +static gdbpy_ref<> 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; + { + gdbpy_ref<> key (field_name (type, i)); + if (key == NULL) + return NULL; + gdbpy_ref<> value = convert_field (type, i); + if (value == NULL) + return NULL; + gdbpy_ref<> item (PyTuple_New (2)); + if (item == NULL) + return NULL; + PyTuple_SET_ITEM (item.get (), 0, key.release ()); + PyTuple_SET_ITEM (item.get (), 1, value.release ()); + return item; + } case iter_keys: - item = field_name (type, i); - break; + return field_name (type, i); case iter_values: - item = convert_field (type, i); - break; - default: - gdb_assert_not_reached ("invalid gdbpy_iter_kind"); + return convert_field (type, i); } - return item; - - fail: - Py_XDECREF (key); - Py_XDECREF (value); - Py_XDECREF (item); - return NULL; + gdb_assert_not_reached ("invalid gdbpy_iter_kind"); } /* Return a sequence of all field names, fields, or (name, field) pairs. @@ -340,33 +311,32 @@ 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) + TRY { - CHECK_TYPEDEF (checked_type); + checked_type = 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) + CATCH (except, RETURN_MASK_ALL) { - /* Need to wrap this in braces because Py_DECREF isn't wrapped - in a do{}while(0). */ - Py_DECREF (py_type); + GDB_PY_HANDLE_EXCEPTION (except); } - if (iter != NULL) + END_CATCH + + gdbpy_ref<> type_holder; + if (checked_type != type) { - result = PySequence_List (iter); - Py_DECREF (iter); + type_holder.reset (type_to_type_object (checked_type)); + if (type_holder == nullptr) + return nullptr; + py_type = type_holder.get (); } + gdbpy_ref<> iter (typy_make_iter (py_type, kind)); + if (iter == nullptr) + return nullptr; - return result; + return PySequence_List (iter.get ()); } /* Return a sequence of all fields. Each field is a gdb.Field object. */ @@ -386,7 +356,6 @@ 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); @@ -394,14 +363,11 @@ typy_fields (PyObject *self, PyObject *args) /* Array type. Handle this as a special case because the common machinery wants struct or union or enum types. Build a list of one entry which is the range for the array. */ - r = convert_field (type, 0); + gdbpy_ref<> r = convert_field (type, 0); if (r == NULL) return NULL; - rl = Py_BuildValue ("[O]", r); - Py_DECREF (r); - - return rl; + return Py_BuildValue ("[O]", r.get ()); } /* Return a sequence of all field names. Each field is a gdb.Field object. */ @@ -438,10 +404,16 @@ static PyObject * typy_get_tag (PyObject *self, void *closure) { struct type *type = ((type_object *) self)->type; + const char *tagname = nullptr; + + if (TYPE_CODE (type) == TYPE_CODE_STRUCT + || TYPE_CODE (type) == TYPE_CODE_UNION + || TYPE_CODE (type) == TYPE_CODE_ENUM) + tagname = TYPE_NAME (type); - if (!TYPE_TAG_NAME (type)) + if (tagname == nullptr) Py_RETURN_NONE; - return PyString_FromString (TYPE_TAG_NAME (type)); + return PyString_FromString (tagname); } /* Return the type, stripped of typedefs. */ @@ -449,13 +421,16 @@ 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) + TRY { type = check_typedef (type); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (type); } @@ -466,18 +441,20 @@ typy_strip_typedefs (PyObject *self, PyObject *args) static struct type * typy_get_composite (struct type *type) { - volatile struct gdb_exception except; for (;;) { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - CHECK_TYPEDEF (type); + type = check_typedef (type); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH - if (TYPE_CODE (type) != TYPE_CODE_PTR - && TYPE_CODE (type) != TYPE_CODE_REF) + if (TYPE_CODE (type) != TYPE_CODE_PTR && !TYPE_IS_REFERENCE (type)) break; type = TYPE_TARGET_TYPE (type); } @@ -486,10 +463,11 @@ typy_get_composite (struct type *type) exception. */ if (TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION - && TYPE_CODE (type) != TYPE_CODE_ENUM) + && TYPE_CODE (type) != TYPE_CODE_ENUM + && TYPE_CODE (type) != TYPE_CODE_FUNC) { PyErr_SetString (PyExc_TypeError, - "Type is not a structure, union, or enum type."); + "Type is not a structure, union, enum, or function type."); return NULL; } @@ -505,7 +483,6 @@ typy_array_1 (PyObject *self, PyObject *args, int is_vector) 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; @@ -528,20 +505,24 @@ typy_array_1 (PyObject *self, PyObject *args, int is_vector) n1 = 0; } - if (n2 < n1 - 1) + if (n2 < n1 - 1) /* Note: An empty array has n2 == n1 - 1. */ { PyErr_SetString (PyExc_ValueError, _("Array length must not be negative")); return NULL; } - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { array = lookup_array_range_type (type, n1, n2); if (is_vector) make_vector_type (array); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (array); } @@ -567,13 +548,16 @@ 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) + TRY { type = lookup_pointer_type (type); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (type); } @@ -585,8 +569,6 @@ static PyObject * typy_range (PyObject *self, PyObject *args) { struct type *type = ((type_object *) self)->type; - PyObject *result; - PyObject *low_bound = NULL, *high_bound = NULL; /* Initialize these to appease GCC warnings. */ LONGEST low = 0, high = 0; @@ -612,35 +594,22 @@ typy_range (PyObject *self, PyObject *args) break; } - low_bound = PyLong_FromLong (low); - if (!low_bound) - goto failarg; - - high_bound = PyLong_FromLong (high); - if (!high_bound) - goto failarg; + gdbpy_ref<> low_bound (PyLong_FromLong (low)); + if (low_bound == NULL) + return NULL; - result = PyTuple_New (2); - if (!result) - goto failarg; + gdbpy_ref<> high_bound (PyLong_FromLong (high)); + if (high_bound == NULL) + return NULL; - 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; + gdbpy_ref<> result (PyTuple_New (2)); + if (result == NULL) + return NULL; - failarg: - Py_XDECREF (high_bound); - Py_XDECREF (low_bound); - return NULL; + if (PyTuple_SetItem (result.get (), 0, low_bound.release ()) != 0 + || PyTuple_SetItem (result.get (), 1, high_bound.release ()) != 0) + return NULL; + return result.release (); } /* Return a Type object which represents a reference to SELF. */ @@ -648,13 +617,16 @@ 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) + TRY { - type = lookup_reference_type (type); + type = lookup_lvalue_reference_type (type); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (type); } @@ -680,13 +652,16 @@ 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) + TRY { type = make_cv_type (1, 0, type, NULL); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (type); } @@ -696,13 +671,16 @@ 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) + TRY { type = make_cv_type (0, 1, type, NULL); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (type); } @@ -712,13 +690,16 @@ 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) + TRY { type = make_cv_type (0, 0, type, NULL); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type_to_type_object (type); } @@ -728,36 +709,65 @@ 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) + TRY { check_typedef (type); } + CATCH (except, RETURN_MASK_ALL) + { + } + END_CATCH + /* Ignore exceptions. */ return gdb_py_long_from_longest (TYPE_LENGTH (type)); } +/* Return the alignment of the type represented by SELF, in bytes. */ +static PyObject * +typy_get_alignof (PyObject *self, void *closure) +{ + struct type *type = ((type_object *) self)->type; + + ULONGEST align = 0; + TRY + { + align = type_align (type); + } + CATCH (except, RETURN_MASK_ALL) + { + align = 0; + } + END_CATCH + + /* Ignore exceptions. */ + + return gdb_py_object_from_ulongest (align).release (); +} + 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) + TRY { - if (!strncmp (type_name, "struct ", 7)) + if (startswith (type_name, "struct ")) type = lookup_struct (type_name + 7, NULL); - else if (!strncmp (type_name, "union ", 6)) + else if (startswith (type_name, "union ")) type = lookup_union (type_name + 6, NULL); - else if (!strncmp (type_name, "enum ", 5)) + else if (startswith (type_name, "enum ")) type = lookup_enum (type_name + 5, NULL); else type = lookup_typename (python_language, python_gdbarch, type_name, block, 0); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return type; } @@ -767,9 +777,7 @@ 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; /* Save the type: typy_lookup_type() may (indirectly) overwrite memory pointed by demangled. */ @@ -777,6 +785,7 @@ typy_lookup_type (struct demangle_component *demangled, if (demangled_type == DEMANGLE_COMPONENT_POINTER || demangled_type == DEMANGLE_COMPONENT_REFERENCE + || demangled_type == DEMANGLE_COMPONENT_RVALUE_REFERENCE || demangled_type == DEMANGLE_COMPONENT_CONST || demangled_type == DEMANGLE_COMPONENT_VOLATILE) { @@ -784,7 +793,7 @@ typy_lookup_type (struct demangle_component *demangled, if (! type) return NULL; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { /* If the demangled_type matches with one of the types below, run the corresponding function and save the type @@ -793,7 +802,10 @@ typy_lookup_type (struct demangle_component *demangled, switch (demangled_type) { case DEMANGLE_COMPONENT_REFERENCE: - rtype = lookup_reference_type (type); + rtype = lookup_lvalue_reference_type (type); + break; + case DEMANGLE_COMPONENT_RVALUE_REFERENCE: + rtype = lookup_rvalue_reference_type (type); break; case DEMANGLE_COMPONENT_POINTER: rtype = lookup_pointer_type (type); @@ -806,7 +818,11 @@ typy_lookup_type (struct demangle_component *demangled, break; } } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH } /* If we have a type from the switch statement above, just return @@ -815,11 +831,8 @@ typy_lookup_type (struct demangle_component *demangled, return rtype; /* We don't have a type, so lookup the type. */ - type_name = cp_comp_to_string (demangled, 10); - type = typy_lookup_typename (type_name, block); - xfree (type_name); - - return type; + gdb::unique_xmalloc_ptr type_name = cp_comp_to_string (demangled, 10); + return typy_lookup_typename (type_name.get (), block); } /* This is a helper function for typy_template_argument that is used @@ -833,11 +846,9 @@ typy_legacy_template_argument (struct type *type, const struct block *block, { int i; struct demangle_component *demangled; - struct demangle_parse_info *info = NULL; - const char *err; + std::unique_ptr info; + std::string err; struct type *argtype; - struct cleanup *cleanup; - volatile struct gdb_exception except; if (TYPE_NAME (type) == NULL) { @@ -845,20 +856,23 @@ typy_legacy_template_argument (struct type *type, const struct block *block, return NULL; } - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { /* Note -- this is not thread-safe. */ info = cp_demangled_name_to_comp (TYPE_NAME (type), &err); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH if (! info) { - PyErr_SetString (PyExc_RuntimeError, err); + PyErr_SetString (PyExc_RuntimeError, err.c_str ()); return NULL; } demangled = info->tree; - cleanup = make_cleanup_cp_demangled_name_parse_free (info); /* Strip off component names. */ while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME @@ -867,7 +881,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block, if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE) { - do_cleanups (cleanup); PyErr_SetString (PyExc_RuntimeError, _("Type is not a template.")); return NULL; } @@ -880,14 +893,12 @@ typy_legacy_template_argument (struct type *type, const struct block *block, 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; @@ -903,11 +914,17 @@ typy_template_argument (PyObject *self, PyObject *args) 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 (argno < 0) + { + PyErr_SetString (PyExc_RuntimeError, + _("Template argument number must be non-negative")); + return NULL; + } + if (block_obj) { block = block_object_to_block (block_obj); @@ -919,13 +936,17 @@ typy_template_argument (PyObject *self, PyObject *args) } } - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { type = check_typedef (type); - if (TYPE_CODE (type) == TYPE_CODE_REF) + if (TYPE_IS_REFERENCE (type)) type = check_typedef (TYPE_TARGET_TYPE (type)); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH /* We might not have DW_TAG_template_*, so try to parse the type's name. This is inefficient if we do not have a template type -- @@ -950,11 +971,15 @@ typy_template_argument (PyObject *self, PyObject *args) return NULL; } - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { val = value_of_variable (sym, block); } - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH return value_to_value_object (val); } @@ -962,35 +987,21 @@ typy_template_argument (PyObject *self, PyObject *args) static PyObject * typy_str (PyObject *self) { - volatile struct gdb_exception except; - char *thetype = NULL; - long length = 0; - PyObject *result; + string_file thetype; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - 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, + LA_PRINT_TYPE (type_object_to_type (self), "", &thetype, -1, 0, &type_print_raw_options); - - thetype = ui_file_xstrdup (stb, &length); - do_cleanups (old_chain); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { - xfree (thetype); GDB_PY_HANDLE_EXCEPTION (except); } + END_CATCH - result = PyUnicode_Decode (thetype, length, host_charset (), NULL); - xfree (thetype); - - return result; + return PyUnicode_Decode (thetype.c_str (), thetype.size (), + host_charset (), NULL); } /* Implement the richcompare method. */ @@ -998,10 +1009,9 @@ typy_str (PyObject *self) static PyObject * typy_richcompare (PyObject *self, PyObject *other, int op) { - int result = Py_NE; + bool result = false; struct type *type1 = type_object_to_type (self); struct type *type2 = type_object_to_type (other); - volatile struct gdb_exception except; /* We can only compare ourselves to another Type object, and only for equality or inequality. */ @@ -1012,16 +1022,20 @@ typy_richcompare (PyObject *self, PyObject *other, int op) } if (type1 == type2) - result = Py_EQ; + result = true; else { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { result = types_deeply_equal (type1, type2); } - /* If there is a GDB exception, a comparison is not capable - (or trusted), so exit. */ - GDB_PY_HANDLE_EXCEPTION (except); + CATCH (except, RETURN_MASK_ALL) + { + /* If there is a GDB exception, a comparison is not capable + (or trusted), so exit. */ + GDB_PY_HANDLE_EXCEPTION (except); + } + END_CATCH } if (op == (result ? Py_EQ : Py_NE)) @@ -1036,16 +1050,15 @@ static const struct objfile_data *typy_objfile_data_key; static void save_objfile_types (struct objfile *objfile, void *datum) { - type_object *obj = datum; + type_object *obj = (type_object *) datum; htab_t copied_types; - struct cleanup *cleanup; if (!gdb_python_initialized) return; /* This prevents another thread from freeing the objects we're operating on. */ - cleanup = ensure_python_env (get_objfile_arch (objfile), current_language); + gdbpy_enter enter_py (get_objfile_arch (objfile), current_language); copied_types = create_copied_types_hash (objfile); @@ -1064,8 +1077,6 @@ save_objfile_types (struct objfile *objfile, void *datum) } htab_delete (copied_types); - - do_cleanups (cleanup); } static void @@ -1077,7 +1088,8 @@ set_type (type_object *obj, struct type *type) { struct objfile *objfile = TYPE_OBJFILE (type); - obj->next = objfile_data (objfile, typy_objfile_data_key); + obj->next = ((struct pyty_type_object *) + objfile_data (objfile, typy_objfile_data_key)); if (obj->next) obj->next->prev = obj; set_objfile_data (objfile, typy_objfile_data_key, obj); @@ -1131,16 +1143,25 @@ typy_nonzero (PyObject *self) return 1; } +/* Return optimized out value of this type. */ + +static PyObject * +typy_optimized_out (PyObject *self, PyObject *args) +{ + struct type *type = ((type_object *) self)->type; + + return value_to_value_object (allocate_optimized_out_value (type)); +} + /* Return a gdb.Field object for the field named by the argument. */ 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); + gdb::unique_xmalloc_ptr field = python_string_to_host_string (key); if (field == NULL) return NULL; @@ -1156,10 +1177,8 @@ typy_getitem (PyObject *self, PyObject *key) { 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); - } + if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0)) + return convert_field (type, i).release (); } PyErr_SetObject (PyExc_KeyError, key); return NULL; @@ -1296,14 +1315,14 @@ 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); + gdbpy_ref<> result = make_fielditem (type, iter_obj->field, + iter_obj->kind); if (result != NULL) iter_obj->field++; - return result; + return result.release (); } return NULL; @@ -1344,14 +1363,14 @@ type_object_to_type (PyObject *obj) PyObject * gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw) { - static char *keywords[] = { "name", "block", NULL }; + static const 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)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O", keywords, + &type_name, &block_obj)) return NULL; if (block_obj) @@ -1369,7 +1388,7 @@ gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw) if (! type) return NULL; - return (PyObject *) type_to_type_object (type); + return type_to_type_object (type); } int @@ -1410,8 +1429,10 @@ gdbpy_initialize_types (void) -static PyGetSetDef type_object_getset[] = +static gdb_PyGetSetDef type_object_getset[] = { + { "alignof", typy_get_alignof, NULL, + "The alignment of this type, in bytes.", NULL }, { "code", typy_get_code, NULL, "The code for this type.", NULL }, { "name", typy_get_name, NULL, @@ -1443,6 +1464,9 @@ They are first class values." }, { "const", typy_const, METH_NOARGS, "const () -> Type\n\ Return a const variant of this type." }, + { "optimized_out", typy_optimized_out, METH_NOARGS, + "optimized_out() -> Value\n\ +Return optimized out value of this type." }, { "fields", typy_fields, METH_NOARGS, "fields () -> list\n\ Return a list holding all the fields of this type.\n\ @@ -1539,7 +1563,7 @@ static PyMappingMethods typy_mapping = { NULL /* no "set" method */ }; -static PyTypeObject type_object_type = +PyTypeObject type_object_type = { PyVarObject_HEAD_INIT (NULL, 0) "gdb.Type", /*tp_name*/ @@ -1581,14 +1605,14 @@ static PyTypeObject type_object_type = 0, /* tp_new */ }; -static PyGetSetDef field_object_getset[] = +static gdb_PyGetSetDef field_object_getset[] = { { "__dict__", gdb_py_generic_dict, NULL, "The __dict__ for this field.", &field_object_type }, { NULL } }; -static PyTypeObject field_object_type = +PyTypeObject field_object_type = { PyVarObject_HEAD_INIT (NULL, 0) "gdb.Field", /*tp_name*/ @@ -1630,7 +1654,7 @@ static PyTypeObject field_object_type = 0, /* tp_new */ }; -static PyTypeObject type_iterator_object_type = { +PyTypeObject type_iterator_object_type = { PyVarObject_HEAD_INIT (NULL, 0) "gdb.TypeIterator", /*tp_name*/ sizeof (typy_iterator_object), /*tp_basicsize*/