]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/python/py-type.c
Update copyright year range in all GDB files.
[thirdparty/binutils-gdb.git] / gdb / python / py-type.c
index e202c83732dc9038ca167aebdc0e1793ea004c8f..b19cad098a46410262080cd2b1aaa8f8f1729ea6 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to types.
 
-   Copyright (C) 2008-2015 Free Software Foundation, Inc.
+   Copyright (C) 2008-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -26,7 +26,6 @@
 #include "demangle.h"
 #include "objfiles.h"
 #include "language.h"
-#include "vec.h"
 #include "typeprint.h"
 
 typedef struct pyty_type_object
@@ -105,6 +104,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 +129,16 @@ field_dealloc (PyObject *obj)
 static PyObject *
 field_new (void)
 {
-  field_object *result = PyObject_New (field_object, &field_object_type);
+  gdbpy_ref<field_object> 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 ();
 }
 
 \f
@@ -165,21 +163,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 +183,87 @@ 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 (), 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);
+
+  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 = 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 +273,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,36 +308,31 @@ static PyObject *
 typy_fields_items (PyObject *self, enum gdbpy_iter_kind kind)
 {
   PyObject *py_type = self;
-  PyObject *result = NULL, *iter = NULL;
   struct type *type = ((type_object *) py_type)->type;
   struct type *checked_type = type;
 
-  TRY
+  try
     {
       checked_type = check_typedef (checked_type);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
+  gdbpy_ref<> type_holder;
   if (checked_type != type)
-    py_type = type_to_type_object (checked_type);
-  iter = typy_make_iter (py_type, kind);
-  if (checked_type != type)
-    {
-      /* Need to wrap this in braces because Py_DECREF isn't wrapped
-        in a do{}while(0).  */
-      Py_DECREF (py_type);
-    }
-  if (iter != NULL)
     {
-      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.  */
@@ -389,7 +352,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 +359,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.  */
@@ -441,10 +400,28 @@ 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's objfile, or None.  */
+static PyObject *
+typy_get_objfile (PyObject *self, void *closure)
+{
+  struct type *type = ((type_object *) self)->type;
+  struct objfile *objfile = TYPE_OBJFILE (type);
+
+  if (objfile == nullptr)
+    Py_RETURN_NONE;
+  return objfile_to_objfile_object (objfile).release ();
 }
 
 /* Return the type, stripped of typedefs. */
@@ -453,15 +430,14 @@ typy_strip_typedefs (PyObject *self, PyObject *args)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
       type = check_typedef (type);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (type);
 }
@@ -475,18 +451,16 @@ typy_get_composite (struct type *type)
 
   for (;;)
     {
-      TRY
+      try
        {
          type = check_typedef (type);
        }
-      CATCH (except, RETURN_MASK_ALL)
+      catch (const gdb_exception &except)
        {
          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);
     }
@@ -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;
     }
 
@@ -543,17 +518,16 @@ typy_array_1 (PyObject *self, PyObject *args, int is_vector)
       return NULL;
     }
 
-  TRY
+  try
     {
       array = lookup_array_range_type (type, n1, n2);
       if (is_vector)
        make_vector_type (array);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (array);
 }
@@ -580,15 +554,14 @@ typy_pointer (PyObject *self, PyObject *args)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
       type = lookup_pointer_type (type);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (type);
 }
@@ -600,8 +573,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 +598,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.  */
@@ -664,15 +622,14 @@ typy_reference (PyObject *self, PyObject *args)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
-      type = lookup_reference_type (type);
+      type = lookup_lvalue_reference_type (type);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (type);
 }
@@ -699,15 +656,14 @@ typy_const (PyObject *self, PyObject *args)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
       type = make_cv_type (1, 0, type, NULL);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (type);
 }
@@ -718,15 +674,14 @@ typy_volatile (PyObject *self, PyObject *args)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
       type = make_cv_type (0, 1, type, NULL);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (type);
 }
@@ -737,15 +692,14 @@ typy_unqualified (PyObject *self, PyObject *args)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
       type = make_cv_type (0, 0, type, NULL);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type_to_type_object (type);
 }
@@ -756,26 +710,46 @@ typy_get_sizeof (PyObject *self, void *closure)
 {
   struct type *type = ((type_object *) self)->type;
 
-  TRY
+  try
     {
       check_typedef (type);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
     }
-  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 (const gdb_exception &except)
+    {
+      align = 0;
+    }
+
+  /* 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;
 
-  TRY
+  try
     {
       if (startswith (type_name, "struct "))
        type = lookup_struct (type_name + 7, NULL);
@@ -784,14 +758,13 @@ typy_lookup_typename (const char *type_name, const struct block *block)
       else if (startswith (type_name, "enum "))
        type = lookup_enum (type_name + 5, NULL);
       else
-       type = lookup_typename (python_language, python_gdbarch,
+       type = lookup_typename (python_language,
                                type_name, block, 0);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return type;
 }
@@ -801,7 +774,6 @@ 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;
 
   /* Save the type: typy_lookup_type() may (indirectly) overwrite
@@ -810,6 +782,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)
     {
@@ -817,7 +790,7 @@ typy_lookup_type (struct demangle_component *demangled,
       if (! type)
        return NULL;
 
-      TRY
+      try
        {
          /* If the demangled_type matches with one of the types
             below, run the corresponding function and save the type
@@ -826,7 +799,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);
@@ -839,11 +815,10 @@ typy_lookup_type (struct demangle_component *demangled,
              break;
            }
        }
-      CATCH (except, RETURN_MASK_ALL)
+      catch (const gdb_exception &except)
        {
          GDB_PY_HANDLE_EXCEPTION (except);
        }
-      END_CATCH
     }
 
   /* If we have a type from the switch statement above, just return
@@ -852,11 +827,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<char> 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
@@ -870,10 +842,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<demangle_parse_info> info;
+  std::string err;
   struct type *argtype;
-  struct cleanup *cleanup;
 
   if (TYPE_NAME (type) == NULL)
     {
@@ -881,24 +852,22 @@ typy_legacy_template_argument (struct type *type, const struct block *block,
       return NULL;
     }
 
-  TRY
+  try
     {
       /* Note -- this is not thread-safe.  */
       info = cp_demangled_name_to_comp (TYPE_NAME (type), &err);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       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
@@ -907,7 +876,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 +888,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;
 
@@ -947,6 +913,13 @@ typy_template_argument (PyObject *self, PyObject *args)
   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);
@@ -958,17 +931,16 @@ typy_template_argument (PyObject *self, PyObject *args)
        }
     }
 
-  TRY
+  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)
+  catch (const gdb_exception &except)
     {
       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 --
@@ -993,15 +965,14 @@ typy_template_argument (PyObject *self, PyObject *args)
       return NULL;
     }
 
-  TRY
+  try
     {
       val = value_of_variable (sym, block);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception &except)
     {
       GDB_PY_HANDLE_EXCEPTION (except);
     }
-  END_CATCH
 
   return value_to_value_object (val);
 }
@@ -1009,35 +980,20 @@ typy_template_argument (PyObject *self, PyObject *args)
 static PyObject *
 typy_str (PyObject *self)
 {
-  char *thetype = NULL;
-  long length = 0;
-  PyObject *result;
+  string_file thetype;
 
-  TRY
+  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)
+  catch (const gdb_exception &except)
     {
-      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.  */
@@ -1045,7 +1001,7 @@ 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);
 
@@ -1058,20 +1014,19 @@ typy_richcompare (PyObject *self, PyObject *other, int op)
     }
 
   if (type1 == type2)
-    result = Py_EQ;
+    result = true;
   else
     {
-      TRY
+      try
        {
          result = types_deeply_equal (type1, type2);
        }
-      CATCH (except, RETURN_MASK_ALL)
+      catch (const gdb_exception &except)
        {
          /* 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))
@@ -1086,16 +1041,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 +1068,6 @@ save_objfile_types (struct objfile *objfile, void *datum)
     }
 
   htab_delete (copied_types);
-
-  do_cleanups (cleanup);
 }
 
 static void
@@ -1127,7 +1079,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 +1150,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<char> field = python_string_to_host_string (key);
   if (field == NULL)
     return NULL;
 
@@ -1216,10 +1168,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;
@@ -1356,14 +1306,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;
@@ -1375,6 +1325,7 @@ typy_iterator_dealloc (PyObject *obj)
   typy_iterator_object *iter_obj = (typy_iterator_object *) obj;
 
   Py_DECREF (iter_obj->source);
+  Py_TYPE (obj)->tp_free (obj);
 }
 
 /* Create a new Type referring to TYPE.  */
@@ -1383,6 +1334,17 @@ type_to_type_object (struct type *type)
 {
   type_object *type_obj;
 
+  try
+    {
+      /* Try not to let stub types leak out to Python.  */
+      if (TYPE_STUB (type))
+       type = check_typedef (type);
+    }
+  catch (...)
+    {
+      /* Just ignore failures in check_typedef.  */
+    }
+
   type_obj = PyObject_New (type_object, &type_object_type);
   if (type_obj)
     set_type (type_obj, type);
@@ -1404,14 +1366,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)
@@ -1429,7 +1391,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
@@ -1449,9 +1411,7 @@ gdbpy_initialize_types (void)
 
   for (i = 0; pyty_codes[i].name; ++i)
     {
-      if (PyModule_AddIntConstant (gdb_module,
-                                  /* Cast needed for Python 2.4.  */
-                                  (char *) pyty_codes[i].name,
+      if (PyModule_AddIntConstant (gdb_module, pyty_codes[i].name,
                                   pyty_codes[i].code) < 0)
        return -1;
     }
@@ -1470,8 +1430,10 @@ gdbpy_initialize_types (void)
 
 \f
 
-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,
@@ -1480,6 +1442,8 @@ static PyGetSetDef type_object_getset[] =
     "The size of this type, in bytes.", NULL },
   { "tag", typy_get_tag, NULL,
     "The tag name for this type, or None.", NULL },
+  { "objfile", typy_get_objfile, NULL,
+    "The objfile this type was defined in, or None.", NULL },
   { NULL }
 };
 
@@ -1644,7 +1608,7 @@ 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 },