This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
[python] better type cleanup
- From: Tom Tromey <tromey at redhat dot com>
- To: Project Archer <archer at sourceware dot org>
- Date: Mon, 10 Nov 2008 12:18:56 -0700
- Subject: [python] better type cleanup
- Reply-to: Tom Tromey <tromey at redhat dot com>
This fixes delete_type_recursive to delete a few things it was
previously missing: pointer types, reference types, and type variants.
(You can't create type variants yet from Python, but that will be
implemented eventually.)
This also fixes a bug with the "parent" tracking Type code I committed
earlier.
Tom
2008-11-10 Tom Tromey <tromey@redhat.com>
* python/python-type.c (set_type): Use parent's originator, if it
exists.
* gdbtypes.c (delete_main_type): New function.
(delete_type_recursive): Use it. Delete the pointer type,
reference type, and chain.
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 614f5be..2743c42 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -3065,14 +3065,13 @@ create_deleted_types_hash (void)
return htab_create (1, htab_hash_pointer, htab_eq_pointer, NULL);
}
-/* Recursively delete TYPE and things it references. TYPE must have
- been allocated using xmalloc -- not using an objfile.
- DELETED_TYPES is a hash table, allocated using
- create_deleted_types_hash, which is used for checking whether a
- type has already been deleted. */
+/* A helper for delete_type_recursive which deletes a main_type and
+ the things to which it refers. TYPE is a type whose main_type we
+ wish to destroy. DELETED_TYPES is a hash holding already-seen
+ pointers; see delete_type_recursive. */
-void
-delete_type_recursive (struct type *type, htab_t deleted_types)
+static void
+delete_main_type (struct type *type, htab_t deleted_types)
{
int i;
void **slot;
@@ -3080,17 +3079,19 @@ delete_type_recursive (struct type *type, htab_t deleted_types)
if (!type)
return;
- slot = htab_find_slot (deleted_types, type, INSERT);
+ /* Multiple types might share a single main_type. So, we must
+ check to make sure this is not happening. */
+ slot = htab_find_slot (deleted_types, TYPE_MAIN_TYPE (type), INSERT);
if (*slot != NULL)
return;
-
- gdb_assert (!TYPE_OBJFILE (type));
-
- *slot = type;
+ *slot = TYPE_MAIN_TYPE (type);
xfree (TYPE_NAME (type));
xfree (TYPE_TAG_NAME (type));
+ delete_type_recursive (TYPE_TARGET_TYPE (type), deleted_types);
+ delete_type_recursive (TYPE_VPTR_BASETYPE (type), deleted_types);
+
for (i = 0; i < TYPE_NFIELDS (type); ++i)
{
delete_type_recursive (TYPE_FIELD_TYPE (type, i), deleted_types);
@@ -3102,14 +3103,42 @@ delete_type_recursive (struct type *type, htab_t deleted_types)
}
xfree (TYPE_FIELDS (type));
- delete_type_recursive (TYPE_TARGET_TYPE (type), deleted_types);
- delete_type_recursive (TYPE_VPTR_BASETYPE (type), deleted_types);
-
/* Strangely, HAVE_CPLUS_STRUCT will return true when there isn't
one at all. */
gdb_assert (!HAVE_CPLUS_STRUCT (type) || !TYPE_CPLUS_SPECIFIC (type));
xfree (TYPE_MAIN_TYPE (type));
+}
+
+/* Recursively delete TYPE and things it references. TYPE must have
+ been allocated using xmalloc -- not using an objfile.
+ DELETED_TYPES is a hash table, allocated using
+ create_deleted_types_hash, which is used for checking whether a
+ type has already been deleted. */
+
+void
+delete_type_recursive (struct type *type, htab_t deleted_types)
+{
+ void **slot;
+
+ if (!type)
+ return;
+
+ slot = htab_find_slot (deleted_types, type, INSERT);
+ if (*slot != NULL)
+ return;
+ gdb_assert (!TYPE_OBJFILE (type));
+ *slot = type;
+
+ delete_main_type (type, deleted_types);
+ delete_type_recursive (TYPE_POINTER_TYPE (type), deleted_types);
+ delete_type_recursive (TYPE_REFERENCE_TYPE (type), deleted_types);
+
+ /* It is somewhat inefficient to free the chain recursively.
+ However, the list is typically short, and this avoid duplicating
+ the deletion checking code. */
+ delete_type_recursive (TYPE_CHAIN (type), deleted_types);
+
xfree (type);
}
diff --git a/gdb/python/python-type.c b/gdb/python/python-type.c
index 3a1074c..e0821d7 100644
--- a/gdb/python/python-type.c
+++ b/gdb/python/python-type.c
@@ -335,13 +335,20 @@ set_type (type_object *obj, struct type *type, type_object *parent)
else
obj->next = NULL;
- if (type && parent && parent->owned)
+ obj->originator = NULL;
+ if (type && parent)
{
- Py_INCREF (parent);
- obj->originator = (PyObject *) parent;
+ if (parent->owned)
+ {
+ Py_INCREF (parent);
+ obj->originator = (PyObject *) parent;
+ }
+ else if (parent->originator)
+ {
+ Py_INCREF (parent->originator);
+ obj->originator = parent->originator;
+ }
}
- else
- obj->originator = NULL;
}
static PyObject *