aboutsummaryrefslogtreecommitdiff
path: root/gdb/python
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2020-10-18 11:38:10 -0600
committerTom Tromey <tom@tromey.com>2022-07-28 14:16:50 -0600
commit08b8a139c9e8adcb4ec12a8a17e5836b8b5acb63 (patch)
treee1050b58dcebee1150881f43f64c1c186955d240 /gdb/python
parent8f83e7b9262e08fa43ca6e645337511c68ddc52a (diff)
downloadfsf-binutils-gdb-08b8a139c9e8adcb4ec12a8a17e5836b8b5acb63.zip
fsf-binutils-gdb-08b8a139c9e8adcb4ec12a8a17e5836b8b5acb63.tar.gz
fsf-binutils-gdb-08b8a139c9e8adcb4ec12a8a17e5836b8b5acb63.tar.bz2
Rewrite registry.h
This rewrites registry.h, removing all the macros and replacing it with relatively ordinary template classes. The result is less code than the previous setup. It replaces large macros with a relatively straightforward C++ class, and now manages its own cleanup. The existing type-safe "key" class is replaced with the equivalent template class. This approach ended up requiring relatively few changes to the users of the registry code in gdb -- code using the key system just required a small change to the key's declaration. All existing users of the old C-like API are now converted to use the type-safe API. This mostly involved changing explicit deletion functions to be an operator() in a deleter class. The old "save/free" two-phase process is removed, and replaced with a single "free" phase. No existing code used both phases. The old "free" callbacks took a parameter for the enclosing container object. However, this wasn't truly needed and is removed here as well.
Diffstat (limited to 'gdb/python')
-rw-r--r--gdb/python/py-block.c70
-rw-r--r--gdb/python/py-inferior.c68
-rw-r--r--gdb/python/py-objfile.c37
-rw-r--r--gdb/python/py-progspace.c59
-rw-r--r--gdb/python/py-symbol.c63
-rw-r--r--gdb/python/py-symtab.c142
-rw-r--r--gdb/python/py-type.c59
7 files changed, 212 insertions, 286 deletions
diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c
index 872fb89..b9aea3a 100644
--- a/gdb/python/py-block.c
+++ b/gdb/python/py-block.c
@@ -77,9 +77,33 @@ struct block_syms_iterator_object {
} \
} while (0)
+/* This is called when an objfile is about to be freed.
+ Invalidate the block as further actions on the block would result
+ in bad data. All access to obj->symbol should be gated by
+ BLPY_REQUIRE_VALID which will raise an exception on invalid
+ blocks. */
+struct blpy_deleter
+{
+ void operator() (block_object *obj)
+ {
+ while (obj)
+ {
+ block_object *next = obj->next;
+
+ obj->block = NULL;
+ obj->objfile = NULL;
+ obj->next = NULL;
+ obj->prev = NULL;
+
+ obj = next;
+ }
+ }
+};
+
extern PyTypeObject block_syms_iterator_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
-static const struct objfile_data *blpy_objfile_data_key;
+static const registry<objfile>::key<block_object, blpy_deleter>
+ blpy_objfile_data_key;
static PyObject *
blpy_iter (PyObject *self)
@@ -269,10 +293,7 @@ blpy_dealloc (PyObject *obj)
if (block->prev)
block->prev->next = block->next;
else if (block->objfile)
- {
- set_objfile_data (block->objfile, blpy_objfile_data_key,
- block->next);
- }
+ blpy_objfile_data_key.set (block->objfile, block->next);
if (block->next)
block->next->prev = block->prev;
block->block = NULL;
@@ -293,11 +314,10 @@ set_block (block_object *obj, const struct block *block,
if (objfile)
{
obj->objfile = objfile;
- obj->next = ((block_object *)
- objfile_data (objfile, blpy_objfile_data_key));
+ obj->next = blpy_objfile_data_key.get (objfile);
if (obj->next)
obj->next->prev = obj;
- set_objfile_data (objfile, blpy_objfile_data_key, obj);
+ blpy_objfile_data_key.set (objfile, obj);
}
else
obj->next = NULL;
@@ -404,40 +424,6 @@ blpy_iter_is_valid (PyObject *self, PyObject *args)
Py_RETURN_TRUE;
}
-/* This function is called when an objfile is about to be freed.
- Invalidate the block as further actions on the block would result
- in bad data. All access to obj->symbol should be gated by
- BLPY_REQUIRE_VALID which will raise an exception on invalid
- blocks. */
-static void
-del_objfile_blocks (struct objfile *objfile, void *datum)
-{
- block_object *obj = (block_object *) datum;
-
- while (obj)
- {
- block_object *next = obj->next;
-
- obj->block = NULL;
- obj->objfile = NULL;
- obj->next = NULL;
- obj->prev = NULL;
-
- obj = next;
- }
-}
-
-void _initialize_py_block ();
-void
-_initialize_py_block ()
-{
- /* Register an objfile "free" callback so we can properly
- invalidate blocks when an object file is about to be
- deleted. */
- blpy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
-}
-
int
gdbpy_initialize_blocks (void)
{
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 61ed342..6ea384e 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -60,7 +60,35 @@ struct inferior_object
extern PyTypeObject inferior_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
-static const struct inferior_data *infpy_inf_data_key;
+/* Deleter to clean up when an inferior is removed. */
+struct infpy_deleter
+{
+ void operator() (inferior_object *obj)
+ {
+ struct threadlist_entry *th_entry, *th_tmp;
+
+ if (!gdb_python_initialized)
+ return;
+
+ gdbpy_enter enter_py;
+ gdbpy_ref<inferior_object> inf_obj (obj);
+
+ inf_obj->inferior = NULL;
+
+ /* Deallocate threads list. */
+ for (th_entry = inf_obj->threads; th_entry != NULL;)
+ {
+ th_tmp = th_entry;
+ th_entry = th_entry->next;
+ delete th_tmp;
+ }
+
+ inf_obj->nthreads = 0;
+ }
+};
+
+static const registry<inferior>::key<inferior_object, infpy_deleter>
+ infpy_inf_data_key;
/* Require that INFERIOR be a valid inferior ID. */
#define INFPY_REQUIRE_VALID(Inferior) \
@@ -221,7 +249,7 @@ inferior_to_inferior_object (struct inferior *inferior)
{
inferior_object *inf_obj;
- inf_obj = (inferior_object *) inferior_data (inferior, infpy_inf_data_key);
+ inf_obj = infpy_inf_data_key.get (inferior);
if (!inf_obj)
{
inf_obj = PyObject_New (inferior_object, &inferior_object_type);
@@ -234,7 +262,7 @@ inferior_to_inferior_object (struct inferior *inferior)
/* PyObject_New initializes the new object with a refcount of 1. This
counts for the reference we are keeping in the inferior data. */
- set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
+ infpy_inf_data_key.set (inferior, inf_obj);
}
/* We are returning a new reference. */
@@ -795,32 +823,6 @@ infpy_dealloc (PyObject *obj)
Py_TYPE (obj)->tp_free (obj);
}
-/* Clear the INFERIOR pointer in an Inferior object and clear the
- thread list. */
-static void
-py_free_inferior (struct inferior *inf, void *datum)
-{
- struct threadlist_entry *th_entry, *th_tmp;
-
- if (!gdb_python_initialized)
- return;
-
- gdbpy_enter enter_py;
- gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
-
- inf_obj->inferior = NULL;
-
- /* Deallocate threads list. */
- for (th_entry = inf_obj->threads; th_entry != NULL;)
- {
- th_tmp = th_entry;
- th_entry = th_entry->next;
- delete th_tmp;
- }
-
- inf_obj->nthreads = 0;
-}
-
/* Implementation of gdb.selected_inferior() -> gdb.Inferior.
Returns the current inferior object. */
@@ -831,14 +833,6 @@ gdbpy_selected_inferior (PyObject *self, PyObject *args)
inferior_to_inferior_object (current_inferior ()).release ());
}
-void _initialize_py_inferior ();
-void
-_initialize_py_inferior ()
-{
- infpy_inf_data_key =
- register_inferior_data_with_cleanup (NULL, py_free_inferior);
-}
-
int
gdbpy_initialize_inferior (void)
{
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
index 298f3f2..4cc5702 100644
--- a/gdb/python/py-objfile.c
+++ b/gdb/python/py-objfile.c
@@ -55,7 +55,20 @@ struct objfile_object
extern PyTypeObject objfile_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("objfile_object");
-static const struct objfile_data *objfpy_objfile_data_key;
+/* Clear the OBJFILE pointer in an Objfile object and remove the
+ reference. */
+struct objfpy_deleter
+{
+ void operator() (objfile_object *obj)
+ {
+ gdbpy_enter enter_py;
+ gdbpy_ref<objfile_object> object (obj);
+ object->objfile = nullptr;
+ }
+};
+
+static const registry<objfile>::key<objfile_object, objfpy_deleter>
+ objfpy_objfile_data_key;
/* Require that OBJF be a valid objfile. */
#define OBJFPY_REQUIRE_VALID(obj) \
@@ -668,16 +681,6 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
-/* Clear the OBJFILE pointer in an Objfile object and remove the
- reference. */
-static void
-py_free_objfile (struct objfile *objfile, void *datum)
-{
- gdbpy_enter enter_py (objfile->arch ());
- gdbpy_ref<objfile_object> object ((objfile_object *) datum);
- object->objfile = NULL;
-}
-
/* Return a new reference to the Python object of type Objfile
representing OBJFILE. If the object has already been created,
return it. Otherwise, create it. Return NULL and set the Python
@@ -687,7 +690,7 @@ gdbpy_ref<>
objfile_to_objfile_object (struct objfile *objfile)
{
PyObject *result
- = ((PyObject *) objfile_data (objfile, objfpy_objfile_data_key));
+ = (PyObject *) objfpy_objfile_data_key.get (objfile);
if (result == NULL)
{
gdbpy_ref<objfile_object> object
@@ -698,21 +701,13 @@ objfile_to_objfile_object (struct objfile *objfile)
return NULL;
object->objfile = objfile;
- set_objfile_data (objfile, objfpy_objfile_data_key, object.get ());
+ objfpy_objfile_data_key.set (objfile, object.get ());
result = (PyObject *) object.release ();
}
return gdbpy_ref<>::new_reference (result);
}
-void _initialize_py_objfile ();
-void
-_initialize_py_objfile ()
-{
- objfpy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, py_free_objfile);
-}
-
int
gdbpy_initialize_objfile (void)
{
diff --git a/gdb/python/py-progspace.c b/gdb/python/py-progspace.c
index 5ec5986..4eb33e8 100644
--- a/gdb/python/py-progspace.c
+++ b/gdb/python/py-progspace.c
@@ -57,7 +57,30 @@ struct pspace_object
extern PyTypeObject pspace_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pspace_object");
-static const struct program_space_data *pspy_pspace_data_key;
+/* Clear the PSPACE pointer in a Pspace object and remove the reference. */
+struct pspace_deleter
+{
+ void operator() (pspace_object *obj)
+ {
+ /* This is a fiction, but we're in a nasty spot: The pspace is in the
+ process of being deleted, we can't rely on anything in it. Plus
+ this is one time when the current program space and current inferior
+ are not in sync: All inferiors that use PSPACE may no longer exist.
+ We don't need to do much here, and since "there is always an inferior"
+ using target_gdbarch suffices.
+ Note: We cannot call get_current_arch because it may try to access
+ the target, which may involve accessing data in the pspace currently
+ being deleted. */
+ struct gdbarch *arch = target_gdbarch ();
+
+ gdbpy_enter enter_py (arch);
+ gdbpy_ref<pspace_object> object (obj);
+ object->pspace = NULL;
+ }
+};
+
+static const registry<program_space>::key<pspace_object, pspace_deleter>
+ pspy_pspace_data_key;
/* Require that PSPACE_OBJ be a valid program space ID. */
#define PSPY_REQUIRE_VALID(pspace_obj) \
@@ -463,27 +486,6 @@ pspy_is_valid (PyObject *o, PyObject *args)
-/* Clear the PSPACE pointer in a Pspace object and remove the reference. */
-
-static void
-py_free_pspace (struct program_space *pspace, void *datum)
-{
- /* This is a fiction, but we're in a nasty spot: The pspace is in the
- process of being deleted, we can't rely on anything in it. Plus
- this is one time when the current program space and current inferior
- are not in sync: All inferiors that use PSPACE may no longer exist.
- We don't need to do much here, and since "there is always an inferior"
- using target_gdbarch suffices.
- Note: We cannot call get_current_arch because it may try to access
- the target, which may involve accessing data in the pspace currently
- being deleted. */
- struct gdbarch *arch = target_gdbarch ();
-
- gdbpy_enter enter_py (arch);
- gdbpy_ref<pspace_object> object ((pspace_object *) datum);
- object->pspace = NULL;
-}
-
/* Return a new reference to the Python object of type Pspace
representing PSPACE. If the object has already been created,
return it. Otherwise, create it. Return NULL and set the Python
@@ -492,8 +494,7 @@ py_free_pspace (struct program_space *pspace, void *datum)
gdbpy_ref<>
pspace_to_pspace_object (struct program_space *pspace)
{
- PyObject *result
- ((PyObject *) program_space_data (pspace, pspy_pspace_data_key));
+ PyObject *result = (PyObject *) pspy_pspace_data_key.get (pspace);
if (result == NULL)
{
gdbpy_ref<pspace_object> object
@@ -504,7 +505,7 @@ pspace_to_pspace_object (struct program_space *pspace)
return NULL;
object->pspace = pspace;
- set_program_space_data (pspace, pspy_pspace_data_key, object.get ());
+ pspy_pspace_data_key.set (pspace, object.get ());
result = (PyObject *) object.release ();
}
@@ -528,14 +529,6 @@ gdbpy_is_progspace (PyObject *obj)
return PyObject_TypeCheck (obj, &pspace_object_type);
}
-void _initialize_py_progspace ();
-void
-_initialize_py_progspace ()
-{
- pspy_pspace_data_key
- = register_program_space_data_with_cleanup (NULL, py_free_pspace);
-}
-
int
gdbpy_initialize_pspace (void)
{
diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c
index 23495b6..e5fe5cf 100644
--- a/gdb/python/py-symbol.c
+++ b/gdb/python/py-symbol.c
@@ -50,7 +50,26 @@ struct symbol_object {
} \
} while (0)
-static const struct objfile_data *sympy_objfile_data_key;
+/* A deleter that is used when an objfile is about to be freed. */
+struct symbol_object_deleter
+{
+ void operator() (symbol_object *obj)
+ {
+ while (obj)
+ {
+ symbol_object *next = obj->next;
+
+ obj->symbol = NULL;
+ obj->next = NULL;
+ obj->prev = NULL;
+
+ obj = next;
+ }
+ }
+};
+
+static const registry<objfile>::key<symbol_object, symbol_object_deleter>
+ sympy_objfile_data_key;
static PyObject *
sympy_str (PyObject *self)
@@ -307,11 +326,10 @@ set_symbol (symbol_object *obj, struct symbol *symbol)
{
struct objfile *objfile = symbol->objfile ();
- obj->next = ((symbol_object *)
- objfile_data (objfile, sympy_objfile_data_key));
+ obj->next = sympy_objfile_data_key.get (objfile);
if (obj->next)
obj->next->prev = obj;
- set_objfile_data (objfile, sympy_objfile_data_key, obj);
+ sympy_objfile_data_key.set (objfile, obj);
}
else
obj->next = NULL;
@@ -350,10 +368,7 @@ sympy_dealloc (PyObject *obj)
else if (sym_obj->symbol != NULL
&& sym_obj->symbol->is_objfile_owned ()
&& sym_obj->symbol->symtab () != NULL)
- {
- set_objfile_data (sym_obj->symbol->objfile (),
- sympy_objfile_data_key, sym_obj->next);
- }
+ sympy_objfile_data_key.set (sym_obj->symbol->objfile (), sym_obj->next);
if (sym_obj->next)
sym_obj->next->prev = sym_obj->prev;
sym_obj->symbol = NULL;
@@ -596,38 +611,6 @@ gdbpy_lookup_static_symbols (PyObject *self, PyObject *args, PyObject *kw)
return return_list.release ();
}
-/* This function is called when an objfile is about to be freed.
- Invalidate the symbol as further actions on the symbol would result
- in bad data. All access to obj->symbol should be gated by
- SYMPY_REQUIRE_VALID which will raise an exception on invalid
- symbols. */
-static void
-del_objfile_symbols (struct objfile *objfile, void *datum)
-{
- symbol_object *obj = (symbol_object *) datum;
- while (obj)
- {
- symbol_object *next = obj->next;
-
- obj->symbol = NULL;
- obj->next = NULL;
- obj->prev = NULL;
-
- obj = next;
- }
-}
-
-void _initialize_py_symbol ();
-void
-_initialize_py_symbol ()
-{
- /* Register an objfile "free" callback so we can properly
- invalidate symbol when an object file that is about to be
- deleted. */
- sympy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, del_objfile_symbols);
-}
-
int
gdbpy_initialize_symbols (void)
{
diff --git a/gdb/python/py-symtab.c b/gdb/python/py-symtab.c
index 7ed6271..03c274d 100644
--- a/gdb/python/py-symtab.c
+++ b/gdb/python/py-symtab.c
@@ -37,9 +37,31 @@ struct symtab_object {
symtab_object *next;
};
+/* This function is called when an objfile is about to be freed.
+ Invalidate the symbol table as further actions on the symbol table
+ would result in bad data. All access to obj->symtab should be
+ gated by STPY_REQUIRE_VALID which will raise an exception on
+ invalid symbol tables. */
+struct stpy_deleter
+{
+ void operator() (symtab_object *obj)
+ {
+ while (obj)
+ {
+ symtab_object *next = obj->next;
+
+ obj->symtab = NULL;
+ obj->next = NULL;
+ obj->prev = NULL;
+ obj = next;
+ }
+ }
+};
+
extern PyTypeObject symtab_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symtab_object");
-static const struct objfile_data *stpy_objfile_data_key;
+static const registry<objfile>::key<symtab_object, stpy_deleter>
+ stpy_objfile_data_key;
/* Require a valid symbol table. All access to symtab_object->symtab
should be gated by this call. */
@@ -68,9 +90,39 @@ struct sal_object {
sal_object *next;
};
+/* This is called when an objfile is about to be freed. Invalidate
+ the sal object as further actions on the sal would result in bad
+ data. All access to obj->sal should be gated by
+ SALPY_REQUIRE_VALID which will raise an exception on invalid symbol
+ table and line objects. */
+struct salpy_deleter
+{
+ void operator() (sal_object *obj)
+ {
+ gdbpy_enter enter_py;
+
+ while (obj)
+ {
+ sal_object *next = obj->next;
+
+ gdbpy_ref<> tmp (obj->symtab);
+ obj->symtab = Py_None;
+ Py_INCREF (Py_None);
+
+ obj->next = NULL;
+ obj->prev = NULL;
+ xfree (obj->sal);
+ obj->sal = NULL;
+
+ obj = next;
+ }
+ }
+};
+
extern PyTypeObject sal_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("sal_object");
-static const struct objfile_data *salpy_objfile_data_key;
+static const registry<objfile>::key<sal_object, salpy_deleter>
+ salpy_objfile_data_key;
/* Require a valid symbol table and line object. All access to
sal_object->sal should be gated by this call. */
@@ -246,10 +298,8 @@ stpy_dealloc (PyObject *obj)
if (symtab->prev)
symtab->prev->next = symtab->next;
else if (symtab->symtab)
- {
- set_objfile_data (symtab->symtab->compunit ()->objfile (),
- stpy_objfile_data_key, symtab->next);
- }
+ stpy_objfile_data_key.set (symtab->symtab->compunit ()->objfile (),
+ symtab->next);
if (symtab->next)
symtab->next->prev = symtab->prev;
symtab->symtab = NULL;
@@ -329,9 +379,9 @@ salpy_dealloc (PyObject *self)
if (self_sal->prev)
self_sal->prev->next = self_sal->next;
else if (self_sal->symtab != Py_None)
- set_objfile_data
+ salpy_objfile_data_key.set
(symtab_object_to_symtab (self_sal->symtab)->compunit ()->objfile (),
- salpy_objfile_data_key, self_sal->next);
+ self_sal->next);
if (self_sal->next)
self_sal->next->prev = self_sal->prev;
@@ -378,13 +428,11 @@ set_sal (sal_object *sal_obj, struct symtab_and_line sal)
symtab *symtab = symtab_object_to_symtab (sal_obj->symtab);
sal_obj->next
- = ((sal_object *) objfile_data (symtab->compunit ()->objfile (),
- salpy_objfile_data_key));
+ = salpy_objfile_data_key.get (symtab->compunit ()->objfile ());
if (sal_obj->next)
sal_obj->next->prev = sal_obj;
- set_objfile_data (symtab->compunit ()->objfile (),
- salpy_objfile_data_key, sal_obj);
+ salpy_objfile_data_key.set (symtab->compunit ()->objfile (), sal_obj);
}
else
sal_obj->next = NULL;
@@ -404,14 +452,10 @@ set_symtab (symtab_object *obj, struct symtab *symtab)
obj->prev = NULL;
if (symtab)
{
- obj->next
- = ((symtab_object *)
- objfile_data (symtab->compunit ()->objfile (),
- stpy_objfile_data_key));
+ obj->next = stpy_objfile_data_key.get (symtab->compunit ()->objfile ());
if (obj->next)
obj->next->prev = obj;
- set_objfile_data (symtab->compunit ()->objfile (),
- stpy_objfile_data_key, obj);
+ stpy_objfile_data_key.set (symtab->compunit ()->objfile (), obj);
}
else
obj->next = NULL;
@@ -465,68 +509,6 @@ symtab_object_to_symtab (PyObject *obj)
return ((symtab_object *) obj)->symtab;
}
-/* This function is called when an objfile is about to be freed.
- Invalidate the symbol table as further actions on the symbol table
- would result in bad data. All access to obj->symtab should be
- gated by STPY_REQUIRE_VALID which will raise an exception on
- invalid symbol tables. */
-static void
-del_objfile_symtab (struct objfile *objfile, void *datum)
-{
- symtab_object *obj = (symtab_object *) datum;
-
- while (obj)
- {
- symtab_object *next = obj->next;
-
- obj->symtab = NULL;
- obj->next = NULL;
- obj->prev = NULL;
- obj = next;
- }
-}
-
-/* This function is called when an objfile is about to be freed.
- Invalidate the sal object as further actions on the sal
- would result in bad data. All access to obj->sal should be
- gated by SALPY_REQUIRE_VALID which will raise an exception on
- invalid symbol table and line objects. */
-static void
-del_objfile_sal (struct objfile *objfile, void *datum)
-{
- sal_object *obj = (sal_object *) datum;
-
- while (obj)
- {
- sal_object *next = obj->next;
-
- gdbpy_ref<> tmp (obj->symtab);
- obj->symtab = Py_None;
- Py_INCREF (Py_None);
-
- obj->next = NULL;
- obj->prev = NULL;
- xfree (obj->sal);
- obj->sal = NULL;
-
- obj = next;
- }
-}
-
-void _initialize_py_symtab ();
-void
-_initialize_py_symtab ()
-{
- /* Register an objfile "free" callback so we can properly
- invalidate symbol tables, and symbol table and line data
- structures when an object file that is about to be
- deleted. */
- stpy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, del_objfile_symtab);
- salpy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, del_objfile_sal);
-}
-
int
gdbpy_initialize_symtabs (void)
{
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 7cfc8d1..d14f9e4 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1109,36 +1109,38 @@ typy_richcompare (PyObject *self, PyObject *other, int op)
-static const struct objfile_data *typy_objfile_data_key;
-
-static void
-save_objfile_types (struct objfile *objfile, void *datum)
+/* Deleter that saves types when an objfile is being destroyed. */
+struct typy_deleter
{
- type_object *obj = (type_object *) datum;
+ void operator() (type_object *obj)
+ {
+ if (!gdb_python_initialized)
+ return;
- if (!gdb_python_initialized)
- return;
+ /* This prevents another thread from freeing the objects we're
+ operating on. */
+ gdbpy_enter enter_py;
- /* This prevents another thread from freeing the objects we're
- operating on. */
- gdbpy_enter enter_py (objfile->arch ());
+ htab_up copied_types = create_copied_types_hash ();
- htab_up copied_types = create_copied_types_hash ();
+ while (obj)
+ {
+ type_object *next = obj->next;
- while (obj)
- {
- type_object *next = obj->next;
+ htab_empty (copied_types.get ());
- htab_empty (copied_types.get ());
+ obj->type = copy_type_recursive (obj->type, copied_types.get ());
- obj->type = copy_type_recursive (obj->type, copied_types.get ());
+ obj->next = NULL;
+ obj->prev = NULL;
- obj->next = NULL;
- obj->prev = NULL;
+ obj = next;
+ }
+ }
+};
- obj = next;
- }
-}
+static const registry<objfile>::key<type_object, typy_deleter>
+ typy_objfile_data_key;
static void
set_type (type_object *obj, struct type *type)
@@ -1149,11 +1151,10 @@ set_type (type_object *obj, struct type *type)
{
struct objfile *objfile = type->objfile_owner ();
- obj->next = ((type_object *)
- objfile_data (objfile, typy_objfile_data_key));
+ obj->next = typy_objfile_data_key.get (objfile);
if (obj->next)
obj->next->prev = obj;
- set_objfile_data (objfile, typy_objfile_data_key, obj);
+ typy_objfile_data_key.set (objfile, obj);
}
else
obj->next = NULL;
@@ -1172,7 +1173,7 @@ typy_dealloc (PyObject *obj)
struct objfile *objfile = type->type->objfile_owner ();
if (objfile)
- set_objfile_data (objfile, typy_objfile_data_key, type->next);
+ typy_objfile_data_key.set (objfile, type->next);
}
if (type->next)
type->next->prev = type->prev;
@@ -1464,14 +1465,6 @@ gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw)
return type_to_type_object (type);
}
-void _initialize_py_type ();
-void
-_initialize_py_type ()
-{
- typy_objfile_data_key
- = register_objfile_data_with_cleanup (save_objfile_types, NULL);
-}
-
int
gdbpy_initialize_types (void)
{