diff options
-rw-r--r-- | gdb/ChangeLog | 39 | ||||
-rw-r--r-- | gdb/c-typeprint.c | 41 | ||||
-rw-r--r-- | gdb/extension.c | 19 | ||||
-rw-r--r-- | gdb/extension.h | 9 | ||||
-rw-r--r-- | gdb/typeprint.c | 156 | ||||
-rw-r--r-- | gdb/typeprint.h | 54 |
6 files changed, 153 insertions, 165 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8cbb725..a3e99e6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,44 @@ 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>. 2018-03-27 Joel Brobecker <brobecker@adacore.com> diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 2e9ed1b..1a8af78 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -68,12 +68,13 @@ static void c_type_print_base_1 (struct type *type, struct ui_file *stream, /* 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, @@ -114,7 +115,7 @@ c_print_type_1 (struct type *type, 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); @@ -1109,21 +1110,18 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *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); @@ -1164,18 +1162,25 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, 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"); @@ -1518,8 +1523,6 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream, fprintfi_filtered (level, stream, "}"); } - - do_cleanups (local_cleanups); } /* Print the name of the type (or the ultimate pointer target, diff --git a/gdb/extension.c b/gdb/extension.c index 4e3b3e9..e5c0146 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -405,21 +405,16 @@ auto_load_ext_lang_scripts_for_objfile (struct objfile *objfile) 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 @@ -460,11 +455,7 @@ apply_ext_lang_type_printers (struct ext_lang_type_printers *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; @@ -472,10 +463,8 @@ free_ext_lang_type_printers (struct ext_lang_type_printers *printers) 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); } /* Try to pretty-print a value of type TYPE located at VAL's contents diff --git a/gdb/extension.h b/gdb/extension.h index c675ae2..abde5e5 100644 --- a/gdb/extension.h +++ b/gdb/extension.h @@ -146,6 +146,11 @@ enum ext_lang_bp_stop 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; }; @@ -273,13 +278,9 @@ extern void eval_ext_lang_from_control_command (struct command_line *cmd); 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, diff --git a/gdb/typeprint.c b/gdb/typeprint.c index c098a3f..222fc0a 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -65,19 +65,6 @@ static struct type_print_options default_ptype_flags = -/* 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 @@ -100,23 +87,19 @@ eq_typedef_field (const void *a, const void *b) 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. */ @@ -126,19 +109,16 @@ recursively_update_typedef_hash (struct typedef_hash_table *table, /* 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; @@ -148,61 +128,32 @@ add_template_parameters (struct typedef_hash_table *table, struct type *t) 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) @@ -217,42 +168,14 @@ 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, @@ -260,9 +183,9 @@ create_global_typedef_table (struct type_print_options *flags) 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; @@ -274,7 +197,7 @@ find_global_typedef (const struct type_print_options *flags, 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; @@ -283,7 +206,7 @@ find_global_typedef (const struct type_print_options *flags, /* 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; @@ -294,7 +217,7 @@ find_global_typedef (const struct type_print_options *flags, 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); } @@ -302,13 +225,11 @@ find_global_typedef (const struct type_print_options *flags, 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) { @@ -316,7 +237,7 @@ find_typedef_in_hash (const struct type_print_options *flags, struct type *t) 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) @@ -406,7 +327,6 @@ static void 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; @@ -415,8 +335,6 @@ whatis_exp (const char *exp, int show) struct value_print_options opts; struct type_print_options flags = default_ptype_flags; - old_chain = make_cleanup (null_cleanup, NULL); - if (exp) { if (*exp == '/') @@ -526,8 +444,16 @@ whatis_exp (const char *exp, int show) 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) { @@ -540,8 +466,6 @@ whatis_exp (const char *exp, int show) LA_PRINT_TYPE (type, "", gdb_stdout, show, 0, &flags); printf_filtered ("\n"); - - do_cleanups (old_chain); } static void diff --git a/gdb/typeprint.h b/gdb/typeprint.h index ba9588a..895eebd 100644 --- a/gdb/typeprint.h +++ b/gdb/typeprint.h @@ -19,6 +19,8 @@ #ifndef TYPEPRINT_H #define TYPEPRINT_H +#include "gdb_obstack.h" + enum language; struct ui_file; struct typedef_hash_table; @@ -57,11 +59,11 @@ struct type_print_options /* 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. */ @@ -70,21 +72,51 @@ struct type_print_options 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 *); |