/* Python interface to types.

   Copyright (C) 2008-2012 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "value.h"
#include "exceptions.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 "bcache.h"
#include "dwarf2loc.h"

typedef struct pyty_type_object
{
  PyObject_HEAD
  struct type *type;

  /* If a Type object is associated with an objfile, it is kept on a
     doubly-linked list, rooted in the objfile.  This lets us copy the
     underlying struct type when the objfile is deleted.  */
  struct pyty_type_object *prev;
  struct pyty_type_object *next;
} type_object;

static PyTypeObject type_object_type;

/* A Field object.  */
typedef struct pyty_field_object
{
  PyObject_HEAD

  /* Dictionary holding our attributes.  */
  PyObject *dict;
} field_object;

static PyTypeObject field_object_type;

/* A type iterator object.  */
typedef struct {
  PyObject_HEAD
  /* The current field index.  */
  int field;
  /* What to return.  */
  enum gdbpy_iter_kind kind;
  /* Pointer back to the original source type object.  */
  struct pyty_type_object *source;
} typy_iterator_object;

static PyTypeObject type_iterator_object_type;

/* This is used to initialize various gdb.TYPE_ constants.  */
struct pyty_code
{
  /* The code.  */
  enum type_code code;
  /* The name.  */
  const char *name;
};

/* Forward declarations.  */
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_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_BITSTRING),
  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);
  f->ob_type->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;
}



/* Return the code for this type.  */
static PyObject *
typy_get_code (PyObject *self, void *closure)
{
  struct type *type = ((type_object *) self)->type;

  return PyInt_FromLong (TYPE_CODE (type));
}

/* Helper function for typy_fields which converts a single field to a
   gdb.Field object.  Returns NULL on error.  */

static PyObject *
convert_field (struct type *type, int field)
{
  PyObject *result = field_new ();
  PyObject *arg;

  if (!result)
    return NULL;

  if (!field_is_static (&TYPE_FIELD (type, field)))
    {
      arg = PyLong_FromLong (TYPE_FIELD_BITPOS (type, field));
      if (!arg)
	goto fail;

      if (PyObject_SetAttrString (result, "bitpos", arg) < 0)
	goto failarg;
    }

  if (TYPE_FIELD_NAME (type, field))
    arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
  else
    {
      arg = Py_None;
      Py_INCREF (arg);
    }
  if (!arg)
    goto fail;
  if (PyObject_SetAttrString (result, "name", arg) < 0)
    goto failarg;

  arg = TYPE_FIELD_ARTIFICIAL (type, field) ? Py_True : Py_False;
  Py_INCREF (arg);
  if (PyObject_SetAttrString (result, "artificial", arg) < 0)
    goto failarg;

  if (TYPE_CODE (type) == TYPE_CODE_CLASS)
    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;

  arg = PyLong_FromLong (TYPE_FIELD_BITSIZE (type, field));
  if (!arg)
    goto fail;
  if (PyObject_SetAttrString (result, "bitsize", arg) < 0)
    goto failarg;

  /* A field can have a NULL type in some situations.  */
  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;

  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 *
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;
}

/* Helper function for Type standard mapping methods.  Returns a
   Python object for field i of the type.  "kind" specifies what to
   return: the name of the field, a gdb.Field object corresponding to
   the field, or a tuple consisting of field name and gdb.Field
   object.  */

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;
    }
  return item;
  
 fail:
  Py_XDECREF (key);
  Py_XDECREF (value);
  Py_XDECREF (item);
  return NULL;
}

/* Return a sequence of all field names, fields, or (name, field) pairs.
   Each field is a gdb.Field object.  */

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)
    {
      /* 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);
    }

  return result;
}

/* Return a sequence of all fields.  Each field is a gdb.Field object.  */

static PyObject *
typy_values (PyObject *self, PyObject *args)
{
  return typy_fields_items (self, iter_values);
}

/* Return a sequence of all fields.  Each field is a gdb.Field object.
   This method is similar to typy_values, except where the supplied 
   gdb.Type is an array, in which case it returns a list of one entry
   which is a gdb.Field object for a range (the array bounds).  */

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);

  /* 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);
  if (r == NULL)
    return NULL;
  
  rl = Py_BuildValue ("[O]", r);
  if (rl == NULL)
    {
      Py_DECREF (r);
    }

  return rl;
}

/* Return a sequence of all field names.  Each field is a gdb.Field object.  */

static PyObject *
typy_field_names (PyObject *self, PyObject *args)
{
  return typy_fields_items (self, iter_keys);
}

/* Return a sequence of all (name, fields) pairs.  Each field is a 
   gdb.Field object.  */

static PyObject *
typy_items (PyObject *self, PyObject *args)
{
  return typy_fields_items (self, iter_items);
}

/* Return the type's tag, or None.  */
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));
}

/* Return the type, stripped of typedefs. */
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 (check_typedef (type));
}

/* Strip typedefs and pointers/reference from a type.  Then check that
   it is a struct, union, or enum type.  If not, raise TypeError.  */

static struct type *
typy_get_composite (struct type *type)
{
  volatile struct gdb_exception except;

  for (;;)
    {
      TRY_CATCH (except, RETURN_MASK_ALL)
	{
	  CHECK_TYPEDEF (type);
	}
      /* Don't use GDB_PY_HANDLE_EXCEPTION here because that returns
	 a (NULL) pointer of the wrong type.  */
      if (except.reason < 0)
	{
	  gdbpy_convert_exception (except);
	  return NULL;
	}

      if (TYPE_CODE (type) != TYPE_CODE_PTR
	  && TYPE_CODE (type) != TYPE_CODE_REF)
	break;
      type = TYPE_TARGET_TYPE (type);
    }

  /* If this is not a struct, union, or enum type, raise TypeError
     exception.  */
  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;
}

/* Return an array type.  */

static PyObject *
typy_array (PyObject *self, PyObject *args)
{
  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)
    {
      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);
    }
  GDB_PY_HANDLE_EXCEPTION (except);

  return type_to_type_object (array);
}

/* Return a Type object which represents a pointer to SELF.  */
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);
}

/* Return the range of a type represented by SELF.  The return type is
   a tuple.  The first element of the tuple contains the low bound,
   while the second element of the tuple contains the high bound.  */
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;

  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;
}

/* Return a Type object which represents a reference to SELF.  */
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);
}

/* Return a Type object which represents the target type of SELF.  */
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));
}

/* Return a const-qualified type variant.  */
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);
}

/* Return a volatile-qualified type variant.  */
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);
}

/* Return an unqualified type variant.  */
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);
}

/* Return the size of the type represented by SELF, in bytes.  */
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);
    }
  /* Ignore exceptions.  */

  return PyLong_FromLong (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);
    }
  if (except.reason < 0)
    {
      gdbpy_convert_exception (except);
      return NULL;
    }

  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;

  /* Save the type: typy_lookup_type() may (indirectly) overwrite
     memory pointed by demangled.  */
  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)
	{
	  /* If the demangled_type matches with one of the types
	     below, run the corresponding function and save the type
	     to return later.  We cannot just return here as we are in
	     an exception handler.  */
	  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;
	    }
	}
      if (except.reason < 0)
	{
	  gdbpy_convert_exception (except);
	  return NULL;
	}
    }
  
  /* If we have a type from the switch statement above, just return
     that.  */
  if (rtype)
    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;
}

/* This is a helper function for typy_template_argument that is used
   when the type does not have template symbols attached.  It works by
   parsing the type name.  This happens with compilers, like older
   versions of GCC, that do not emit DW_TAG_template_*.  */

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)
    {
      /* Note -- this is not thread-safe.  */
      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);

  /* Strip off component names.  */
  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;
    }

  /* Skip from the template to the arguments.  */
  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);

  /* 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 --
     but that is going to wind up as an error anyhow.  */
  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);

      type_print (type_object_to_type (self), "", stb, -1);

      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;
}

/* An entry in the type-equality bcache.  */

typedef struct type_equality_entry
{
  struct type *type1, *type2;
} type_equality_entry_d;

DEF_VEC_O (type_equality_entry_d);

/* A helper function to compare two strings.  Returns 1 if they are
   the same, 0 otherwise.  Handles NULLs properly.  */

static int
compare_maybe_null_strings (const char *s, const char *t)
{
  if (s == NULL && t != NULL)
    return 0;
  else if (s != NULL && t == NULL)
    return 0;
  else if (s == NULL && t== NULL)
    return 1;
  return strcmp (s, t) == 0;
}

/* A helper function for typy_richcompare that checks two types for
   "deep" equality.  Returns Py_EQ if the types are considered the
   same, Py_NE otherwise.  */

static int
check_types_equal (struct type *type1, struct type *type2,
		   VEC (type_equality_entry_d) **worklist)
{
  CHECK_TYPEDEF (type1);
  CHECK_TYPEDEF (type2);

  if (type1 == type2)
    return Py_EQ;

  if (TYPE_CODE (type1) != TYPE_CODE (type2)
      || TYPE_LENGTH (type1) != TYPE_LENGTH (type2)
      || TYPE_UNSIGNED (type1) != TYPE_UNSIGNED (type2)
      || TYPE_NOSIGN (type1) != TYPE_NOSIGN (type2)
      || TYPE_VARARGS (type1) != TYPE_VARARGS (type2)
      || TYPE_VECTOR (type1) != TYPE_VECTOR (type2)
      || TYPE_NOTTEXT (type1) != TYPE_NOTTEXT (type2)
      || TYPE_INSTANCE_FLAGS (type1) != TYPE_INSTANCE_FLAGS (type2)
      || TYPE_NFIELDS (type1) != TYPE_NFIELDS (type2))
    return Py_NE;

  if (!compare_maybe_null_strings (TYPE_TAG_NAME (type1),
				   TYPE_TAG_NAME (type2)))
    return Py_NE;
  if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
    return Py_NE;

  if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
    {
      if (memcmp (TYPE_RANGE_DATA (type1), TYPE_RANGE_DATA (type2),
		  sizeof (*TYPE_RANGE_DATA (type1))) != 0)
	return Py_NE;
    }
  else
    {
      int i;

      for (i = 0; i < TYPE_NFIELDS (type1); ++i)
	{
	  const struct field *field1 = &TYPE_FIELD (type1, i);
	  const struct field *field2 = &TYPE_FIELD (type2, i);
	  struct type_equality_entry entry;

	  if (FIELD_ARTIFICIAL (*field1) != FIELD_ARTIFICIAL (*field2)
	      || FIELD_BITSIZE (*field1) != FIELD_BITSIZE (*field2)
	      || FIELD_LOC_KIND (*field1) != FIELD_LOC_KIND (*field2))
	    return Py_NE;
	  if (!compare_maybe_null_strings (FIELD_NAME (*field1),
					   FIELD_NAME (*field2)))
	    return Py_NE;
	  switch (FIELD_LOC_KIND (*field1))
	    {
	    case FIELD_LOC_KIND_BITPOS:
	      if (FIELD_BITPOS (*field1) != FIELD_BITPOS (*field2))
		return Py_NE;
	      break;
	    case FIELD_LOC_KIND_PHYSADDR:
	      if (FIELD_STATIC_PHYSADDR (*field1)
		  != FIELD_STATIC_PHYSADDR (*field2))
		return Py_NE;
	      break;
	    case FIELD_LOC_KIND_PHYSNAME:
	      if (!compare_maybe_null_strings (FIELD_STATIC_PHYSNAME (*field1),
					       FIELD_STATIC_PHYSNAME (*field2)))
		return Py_NE;
	      break;
	    case FIELD_LOC_KIND_DWARF_BLOCK:
	      {
		struct dwarf2_locexpr_baton *block1, *block2;

		block1 = FIELD_DWARF_BLOCK (*field1);
		block2 = FIELD_DWARF_BLOCK (*field2);
		if (block1->per_cu != block2->per_cu
		    || block1->size != block2->size
		    || memcmp (block1->data, block2->data, block1->size) != 0)
		return Py_NE;
	      }
	      break;
	    default:
	      internal_error (__FILE__, __LINE__, _("Unsupported field kind "
						    "%d by check_types_equal"),
			      FIELD_LOC_KIND (*field1));
	    }

	  entry.type1 = FIELD_TYPE (*field1);
	  entry.type2 = FIELD_TYPE (*field2);
	  VEC_safe_push (type_equality_entry_d, *worklist, &entry);
	}
    }

  if (TYPE_TARGET_TYPE (type1) != NULL)
    {
      struct type_equality_entry entry;
      int added;

      if (TYPE_TARGET_TYPE (type2) == NULL)
	return Py_NE;

      entry.type1 = TYPE_TARGET_TYPE (type1);
      entry.type2 = TYPE_TARGET_TYPE (type2);
      VEC_safe_push (type_equality_entry_d, *worklist, &entry);
    }
  else if (TYPE_TARGET_TYPE (type2) != NULL)
    return Py_NE;

  return Py_EQ;
}

/* Check types on a worklist for equality.  Returns Py_NE if any pair
   is not equal, Py_EQ if they are all considered equal.  */

static int
check_types_worklist (VEC (type_equality_entry_d) **worklist,
		      struct bcache *cache)
{
  while (!VEC_empty (type_equality_entry_d, *worklist))
    {
      struct type_equality_entry entry;
      int added;

      entry = *VEC_last (type_equality_entry_d, *worklist);
      VEC_pop (type_equality_entry_d, *worklist);

      /* If the type pair has already been visited, we know it is
	 ok.  */
      bcache_full (&entry, sizeof (entry), cache, &added);
      if (!added)
	continue;

      if (check_types_equal (entry.type1, entry.type2, worklist) == Py_NE)
	return Py_NE;
    }

  return Py_EQ;
}

/* Implement the richcompare method.  */

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;

  /* We can only compare ourselves to another Type object, and only
     for equality or inequality.  */
  if (type2 == NULL || (op != Py_EQ && op != Py_NE))
    {
      Py_INCREF (Py_NotImplemented);
      return Py_NotImplemented;
    }

  if (type1 == type2)
    result = Py_EQ;
  else
    {
      struct bcache *cache;
      VEC (type_equality_entry_d) *worklist = NULL;
      struct type_equality_entry entry;

      cache = bcache_xmalloc (NULL, NULL);

      entry.type1 = type1;
      entry.type2 = type2;
      VEC_safe_push (type_equality_entry_d, worklist, &entry);

      TRY_CATCH (except, RETURN_MASK_ALL)
	{
	  result = check_types_worklist (&worklist, cache);
	}
      /* check_types_worklist calls several nested Python helper
	 functions, some of which can raise a GDB Exception, so we
	 just check and convert here.  If there is a GDB exception, a
	 comparison is not capable (or trusted), so exit.  */
      bcache_xfree (cache);
      VEC_free (type_equality_entry_d, worklist);
      GDB_PY_HANDLE_EXCEPTION (except);
    }

  if (op == result)
    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;

  /* This prevents another thread from freeing the objects we're
     operating on.  */
  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))
    {
      /* Must reset head of list.  */
      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;

  type->ob_type->tp_free (type);
}

/* Return number of fields ("length" of the field dictionary).  */

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);
}

/* Implements boolean evaluation of gdb.Type.  Handle this like other
   Python objects that don't have a meaningful truth value -- all 
   values are true.  */

static int
typy_nonzero (PyObject *self)
{
  return 1;
}

/* 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;
  volatile struct gdb_exception except;

  field = python_string_to_host_string (key);
  if (field == NULL)
    return NULL;

  /* We want just fields of this type, not of base types, so instead of 
     using lookup_struct_elt_type, portions of that function are
     copied here.  */

  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;
}

/* Implement the "get" method on the type object.  This is the 
   same as getitem if the key is present, but returns the supplied
   default value or None if the key is not found.  */

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;
  
  /* typy_getitem returned error status.  If the exception is
     KeyError, clear the exception status and return the defval
     instead.  Otherwise return the exception unchanged.  */
  if (!PyErr_ExceptionMatches (PyExc_KeyError))
    return NULL;
  
  PyErr_Clear ();
  Py_INCREF (defval);
  return defval;
}

/* Implement the "has_key" method on the type object.  */

static PyObject *
typy_has_key (PyObject *self, PyObject *args)
{
  struct type *type = ((type_object *) self)->type;
  const char *field;
  int i;
  volatile struct gdb_exception except;

  if (!PyArg_ParseTuple (args, "s", &field))
    return NULL;

  /* We want just fields of this type, not of base types, so instead of 
     using lookup_struct_elt_type, portions of that function are
     copied here.  */

  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;
}

/* Make an iterator object to iterate over keys, values, or items.  */

static PyObject *
typy_make_iter (PyObject *self, enum gdbpy_iter_kind kind)
{
  typy_iterator_object *typy_iter_obj;

  /* Check that "self" is a structure or union type.  */
  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;
}

/* iteritems() method.  */

static PyObject *
typy_iteritems (PyObject *self, PyObject *args)
{
  return typy_make_iter (self, iter_items);
}

/* iterkeys() method.  */

static PyObject *
typy_iterkeys (PyObject *self, PyObject *args)
{
  return typy_make_iter (self, iter_keys);
}

/* Iterating over the class, same as iterkeys except for the function
   signature.  */

static PyObject *
typy_iter (PyObject *self)
{
  return typy_make_iter (self, iter_keys);
}

/* itervalues() method.  */

static PyObject *
typy_itervalues (PyObject *self, PyObject *args)
{
  return typy_make_iter (self, iter_values);
}

/* Return a reference to the type iterator.  */

static PyObject *
typy_iterator_iter (PyObject *self)
{
  Py_INCREF (self);
  return self;
}

/* Return the next field in the iteration through the list of fields
   of the type.  */

static PyObject *
typy_iterator_iternext (PyObject *self)
{
  typy_iterator_object *iter_obj = (typy_iterator_object *) self;
  struct type *type = iter_obj->source->type;
  int i;
  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);
}

/* Create a new Type referring to TYPE.  */
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;
}



/* Implementation of gdb.lookup_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);
}

void
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;
  if (PyType_Ready (&field_object_type) < 0)
    return;
  if (PyType_Ready (&type_iterator_object_type) < 0)
    return;

  for (i = 0; pyty_codes[i].name; ++i)
    {
      if (PyModule_AddIntConstant (gdb_module,
				   /* Cast needed for Python 2.4.  */
				   (char *) pyty_codes[i].name,
				   pyty_codes[i].code) < 0)
	return;
    }

  Py_INCREF (&type_object_type);
  PyModule_AddObject (gdb_module, "Type", (PyObject *) &type_object_type);

  Py_INCREF (&type_iterator_object_type);
  PyModule_AddObject (gdb_module, "TypeIterator",
		      (PyObject *) &type_iterator_object_type);

  Py_INCREF (&field_object_type);
  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 },
  { "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." },
   { "__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,			      /* nb_add */
  NULL,			      /* nb_subtract */
  NULL,			      /* nb_multiply */
  NULL,			      /* nb_divide */
  NULL,			      /* nb_remainder */
  NULL,			      /* nb_divmod */
  NULL,			      /* nb_power */
  NULL,			      /* nb_negative */
  NULL,			      /* nb_positive */
  NULL,			      /* nb_absolute */
  typy_nonzero,		      /* nb_nonzero */
  NULL,			      /* nb_invert */
  NULL,			      /* nb_lshift */
  NULL,			      /* nb_rshift */
  NULL,			      /* nb_and */
  NULL,			      /* nb_xor */
  NULL,			      /* nb_or */
  NULL,			      /* nb_coerce */
  NULL,			      /* nb_int */
  NULL,			      /* nb_long */
  NULL,			      /* nb_float */
  NULL,			      /* nb_oct */
  NULL			      /* nb_hex */
};

static PyMappingMethods typy_mapping = {
  typy_length,
  typy_getitem,
  NULL				  /* no "set" method */
};

static PyTypeObject type_object_type =
{
  PyObject_HEAD_INIT (NULL)
  0,				  /*ob_size*/
  "gdb.Type",			  /*tp_name*/
  sizeof (type_object),		  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  typy_dealloc,			  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  0,				  /*tp_repr*/
  &type_object_as_number,	  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  &typy_mapping,		  /*tp_as_mapping*/
  0,				  /*tp_hash */
  0,				  /*tp_call*/
  typy_str,			  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
  "GDB type object",		  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  typy_richcompare,		  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  typy_iter,			  /* tp_iter */
  0,				  /* tp_iternext */
  type_object_methods,		  /* tp_methods */
  0,				  /* tp_members */
  type_object_getset,		  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  0,				  /* tp_dictoffset */
  0,				  /* tp_init */
  0,				  /* tp_alloc */
  0,				  /* tp_new */
};

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 =
{
  PyObject_HEAD_INIT (NULL)
  0,				  /*ob_size*/
  "gdb.Field",			  /*tp_name*/
  sizeof (field_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  field_dealloc,		  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  0,				  /*tp_repr*/
  0,				  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  0,				  /*tp_as_mapping*/
  0,				  /*tp_hash */
  0,				  /*tp_call*/
  0,				  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
  "GDB field object",		  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  0,				  /* tp_methods */
  0,				  /* tp_members */
  field_object_getset,		  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  offsetof (field_object, dict),  /* tp_dictoffset */
  0,				  /* tp_init */
  0,				  /* tp_alloc */
  0,				  /* tp_new */
};

static PyTypeObject type_iterator_object_type = {
  PyObject_HEAD_INIT (NULL)
  0,				  /*ob_size*/
  "gdb.TypeIterator",		  /*tp_name*/
  sizeof (typy_iterator_object),  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  typy_iterator_dealloc,	  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  0,				  /*tp_repr*/
  0,				  /*tp_as_number*/
  0,				  /*tp_as_sequence*/
  0,				  /*tp_as_mapping*/
  0,				  /*tp_hash */
  0,				  /*tp_call*/
  0,				  /*tp_str*/
  0,				  /*tp_getattro*/
  0,				  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER,  /*tp_flags*/
  "GDB type iterator object",	  /*tp_doc */
  0,				  /*tp_traverse */
  0,				  /*tp_clear */
  0,				  /*tp_richcompare */
  0,				  /*tp_weaklistoffset */
  typy_iterator_iter,             /*tp_iter */
  typy_iterator_iternext,	  /*tp_iternext */
  0				  /*tp_methods */
};
