X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-type.c;h=f0710061f748779d6b0150b4b9a89d1ef5a734bc;hb=aa0061181ab00081e9907447561e589d6edee9f2;hp=648d8c8e1787519a8736249b3bf639c4f7b4be5b;hpb=59fb7612ddee9219817a0c33b7d533b3d1c2aa41;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 648d8c8e17..f0710061f7 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-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -28,6 +28,7 @@ #include "language.h" #include "vec.h" #include "typeprint.h" +#include "py-ref.h" typedef struct pyty_type_object { @@ -105,6 +106,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 +131,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 (); } @@ -168,18 +168,16 @@ typy_get_code (PyObject *self, void *closure) static PyObject * 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,88 +185,79 @@ 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); + arg.reset (Py_None); + Py_INCREF (arg.get ()); } - if (PyObject_SetAttrString (result, "name", arg) < 0) - goto failarg; - Py_DECREF (arg); + if (PyObject_SetAttrString (result.get (), "name", arg.get ()) < 0) + return NULL; - 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); + arg.reset (TYPE_FIELD_ARTIFICIAL (type, field) ? Py_True : Py_False); + Py_INCREF (arg.get ()); + 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.reset (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.reset (Py_False); + Py_INCREF (arg.get ()); + 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.reset (Py_None); + Py_INCREF (arg.get ()); } 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; + 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; - failarg: - Py_DECREF (arg); - fail: - Py_DECREF (result); - return NULL; + return result.release (); } /* Helper function to return the name of a field, as a gdb.Field object. @@ -298,39 +287,29 @@ field_name (struct type *type, int field) 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; + { + 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.release (); + } 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. @@ -346,7 +325,7 @@ typy_fields_items (PyObject *self, enum gdbpy_iter_kind kind) TRY { - CHECK_TYPEDEF (checked_type); + checked_type = check_typedef (checked_type); } CATCH (except, RETURN_MASK_ALL) { @@ -389,7 +368,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); @@ -397,14 +375,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. */ @@ -477,7 +452,7 @@ typy_get_composite (struct type *type) { TRY { - CHECK_TYPEDEF (type); + type = check_typedef (type); } CATCH (except, RETURN_MASK_ALL) { @@ -485,8 +460,7 @@ typy_get_composite (struct type *type) } 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); } @@ -495,10 +469,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; } @@ -600,8 +575,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; @@ -627,35 +600,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. */ @@ -666,7 +626,7 @@ typy_reference (PyObject *self, PyObject *args) TRY { - type = lookup_reference_type (type); + type = lookup_lvalue_reference_type (type); } CATCH (except, RETURN_MASK_ALL) { @@ -810,6 +770,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) { @@ -826,7 +787,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); @@ -870,10 +834,9 @@ typy_legacy_template_argument (struct type *type, const struct block *block, { int i; struct demangle_component *demangled; - struct demangle_parse_info *info = NULL; + std::unique_ptr info; const char *err; struct type *argtype; - struct cleanup *cleanup; if (TYPE_NAME (type) == NULL) { @@ -898,7 +861,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block, 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 @@ -907,7 +869,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; } @@ -920,14 +881,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; @@ -961,7 +920,7 @@ typy_template_argument (PyObject *self, PyObject *args) TRY { type = check_typedef (type); - if (TYPE_CODE (type) == TYPE_CODE_REF) + if (TYPE_IS_REFERENCE (type)) type = check_typedef (TYPE_TARGET_TYPE (type)); } CATCH (except, RETURN_MASK_ALL) @@ -1009,35 +968,22 @@ typy_template_argument (PyObject *self, PyObject *args) static PyObject * typy_str (PyObject *self) { - char *thetype = NULL; - long length = 0; + string_file thetype; PyObject *result; 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); } 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. */ @@ -1086,16 +1032,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); @@ -1114,8 +1059,6 @@ save_objfile_types (struct objfile *objfile, void *datum) } htab_delete (copied_types); - - do_cleanups (cleanup); } static void @@ -1127,7 +1070,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); @@ -1197,10 +1141,9 @@ 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; @@ -1216,7 +1159,7 @@ 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)) + if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0)) { return convert_field (type, i); }