+2018-03-27 Tom Tromey <tom@tromey.com>
+
+ * typeprint.h (struct type_print_options) <local_typedefs,
+ global_typedefs>: Remove "struct" keyword.
+ (class typedef_hash_table): New class.
+ (recursively_update_typedef_hash, add_template_parameters)
+ (create_typedef_hash, free_typedef_hash, copy_typedef_hash)
+ (find_typedef_in_hash): Don't declare.
+ * typeprint.c (struct typedef_hash_table): Move to typeprint.h.
+ (typedef_hash_table::recursively_update): Rename from
+ recursively_update_typedef_hash. Now a member.
+ (typedef_hash_table::add_template_parameters): Rename from
+ add_template_parameters. Now a member.
+ (typedef_hash_table::typedef_hash_table): Now a constructor;
+ rename from create_typedef_hash.
+ (typedef_hash_table::~typedef_hash_table): Now a destructor;
+ rename from free_typedef_hash.
+ (do_free_typedef_hash, make_cleanup_free_typedef_hash)
+ (do_free_global_table): Remove.
+ (typedef_hash_table::typedef_hash_table): New constructor; renamed
+ from copy_type_recursive.
+ (create_global_typedef_table): Remove.
+ (typedef_hash_table::find_global_typedef): Now a member of
+ typedef_hash_table.
+ (typedef_hash_table::find_typedef): Rename from
+ find_typedef_in_hash; now a member.
+ (whatis_exp): Update.
+ * extension.h (struct ext_lang_type_printers): Add constructor and
+ destructor.
+ (start_ext_lang_type_printers, free_ext_lang_type_printers): Don't
+ declare.
+ * extension.c (ext_lang_type_printers::ext_lang_type_printers):
+ Now a constructor; rename from start_ext_lang_type_printers.
+ (ext_lang_type_printers): Now a destructor; rename from
+ free_ext_lang_type_printers.
+ * c-typeprint.c (find_typedef_for_canonicalize, c_print_type_1):
+ Update.
+ (c_type_print_base_struct_union): Update. Remove cleanups.
+
2018-03-27 Tom Tromey <tom@tromey.com>
* dwarf-index-write.c: Include <cmath>.
\f
/* A callback function for cp_canonicalize_string_full that uses
- find_typedef_in_hash. */
+ typedef_hash_table::find_typedef. */
static const char *
find_typedef_for_canonicalize (struct type *t, void *data)
{
- return find_typedef_in_hash ((const struct type_print_options *) data, t);
+ return typedef_hash_table::find_typedef
+ ((const struct type_print_options *) data, t);
}
/* Print NAME on STREAM. If the 'raw' field of FLAGS is not set,
if (show > 0)
type = check_typedef (type);
- local_name = find_typedef_in_hash (flags, type);
+ local_name = typedef_hash_table::find_typedef (flags, type);
if (local_name != NULL)
{
fputs_filtered (local_name, stream);
struct print_offset_data *podata)
{
struct type_print_options local_flags = *flags;
- struct type_print_options semi_local_flags = *flags;
- struct cleanup *local_cleanups = make_cleanup (null_cleanup, NULL);
-
local_flags.local_typedefs = NULL;
- semi_local_flags.local_typedefs = NULL;
+ std::unique_ptr<typedef_hash_table> hash_holder;
if (!flags->raw)
{
if (flags->local_typedefs)
local_flags.local_typedefs
- = copy_typedef_hash (flags->local_typedefs);
+ = new typedef_hash_table (*flags->local_typedefs);
else
- local_flags.local_typedefs = create_typedef_hash ();
+ local_flags.local_typedefs = new typedef_hash_table ();
- make_cleanup_free_typedef_hash (local_flags.local_typedefs);
+ hash_holder.reset (local_flags.local_typedefs);
}
c_type_print_modifier (type, stream, 0, 1);
c_type_print_template_args (&local_flags, type, stream);
/* Add in template parameters when printing derivation info. */
- add_template_parameters (local_flags.local_typedefs, type);
+ if (local_flags.local_typedefs != NULL)
+ local_flags.local_typedefs->add_template_parameters (type);
cp_type_print_derivation_info (stream, type, &local_flags);
/* This holds just the global typedefs and the template
parameters. */
- semi_local_flags.local_typedefs
- = copy_typedef_hash (local_flags.local_typedefs);
- if (semi_local_flags.local_typedefs)
- make_cleanup_free_typedef_hash (semi_local_flags.local_typedefs);
+ struct type_print_options semi_local_flags = *flags;
+ semi_local_flags.local_typedefs = NULL;
- /* Now add in the local typedefs. */
- recursively_update_typedef_hash (local_flags.local_typedefs, type);
+ std::unique_ptr<typedef_hash_table> semi_holder;
+ if (local_flags.local_typedefs != nullptr)
+ {
+ semi_local_flags.local_typedefs
+ = new typedef_hash_table (*local_flags.local_typedefs);
+ semi_holder.reset (semi_local_flags.local_typedefs);
+
+ /* Now add in the local typedefs. */
+ local_flags.local_typedefs->recursively_update (type);
+ }
fprintf_filtered (stream, "{\n");
fprintfi_filtered (level, stream, "}");
}
-
- do_cleanups (local_cleanups);
}
/* Print the name of the type (or the ultimate pointer target,
We don't know in advance which extension language will provide a
pretty-printer for the type, so all are initialized. */
-struct ext_lang_type_printers *
-start_ext_lang_type_printers (void)
+ext_lang_type_printers::ext_lang_type_printers ()
{
- struct ext_lang_type_printers *printers
- = XCNEW (struct ext_lang_type_printers);
int i;
const struct extension_language_defn *extlang;
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
{
if (extlang->ops->start_type_printers != NULL)
- extlang->ops->start_type_printers (extlang, printers);
+ extlang->ops->start_type_printers (extlang, this);
}
-
- return printers;
}
/* Iteratively try the type pretty-printers specified by PRINTERS
return NULL;
}
-/* Call this after pretty-printing a type to release all memory held
- by PRINTERS. */
-
-void
-free_ext_lang_type_printers (struct ext_lang_type_printers *printers)
+ext_lang_type_printers::~ext_lang_type_printers ()
{
int i;
const struct extension_language_defn *extlang;
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
{
if (extlang->ops->free_type_printers != NULL)
- extlang->ops->free_type_printers (extlang, printers);
+ extlang->ops->free_type_printers (extlang, this);
}
-
- xfree (printers);
}
\f
/* Try to pretty-print a value of type TYPE located at VAL's contents
struct ext_lang_type_printers
{
+ ext_lang_type_printers ();
+ ~ext_lang_type_printers ();
+
+ DISABLE_COPY_AND_ASSIGN (ext_lang_type_printers);
+
/* Type-printers from Python. */
void *py_type_printers;
};
extern void auto_load_ext_lang_scripts_for_objfile (struct objfile *);
-extern struct ext_lang_type_printers *start_ext_lang_type_printers (void);
-
extern char *apply_ext_lang_type_printers (struct ext_lang_type_printers *,
struct type *);
-extern void free_ext_lang_type_printers (struct ext_lang_type_printers *);
-
extern int apply_ext_lang_val_pretty_printer
(struct type *type,
LONGEST embedded_offset, CORE_ADDR address,
\f
-/* A hash table holding typedef_field objects. This is more
- complicated than an ordinary hash because it must also track the
- lifetime of some -- but not all -- of the contained objects. */
-
-struct typedef_hash_table
-{
- /* The actual hash table. */
- htab_t table;
-
- /* Storage for typedef_field objects that must be synthesized. */
- struct obstack storage;
-};
-
/* A hash function for a typedef_field. */
static hashval_t
return types_equal (tfa->type, tfb->type);
}
-/* Add typedefs from T to the hash table TABLE. */
+/* See typeprint.h. */
void
-recursively_update_typedef_hash (struct typedef_hash_table *table,
- struct type *t)
+typedef_hash_table::recursively_update (struct type *t)
{
int i;
- if (table == NULL)
- return;
-
for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (t); ++i)
{
struct decl_field *tdef = &TYPE_TYPEDEF_FIELD (t, i);
void **slot;
- slot = htab_find_slot (table->table, tdef, INSERT);
+ slot = htab_find_slot (m_table, tdef, INSERT);
/* Only add a given typedef name once. Really this shouldn't
happen; but it is safe enough to do the updates breadth-first
and thus use the most specific typedef. */
/* Recurse into superclasses. */
for (i = 0; i < TYPE_N_BASECLASSES (t); ++i)
- recursively_update_typedef_hash (table, TYPE_BASECLASS (t, i));
+ recursively_update (TYPE_BASECLASS (t, i));
}
-/* Add template parameters from T to the typedef hash TABLE. */
+/* See typeprint.h. */
void
-add_template_parameters (struct typedef_hash_table *table, struct type *t)
+typedef_hash_table::add_template_parameters (struct type *t)
{
int i;
- if (table == NULL)
- return;
-
for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (t); ++i)
{
struct decl_field *tf;
if (SYMBOL_CLASS (TYPE_TEMPLATE_ARGUMENT (t, i)) != LOC_TYPEDEF)
continue;
- tf = XOBNEW (&table->storage, struct decl_field);
+ tf = XOBNEW (&m_storage, struct decl_field);
tf->name = SYMBOL_LINKAGE_NAME (TYPE_TEMPLATE_ARGUMENT (t, i));
tf->type = SYMBOL_TYPE (TYPE_TEMPLATE_ARGUMENT (t, i));
- slot = htab_find_slot (table->table, tf, INSERT);
+ slot = htab_find_slot (m_table, tf, INSERT);
if (*slot == NULL)
*slot = tf;
}
}
-/* Create a new typedef-lookup hash table. */
+/* See typeprint.h. */
-struct typedef_hash_table *
-create_typedef_hash (void)
+typedef_hash_table::typedef_hash_table ()
{
- struct typedef_hash_table *result;
-
- result = XNEW (struct typedef_hash_table);
- result->table = htab_create_alloc (10, hash_typedef_field, eq_typedef_field,
- NULL, xcalloc, xfree);
- obstack_init (&result->storage);
-
- return result;
+ m_table = htab_create_alloc (10, hash_typedef_field, eq_typedef_field,
+ NULL, xcalloc, xfree);
}
/* Free a typedef field table. */
-void
-free_typedef_hash (struct typedef_hash_table *table)
+typedef_hash_table::~typedef_hash_table ()
{
- if (table != NULL)
- {
- htab_delete (table->table);
- obstack_free (&table->storage, NULL);
- xfree (table);
- }
+ htab_delete (m_table);
}
-/* A cleanup for freeing a typedef_hash_table. */
-
-static void
-do_free_typedef_hash (void *arg)
-{
- free_typedef_hash ((struct typedef_hash_table *) arg);
-}
-
-/* Return a new cleanup that frees TABLE. */
-
-struct cleanup *
-make_cleanup_free_typedef_hash (struct typedef_hash_table *table)
-{
- return make_cleanup (do_free_typedef_hash, table);
-}
-
-/* Helper function for copy_typedef_hash. */
+/* Helper function for typedef_hash_table::copy. */
static int
copy_typedef_hash_element (void **slot, void *nt)
return 1;
}
-/* Copy a typedef hash. */
-
-struct typedef_hash_table *
-copy_typedef_hash (struct typedef_hash_table *table)
-{
- struct typedef_hash_table *result;
-
- if (table == NULL)
- return NULL;
-
- result = create_typedef_hash ();
- htab_traverse_noresize (table->table, copy_typedef_hash_element,
- result->table);
- return result;
-}
-
-/* A cleanup to free the global typedef hash. */
-
-static void
-do_free_global_table (void *arg)
-{
- struct type_print_options *flags = (struct type_print_options *) arg;
-
- free_typedef_hash (flags->global_typedefs);
- free_ext_lang_type_printers (flags->global_printers);
-}
-
-/* Create the global typedef hash. */
+/* See typeprint.h. */
-static struct cleanup *
-create_global_typedef_table (struct type_print_options *flags)
+typedef_hash_table::typedef_hash_table (const typedef_hash_table &table)
{
- gdb_assert (flags->global_typedefs == NULL && flags->global_printers == NULL);
- flags->global_typedefs = create_typedef_hash ();
- flags->global_printers = start_ext_lang_type_printers ();
- return make_cleanup (do_free_global_table, flags);
+ m_table = htab_create_alloc (10, hash_typedef_field, eq_typedef_field,
+ NULL, xcalloc, xfree);
+ htab_traverse_noresize (table.m_table, copy_typedef_hash_element,
+ m_table);
}
/* Look up the type T in the global typedef hash. If it is found,
type-printers, if any, given by start_script_type_printers and return the
result. A NULL return means that the name was not found. */
-static const char *
-find_global_typedef (const struct type_print_options *flags,
- struct type *t)
+const char *
+typedef_hash_table::find_global_typedef (const struct type_print_options *flags,
+ struct type *t)
{
char *applied;
void **slot;
tf.name = NULL;
tf.type = t;
- slot = htab_find_slot (flags->global_typedefs->table, &tf, INSERT);
+ slot = htab_find_slot (flags->global_typedefs->m_table, &tf, INSERT);
if (*slot != NULL)
{
new_tf = (struct decl_field *) *slot;
/* Put an entry into the hash table now, in case
apply_ext_lang_type_printers recurses. */
- new_tf = XOBNEW (&flags->global_typedefs->storage, struct decl_field);
+ new_tf = XOBNEW (&flags->global_typedefs->m_storage, struct decl_field);
new_tf->name = NULL;
new_tf->type = t;
if (applied != NULL)
{
new_tf->name
- = (const char *) obstack_copy0 (&flags->global_typedefs->storage,
+ = (const char *) obstack_copy0 (&flags->global_typedefs->m_storage,
applied, strlen (applied));
xfree (applied);
}
return new_tf->name;
}
-/* Look up the type T in the typedef hash table in with FLAGS. If T
- is in the table, return its short (class-relative) typedef name.
- Otherwise return NULL. If the table is NULL, this always returns
- NULL. */
+/* See typeprint.h. */
const char *
-find_typedef_in_hash (const struct type_print_options *flags, struct type *t)
+typedef_hash_table::find_typedef (const struct type_print_options *flags,
+ struct type *t)
{
if (flags->local_typedefs != NULL)
{
tf.name = NULL;
tf.type = t;
- found = (struct decl_field *) htab_find (flags->local_typedefs->table,
+ found = (struct decl_field *) htab_find (flags->local_typedefs->m_table,
&tf);
if (found != NULL)
whatis_exp (const char *exp, int show)
{
struct value *val;
- struct cleanup *old_chain;
struct type *real_type = NULL;
struct type *type;
int full = 0;
struct value_print_options opts;
struct type_print_options flags = default_ptype_flags;
- old_chain = make_cleanup (null_cleanup, NULL);
-
if (exp)
{
if (*exp == '/')
printf_filtered ("type = ");
+ std::unique_ptr<typedef_hash_table> table_holder;
+ std::unique_ptr<ext_lang_type_printers> printer_holder;
if (!flags.raw)
- create_global_typedef_table (&flags);
+ {
+ table_holder.reset (new typedef_hash_table);
+ flags.global_typedefs = table_holder.get ();
+
+ printer_holder.reset (new ext_lang_type_printers);
+ flags.global_printers = printer_holder.get ();
+ }
if (real_type)
{
LA_PRINT_TYPE (type, "", gdb_stdout, show, 0, &flags);
printf_filtered ("\n");
-
- do_cleanups (old_chain);
}
static void
#ifndef TYPEPRINT_H
#define TYPEPRINT_H
+#include "gdb_obstack.h"
+
enum language;
struct ui_file;
struct typedef_hash_table;
/* If not NULL, a local typedef hash table used when printing a
type. */
- struct typedef_hash_table *local_typedefs;
+ typedef_hash_table *local_typedefs;
/* If not NULL, a global typedef hash table used when printing a
type. */
- struct typedef_hash_table *global_typedefs;
+ typedef_hash_table *global_typedefs;
/* The list of type printers associated with the global typedef
table. This is intentionally opaque. */
extern const struct type_print_options type_print_raw_options;
-void recursively_update_typedef_hash (struct typedef_hash_table *,
- struct type *);
+/* A hash table holding typedef_field objects. This is more
+ complicated than an ordinary hash because it must also track the
+ lifetime of some -- but not all -- of the contained objects. */
+
+class typedef_hash_table
+{
+public:
+
+ /* Create a new typedef-lookup hash table. */
+ typedef_hash_table ();
+
+ ~typedef_hash_table ();
+
+ /* Copy a typedef hash. */
+ typedef_hash_table (const typedef_hash_table &);
-void add_template_parameters (struct typedef_hash_table *, struct type *);
+ typedef_hash_table &operator= (const typedef_hash_table &) = delete;
-struct typedef_hash_table *create_typedef_hash (void);
+ /* Add typedefs from T to the hash table TABLE. */
+ void recursively_update (struct type *);
-void free_typedef_hash (struct typedef_hash_table *);
+ /* Add template parameters from T to the typedef hash TABLE. */
+ void add_template_parameters (struct type *t);
-struct cleanup *make_cleanup_free_typedef_hash (struct typedef_hash_table *);
+ /* Look up the type T in the typedef hash tables contained in FLAGS.
+ The local table is searched first, then the global table (either
+ table can be NULL, in which case it is skipped). If T is in a
+ table, return its short (class-relative) typedef name. Otherwise
+ return NULL. */
+ static const char *find_typedef (const struct type_print_options *flags,
+ struct type *t);
-struct typedef_hash_table *copy_typedef_hash (struct typedef_hash_table *);
+private:
+
+ static const char *find_global_typedef (const struct type_print_options *flags,
+ struct type *t);
+
+
+ /* The actual hash table. */
+ htab_t m_table;
+
+ /* Storage for typedef_field objects that must be synthesized. */
+ auto_obstack m_storage;
+};
-const char *find_typedef_in_hash (const struct type_print_options *,
- struct type *);
void print_type_scalar (struct type * type, LONGEST, struct ui_file *);