This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[python] changes to Type and Value


This updates Type and Value to follow requests made upstream.

Thiago, I only changed a couple of Type's method to attributes.
Most of them, I think, are better as methods -- even when they have no
arguments and perhaps cannot even throw an exception.

Jan, we would like this to go into Fedora, to reduce API divergence.
However, it might be better to hold off on merging this a little
while, in case more changes are requested, or in case we find bugs.

I'm seeing a couple failures in the python test suite.
I have not debugged them yet; at least one is a gdb crash which I
believe was fixed by a patch that has been around a couple times... I
will try to find out.

Tom

2009-04-07  Tom Tromey  <tromey@redhat.com>

	* python/python.c (GdbMethods): Add "lookup_type".
	* python/python-internal.h (gdbpy_lookup_type): Declare.
	* python/lib/gdb/libstdcxx/v6/printers.py: Update.
	* python/lib/gdb/command/pahole.py: Update.
	* python/python-value.c (value_object) <type>: New field.
	(valpy_dealloc): Destroy type.
	(valpy_new): Initialize new field.
	(valpy_get_type): Rename.  Now a getter.
	(value_to_value_object): Initialize new field.
	(value_object_getset): Add "type".
	(value_object_methods): Remove "type".
	* python/python-type.c (field_dealloc): Call tp_free.
	(typy_lookup_typename): Use GDB_PY_HANDLE_EXCEPTION.
	(typy_new): Make name argument mandatory.
	(typy_get_code): Rename.  Now a getter.
	(typy_get_tag): Likewise.
	(typy_get_sizeof): Likewise.  Don't throw an exception.
	(type_object_getset): New global.
	(type_object_type): Use it.
	(type_object_methods): Remove getters.
	(gdbpy_lookup_type): Move.  Rename from typy_new.

2009-04-07  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Types In Python): Rename and update.
	(Values From Inferior): "type" is now an attribute.

2009-04-07  Tom Tromey  <tromey@redhat.com>

	* gdb.python/python-value.exp: Update.
	* gdb.python/python-template.exp: Update.
	* gdb.python/python-prettyprint.py: Update.
	* gdb.python/find.exp: Update.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 4c92495..8b1b944 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18135,7 +18135,7 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown.
 * Exception Handling::
 * Auto-loading::                Automatically loading Python code.
 * Values From Inferior::	Python representation of values.
-* Types From Inferior::		Python representation of types.
+* Types In Python::		Python representation of types.
 * Pretty Printing::		Pretty-printing values.
 * Threads In Python::           Accessing inferior threads from Python.
 * Commands In Python::          Implementing new commands in Python.
@@ -18393,17 +18393,22 @@ Again, @code{bar} will also be a @code{gdb.Value} object.
 The following attributes are provided:
 
 @table @code
-@defmethod Value address
+@defivar Value address
 If this object is addressable, this read-only attribute holds a
 @code{gdb.Value} object representing the address.  Otherwise,
 this attribute holds @code{None}.
-@end defmethod
+@end defivar
 
 @cindex optimized out value in Python
-@defmethod Value is_optimized_out
+@defivar Value is_optimized_out
 This read-only boolean attribute is true if the compiler optimized out
 this value, thus it is not available for fetching from the inferior.
-@end defmethod
+@end defivar
+
+@defivar Value type
+The type of this @code{gdb.Value}.  The result is a @code{gdb.Type}
+object.
+@end defivar
 @end table
 
 The following methods are provided:
@@ -18463,43 +18468,62 @@ will be used, if the current language is able to supply one.
 The optional @var{errors} argument is the same as the corresponding
 argument to Python's @code{string.decode} method.
 @end defmethod
-
-@defmethod Value type
-Return the type of this @code{gdb.Value}.  The result is a
-@code{gdb.Type} object.
-@end defmethod
 @end table
 
-@node Types From Inferior
-@subsubsection Types From Inferior
+@node Types In Python
+@subsubsection Types In Python
+@cindex types in Python
+@cindex Python, working with types
 
-@cindex gdb.Type
+@tindex gdb.Type
 @value{GDBN} represents types from the inferior using the class
 @code{gdb.Type}.
 
-The following methods are provided:
-
-@table @code
-@defmethod Type Type [name [block]]
-Construct a new instance of @code{gdb.Type}.
+The following type-related functions are available in the @code{gdb}
+module:
 
-If @var{name} is given, it specifies the name of a type to look up in
-the inferior.
+@findex gdb.lookup_type
+@defun lookup_type name [block]
+This function looks up a type by name.  @var{name} is the name of the
+type to look up.  It must be a string.
 
 If @var{block} is given, then @var{name} is looked up in that scope.
 Otherwise, it is searched for globally.
-@end defmethod
 
-@defmethod Type code
-Return the type code for this type.  The type code will be one of the
+Ordinarily, this function will return an instance of @code{gdb.Type}.
+If the named type cannot be found, it will throw an exception.
+@end defun
+
+An instance of @code{Type} has the following attributes:
+
+@table @code
+@defivar Type code
+The type code for this type.  The type code will be one of the
 @code{TYPE_CODE_} constants defined below.
-@end defmethod
+@end defivar
 
+@defivar Type sizeof
+The size of this type, in target @code{char} units.  Usually, a
+target's @code{char} type will be an 8-bit byte.  However, on some
+unusual platforms, this type may have a different size.
+@end defivar
+
+@defivar Type tag
+The tag name for this type.  The tag name is the name after
+@code{struct}, @code{union}, or @code{enum} in C; not all languages
+have this concept.  If this type has no tag name, then @code{None} is
+returned.
+@end defivar
+@end table
+
+The following methods are provided:
+
+@table @code
 @defmethod Type fields
 For structure and union types, this method returns the fields.  Range
 types have two fields, the minimum and maximum values.  Enum types
 have one field per enum constant.  Function and method types have one
-field per parameter.  The base types of C++ classes are also
+field per parameter.  The base types of C@t{++} classes are also
 represented as fields.  If the type has no fields, or does not fit
 into one of these categories, an empty sequence will be returned.
 
@@ -18549,24 +18573,11 @@ Return a new @code{gdb.Type} object which represents a reference to this
 type.
 @end defmethod
 
-@defmethod Type sizeof
-Return the size of this type, in target @code{char} units.  Usually, a
-target's @code{char} type will be an 8-bit byte.  However, on some
-unusual platforms, this type may have a different size.
-@end defmethod
-
 @defmethod Type strip_typedefs
 Return a new @code{gdb.Type} that represents the real type,
 after removing all layers of typedefs.
 @end defmethod
 
-@defmethod Type tag
-Return the tag name for this type.  The tag name is the name after
-@code{struct}, @code{union}, or @code{enum} in C; not all languages
-have this concept.  If this type has no tag name, then @code{None} is
-returned.
-@end defmethod
-
 @defmethod Type target
 Return a new @code{gdb.Type} object which represents the target type
 of this type.
@@ -18626,8 +18637,7 @@ The type is an enum.
 @findex TYPE_CODE_FLAGS
 @findex gdb.TYPE_CODE_FLAGS
 @item TYPE_CODE_FLAGS
-A bit flags type.
-@c FIXME: what is this?
+A bit flags type, used for things such as status registers.
 
 @findex TYPE_CODE_FUNC
 @findex gdb.TYPE_CODE_FUNC
@@ -18678,7 +18688,7 @@ An unknown or erroneous type.
 @findex TYPE_CODE_METHOD
 @findex gdb.TYPE_CODE_METHOD
 @item TYPE_CODE_METHOD
-A C++ method type.
+A method type, as found in C++ or Java.
 
 @findex TYPE_CODE_METHODPTR
 @findex gdb.TYPE_CODE_METHODPTR
@@ -18715,19 +18725,6 @@ A complex float type.
 @item TYPE_CODE_TYPEDEF
 A typedef to some other type.
 
-@findex TYPE_CODE_TEMPLATE
-@findex gdb.TYPE_CODE_TEMPLATE
-@item TYPE_CODE_TEMPLATE
-A C++ template type.  Note that this is not used for a template
-instantiation; those appear as ordinary struct types.
-@c FIXME I hope that is true
-
-@findex TYPE_CODE_TEMPLATE_ARG
-@findex gdb.TYPE_CODE_TEMPLATE_ARG
-@item TYPE_CODE_TEMPLATE_ARG
-A C++ template argument.
-@c FIXME: is this ever used?
-
 @findex TYPE_CODE_NAMESPACE
 @findex gdb.TYPE_CODE_NAMESPACE
 @item TYPE_CODE_NAMESPACE
diff --git a/gdb/python/lib/gdb/command/pahole.py b/gdb/python/lib/gdb/command/pahole.py
index 569b816..21a0bf0 100644
--- a/gdb/python/lib/gdb/command/pahole.py
+++ b/gdb/python/lib/gdb/command/pahole.py
@@ -1,6 +1,6 @@
 # pahole command for gdb
 
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
 # 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
@@ -26,16 +26,10 @@ It prints the type and displays comments showing where holes are."""
         super (Pahole, self).__init__ ("pahole", gdb.COMMAND_NONE,
                                        gdb.COMPLETE_SYMBOL)
 
-    @staticmethod
-    def strip (type):
-        while type.code () == gdb.TYPE_CODE_TYPEDEF:
-            type = type.target ()
-        return type
-
     def pahole (self, type, level, name):
         if name is None:
             name = ''
-        tag = type.tag ()
+        tag = type.tag
         if tag is None:
             tag = ''
         print '%sstruct %s {' % (' ' * (2 * level), tag)
@@ -45,7 +39,7 @@ It prints the type and displays comments showing where holes are."""
             if not hasattr (field, ('bitpos')):
                 continue
 
-            ftype = self.strip (field.type)
+            ftype = field.type.strip_typedefs()
 
             if bitpos != field.bitpos:
                 hole = field.bitpos - bitpos
@@ -55,13 +49,13 @@ It prints the type and displays comments showing where holes are."""
                 fieldsize = field.bitsize
             else:
                 # TARGET_CHAR_BIT here...
-                fieldsize = 8 * ftype.sizeof ()
+                fieldsize = 8 * ftype.sizeof
 
             # TARGET_CHAR_BIT
             print ' /* %3d %3d */' % (int (bitpos / 8), int (fieldsize / 8)),
             bitpos = bitpos + fieldsize
 
-            if ftype.code () == gdb.TYPE_CODE_STRUCT:
+            if ftype.code == gdb.TYPE_CODE_STRUCT:
                 self.pahole (ftype, level + 1, field.name)
             else:
                 print ' ' * (2 + 2 * level),
@@ -71,9 +65,9 @@ It prints the type and displays comments showing where holes are."""
         print '} %s' % name
 
     def invoke (self, arg, from_tty):
-        type = gdb.Type (arg)
-        type = self.strip (type)
-        if type.code () != gdb.TYPE_CODE_STRUCT:
+        type = gdb.lookup_type (arg)
+        type = type.strip_typedefs ()
+        if type.code != gdb.TYPE_CODE_STRUCT:
             raise TypeError, '%s is not a struct type' % arg
         print ' ' * 14,
         self.pahole (type, 0, '')
diff --git a/gdb/python/lib/gdb/libstdcxx/v6/printers.py b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
index 149f1dd..2bd2593 100644
--- a/gdb/python/lib/gdb/libstdcxx/v6/printers.py
+++ b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
@@ -68,8 +68,8 @@ class StdListPrinter:
         self.val = val
 
     def children(self):
-        itype = self.val.type().template_argument(0)
-        nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer()
+        itype = self.val.type.template_argument(0)
+        nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer()
         return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
 
     def to_string(self):
@@ -84,8 +84,8 @@ class StdListIteratorPrinter:
         self.val = val
 
     def to_string(self):
-        itype = self.val.type().template_argument(0)
-        nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer()
+        itype = self.val.type.template_argument(0)
+        nodetype = gdb.lookup_type('std::_List_node<%s>' % itype).pointer()
         return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
 
 class StdSlistPrinter:
@@ -113,8 +113,8 @@ class StdSlistPrinter:
         self.val = val
 
     def children(self):
-        itype = self.val.type().template_argument(0)
-        nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
+        itype = self.val.type.template_argument(0)
+        nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
         return self._iterator(nodetype, self.val)
 
     def to_string(self):
@@ -129,8 +129,8 @@ class StdSlistIteratorPrinter:
         self.val = val
 
     def to_string(self):
-        itype = self.val.type().template_argument(0)
-        nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
+        itype = self.val.type.template_argument(0)
+        nodetype = gdb.lookup_type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
         return self.val['_M_node'].cast(nodetype).dereference()['_M_data']
 
 class StdVectorPrinter:
@@ -243,8 +243,8 @@ class StdRbtreeIteratorPrinter:
         self.val = val
 
     def to_string (self):
-        valuetype = self.val.type().template_argument(0)
-        nodetype = gdb.Type('std::_Rb_tree_node < %s >' % valuetype)
+        valuetype = self.val.type.template_argument(0)
+        nodetype = gdb.lookup_type('std::_Rb_tree_node < %s >' % valuetype)
         nodetype = nodetype.pointer()
         return self.val.cast(nodetype).dereference()['_M_value_field']
 
@@ -283,9 +283,9 @@ class StdMapPrinter:
         return '%s with %d elements' % (self.typename, len (self.iter))
 
     def children (self):
-        keytype = self.val.type().template_argument(0).const()
-        valuetype = self.val.type().template_argument(1)
-        nodetype = gdb.Type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype))
+        keytype = self.val.type.template_argument(0).const()
+        valuetype = self.val.type.template_argument(1)
+        nodetype = gdb.lookup_type('std::_Rb_tree_node< std::pair< %s, %s > >' % (keytype, valuetype))
         nodetype = nodetype.pointer()
         return self._iter (self.iter, nodetype)
 
@@ -323,8 +323,8 @@ class StdSetPrinter:
         return '%s with %d elements' % (self.typename, len (self.iter))
 
     def children (self):
-        keytype = self.val.type().template_argument(0)
-        nodetype = gdb.Type('std::_Rb_tree_node< %s >' % keytype).pointer()
+        keytype = self.val.type.template_argument(0)
+        nodetype = gdb.lookup_type('std::_Rb_tree_node< %s >' % keytype).pointer()
         return self._iter (self.iter, nodetype)
 
 class StdBitsetPrinter:
@@ -340,18 +340,18 @@ class StdBitsetPrinter:
 
     def children (self):
         words = self.val['_M_w']
-        wtype = words.type()
+        wtype = words.type
 
         # The _M_w member can be either an unsigned long, or an
         # array.  This depends on the template specialization used.
         # If it is a single long, convert to a single element list.
-        if wtype.code () == gdb.TYPE_CODE_ARRAY:
-            tsize = wtype.target ().sizeof ()
+        if wtype.code == gdb.TYPE_CODE_ARRAY:
+            tsize = wtype.target ().sizeof
         else:
             words = [words]
-            tsize = wtype.sizeof () 
+            tsize = wtype.sizeof 
 
-        nwords = wtype.sizeof() / tsize
+        nwords = wtype.sizeof / tsize
         result = []
         byte = 0
         while byte < nwords:
@@ -401,8 +401,8 @@ class StdDequePrinter:
 
     def __init__(self, val):
         self.val = val
-        self.elttype = val.type().template_argument(0)
-        size = self.elttype.sizeof ()
+        self.elttype = val.type.template_argument(0)
+        size = self.elttype.sizeof
         if size < 512:
             self.buffer_size = int (512 / size)
         else:
@@ -573,17 +573,17 @@ def lookup_function (val):
     "Look-up and return a pretty-printer that can print val."
 
     # Get the type.
-    type = val.type ();
+    type = val.type;
 
     # If it points to a reference, get the reference.
-    if type.code () == gdb.TYPE_CODE_REF:
+    if type.code == gdb.TYPE_CODE_REF:
         type = type.target ()
 
     # Get the unqualified type, stripped of typedefs.
     type = type.unqualified ().strip_typedefs ()
 
     # Get the type name.    
-    typename = type.tag ()
+    typename = type.tag
     if typename == None:
         return None
 
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 4aae0aa..5e43267 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -83,6 +83,7 @@ PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
 PyObject *gdbpy_block_for_pc (PyObject *self, PyObject *args);
 PyObject *gdbpy_read_memory (PyObject *self, PyObject *args);
 PyObject *gdbpy_write_memory (PyObject *self, PyObject *args);
+PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
 
 PyObject *symtab_and_line_to_sal_object (struct symtab_and_line sal);
 PyObject *symtab_to_symtab_object (struct symtab *symtab);
diff --git a/gdb/python/python-type.c b/gdb/python/python-type.c
index 2a54556..ec9ec46 100644
--- a/gdb/python/python-type.c
+++ b/gdb/python/python-type.c
@@ -103,6 +103,7 @@ field_dealloc (PyObject *obj)
 {
   field_object *f = (field_object *) obj;
   Py_XDECREF (f->dict);
+  f->ob_type->tp_free (obj);
 }
 
 static PyObject *
@@ -125,7 +126,7 @@ field_new (void)
 
 /* Return the code for this type.  */
 static PyObject *
-typy_code (PyObject *self, PyObject *args)
+typy_get_code (PyObject *self, void *closure)
 {
   struct type *type = ((type_object *) self)->type;
   return PyInt_FromLong (TYPE_CODE (type));
@@ -232,7 +233,7 @@ typy_fields (PyObject *self, PyObject *args)
 
 /* Return the type's tag, or None.  */
 static PyObject *
-typy_tag (PyObject *self, PyObject *args)
+typy_get_tag (PyObject *self, void *closure)
 {
   struct type *type = ((type_object *) self)->type;
   if (!TYPE_TAG_NAME (type))
@@ -346,16 +347,16 @@ typy_unqualified (PyObject *self, PyObject *args)
 
 /* Return the size of the type represented by SELF, in bytes.  */
 static PyObject *
-typy_sizeof (PyObject *self, PyObject *args)
+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);
+      check_typedef (type);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  /* Ignore exceptions.  */
 
   return PyLong_FromLong (TYPE_LENGTH (type));
 }
@@ -595,47 +596,6 @@ set_type (type_object *obj, struct type *type)
     obj->next = NULL;
 }
 
-static PyObject *
-typy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
-{
-  char *type_name = NULL;
-  struct type *type = NULL;
-  type_object *result;
-  PyObject *block_obj = NULL;
-  struct block *block = NULL;
-
-  /* FIXME: it is strange to allow a Type with no name, but we need
-     this for type_to_type_object.  */
-  if (! PyArg_ParseTuple (args, "|sO", &type_name, &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;
-	}
-    }
-
-  if (type_name)
-    {
-      type = typy_lookup_typename (type_name, block);
-      if (! type)
-	return NULL;
-    }
-
-  result = (type_object *) subtype->tp_alloc (subtype, 1);
-  if (! result)
-    return NULL;
-
-  set_type (result, type);
-
-  return (PyObject *) result;
-}
-
 static void
 typy_dealloc (PyObject *obj)
 {
@@ -682,6 +642,38 @@ type_object_to_type (PyObject *obj)
 
 
 
+/* Implementation of gdb.lookup_type.  */
+PyObject *
+gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
+{
+  static char *keywords[] = { "name", "block", NULL };
+  char *type_name = NULL;
+  struct type *type = NULL;
+  PyObject *block_obj = NULL;
+  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)
 {
@@ -713,29 +705,47 @@ gdbpy_initialize_types (void)
 
 
 
+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[] =
 {
-  { "code", typy_code, METH_NOARGS, "Return the code for this type" },
-  { "const", typy_const, METH_NOARGS, "Return a const variant of this type" },
+  { "const", typy_const, METH_NOARGS,
+    "const () -> Type\n\
+Return a const variant of this type." },
   { "fields", typy_fields, METH_NOARGS,
-    "Return a sequence holding all the fields of this type.\n\
+    "field () -> list\n\
+Return a sequence holding all the fields of this type.\n\
 Each field is a dictionary." },
-  { "pointer", typy_pointer, METH_NOARGS, "Return pointer to this type" },
-  { "reference", typy_reference, METH_NOARGS, "Return reference to this type" },
-  { "sizeof", typy_sizeof, METH_NOARGS,
-    "Return the size of this type, in bytes" },
-  { "tag", typy_tag, METH_NOARGS,
-    "Return the tag name for this type, or None." },
+  { "pointer", typy_pointer, METH_NOARGS,
+    "pointer () -> Type\n\
+Return a type of pointer to 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,
-    "Return a type stripped of typedefs"},
+    "strip_typedefs () -> Type\n\
+Return a type formed by stripping this type of all typedefs."},
   { "target", typy_target, METH_NOARGS,
-    "Return the target type of this type" },
+    "target () -> Type\n\
+Return the target type of this type." },
   { "template_argument", typy_template_argument, METH_VARARGS,
-    "Return a single template argument type" },
+    "template_argument (arg) -> Type\n\
+Return the type of a template argument." },
   { "unqualified", typy_unqualified, METH_NOARGS,
-    "Return a variant of this type without const or volatile attributes" },
+    "unqualified () -> Type\n\
+Return a variant of this type without const or volatile attributes." },
   { "volatile", typy_volatile, METH_NOARGS,
-    "Return a volatile variant of this type" },
+    "volatile () -> Type\n\
+Return a volatile variant of this type" },
   { NULL }
 };
 
@@ -771,7 +781,7 @@ static PyTypeObject type_object_type =
   0,				  /* tp_iternext */
   type_object_methods,		  /* tp_methods */
   0,				  /* tp_members */
-  0,				  /* tp_getset */
+  type_object_getset,		  /* tp_getset */
   0,				  /* tp_base */
   0,				  /* tp_dict */
   0,				  /* tp_descr_get */
@@ -779,7 +789,7 @@ static PyTypeObject type_object_type =
   0,				  /* tp_dictoffset */
   0,				  /* tp_init */
   0,				  /* tp_alloc */
-  typy_new,			  /* tp_new */
+  0,				  /* tp_new */
 };
 
 static PyTypeObject field_object_type =
diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c
index b55463c..2eaf15f 100644
--- a/gdb/python/python-value.c
+++ b/gdb/python/python-value.c
@@ -63,6 +63,7 @@ typedef struct {
   PyObject_HEAD
   struct value *value;
   PyObject *address;
+  PyObject *type;
 } value_object;
 
 /* Called by the Python interpreter when deallocating a value object.  */
@@ -81,6 +82,11 @@ valpy_dealloc (PyObject *obj)
       Py_DECREF (self->address);
     }
 
+  if (self->type)
+    {
+      Py_DECREF (self->type);
+    }
+
   self->ob_type->tp_free (self);
 }
 
@@ -115,6 +121,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
 
   value_obj->value = value;
   value_obj->address = NULL;
+  value_obj->type = NULL;
   release_value (value);
   value_prepend_to_list (&values_in_python, value);
 
@@ -167,10 +174,20 @@ valpy_get_address (PyObject *self, void *closure)
 
 /* Return type of the value.  */
 static PyObject *
-valpy_type (PyObject *self, PyObject *args)
+valpy_get_type (PyObject *self, void *closure)
 {
-  struct value *value = ((value_object *) self)->value;
-  return type_to_type_object (value_type (value));
+  value_object *obj = (value_object *) self;
+  if (!obj->type)
+    {
+      obj->type = type_to_type_object (value_type (obj->value));
+      if (!obj->type)
+	{
+	  obj->type = Py_None;
+	  Py_INCREF (obj->type);
+	}
+    }
+  Py_INCREF (obj->type);
+  return obj->type;
 }
 
 /* Implementation of gdb.Value.string ([encoding] [, errors]) -> string
@@ -784,6 +801,7 @@ value_to_value_object (struct value *val)
     {
       val_obj->value = val;
       val_obj->address = NULL;
+      val_obj->type = NULL;
       release_value (val);
       value_prepend_to_list (&values_in_python, val);
     }
@@ -949,13 +967,13 @@ static PyGetSetDef value_object_getset[] = {
   { "is_optimized_out", valpy_get_is_optimized_out, NULL,
     "Boolean telling whether the value is optimized out (i.e., not available).",
     NULL },
+  { "type", valpy_get_type, NULL, "Type of the value.", NULL },
   {NULL}  /* Sentinel */
 };
 
 static PyMethodDef value_object_methods[] = {
   { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
-  { "type", valpy_type, METH_NOARGS, "Return type of the value." },
   { "string", (PyCFunction) valpy_string, METH_VARARGS | METH_KEYWORDS,
     "string ([encoding] [, errors]) -> string\n\
 Return Unicode string representation of the value." },
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 3dbd47e..2d72f13 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1861,6 +1861,11 @@ Return the selected frame object." },
     "stop_reason_string (Integer) -> String.\n\
 Return a string explaining unwind stop reason." },
 
+  { "lookup_type", (PyCFunction) gdbpy_lookup_type,
+    METH_VARARGS | METH_KEYWORDS,
+    "lookup_type (name [, block]) -> type\n\
+Return a Type corresponding to the given name." },
+
   { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol,
     METH_VARARGS | METH_KEYWORDS,
     "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\
diff --git a/gdb/testsuite/gdb.python/find.exp b/gdb/testsuite/gdb.python/find.exp
index d63ea84..defc31c 100644
--- a/gdb/testsuite/gdb.python/find.exp
+++ b/gdb/testsuite/gdb.python/find.exp
@@ -92,7 +92,7 @@ set two_patterns_found "${newline}.${dec_number}L, ${dec_number}L]"
 gdb_test "set *(int32_t*) &int8_search_buf\[10\] = 0x61616161" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int8_search_buf')" "" ""
 gdb_test "py start_addr = search_buf.address" "" ""
-gdb_test "py length = search_buf.type ().sizeof ()" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
 
 gdb_test "py print gdb.search_memory (start_addr, length, 'aaa')" \
   "${two_patterns_found}" "find string pattern"
@@ -130,7 +130,7 @@ gdb_test "py print gdb.search_memory (start_addr, length, \['a', 'a'\], max_coun
 gdb_test "set int16_search_buf\[10\] = 0x1234" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int16_search_buf')" "" ""
 gdb_test "py start_addr = search_buf.address" "" ""
-gdb_test "py length = search_buf.type ().sizeof ()" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
 gdb_test "py pattern = gdb.parse_and_eval ('(int16_t) 0x1234')" "" ""
 
 gdb_test "py print gdb.search_memory (start_addr, length, 0x1234, 2)" \
@@ -144,7 +144,7 @@ gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \
 gdb_test "set int32_search_buf\[10\] = 0x12345678" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int32_search_buf')" "" ""
 gdb_test "py start_addr = search_buf.address" "" ""
-gdb_test "py length = search_buf.type ().sizeof ()" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
 gdb_test "py pattern = gdb.parse_and_eval ('(int32_t) 0x12345678')" "" ""
 
 gdb_test "py print gdb.search_memory (start_addr, length, 0x12345678, 4)" \
@@ -157,7 +157,7 @@ gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \
 gdb_test "set int64_search_buf\[10\] = 0xfedcba9876543210LL" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int64_search_buf')" "" ""
 gdb_test "py start_addr = search_buf.address" "" ""
-gdb_test "py length = search_buf.type ().sizeof ()" "" ""
+gdb_test "py length = search_buf.type.sizeof" "" ""
 gdb_test "py pattern = gdb.parse_and_eval ('(int64_t) 0xfedcba9876543210LL')" "" ""
 
 gdb_test "py print gdb.search_memory (start_addr, length, 0xfedcba9876543210, 8)" \
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py
index 367baa9..a53e412 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.py
+++ b/gdb/testsuite/gdb.python/python-prettyprint.py
@@ -90,23 +90,23 @@ class pp_vbase1:
         self.val = val
 
     def to_string (self):
-        return "pp class name: " + self.val.type ().tag ()
+        return "pp class name: " + self.val.type.tag
 
 def lookup_function (val):
     "Look-up and return a pretty-printer that can print val."
 
     # Get the type.
-    type = val.type ();
+    type = val.type
 
     # If it points to a reference, get the reference.
-    if type.code () == gdb.TYPE_CODE_REF:
+    if type.code == gdb.TYPE_CODE_REF:
         type = type.target ()
 
     # Get the unqualified type, stripped of typedefs.
     type = type.unqualified ().strip_typedefs ()
 
     # Get the type name.    
-    typename = type.tag ()
+    typename = type.tag
 
     if typename == None:
         return None
diff --git a/gdb/testsuite/gdb.python/python-template.exp b/gdb/testsuite/gdb.python/python-template.exp
index 561ff73..1ace5d6 100644
--- a/gdb/testsuite/gdb.python/python-template.exp
+++ b/gdb/testsuite/gdb.python/python-template.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
 
 # 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
@@ -62,7 +62,7 @@ proc test_template_arg {type} {
 
     # Replace '*' with '\*' in regex.
     regsub -all {\*} $type {\*} t
-    gdb_test "python print foo.type().template_argument(0)" $t $type
+    gdb_test "python print foo.type.template_argument(0)" $t $type
 }
 
 test_template_arg "const int"
diff --git a/gdb/testsuite/gdb.python/python-value.exp b/gdb/testsuite/gdb.python/python-value.exp
index cbcf91f..3421406 100644
--- a/gdb/testsuite/gdb.python/python-value.exp
+++ b/gdb/testsuite/gdb.python/python-value.exp
@@ -238,7 +238,7 @@ proc test_value_in_inferior {} {
 
 proc test_value_after_death {} {
   # Construct a type while the inferior is still running.
-  gdb_py_test_silent_cmd "python ptrtype = gdb.Type('PTR')" \
+  gdb_py_test_silent_cmd "python ptrtype = gdb.lookup_type('PTR')" \
     "create PTR type" 1
 
   # Kill the inferior and remove the symbols.
@@ -259,7 +259,7 @@ proc test_value_after_death {} {
     "delete PTR type" 1
 
   # Now see if the value's type is still valid.
-  gdb_test "python print castval.type()" "struct s .." \
+  gdb_test "python print castval.type" "struct s .." \
     "print value's type"
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]