+ else
+ {
+ /* The position of the field, relative to the beginning of the
+ struct. */
+ fprintf_filtered (stream, "/* %4u",
+ (bitpos + offset_bitpos) / TARGET_CHAR_BIT);
+
+ fprintf_filtered (stream, " ");
+ }
+
+ fprintf_filtered (stream, " | %4u */", fieldsize_byte);
+
+ end_bitpos = bitpos + fieldsize_bit;
+}
+
+/* See typeprint.h. */
+
+void
+print_offset_data::finish (struct type *type, int level,
+ struct ui_file *stream)
+{
+ unsigned int bitpos = TYPE_LENGTH (type) * TARGET_CHAR_BIT;
+ maybe_print_hole (stream, bitpos, "padding");
+
+ fputs_filtered ("\n", stream);
+ print_spaces_filtered (level + 4 + print_offset_data::indentation, stream);
+ fprintf_filtered (stream, "/* total size (bytes): %4s */\n",
+ pulongest (TYPE_LENGTH (type)));
+}
+
+\f
+
+/* A hash function for a typedef_field. */
+
+static hashval_t
+hash_typedef_field (const void *p)
+{
+ const struct decl_field *tf = (const struct decl_field *) p;
+ struct type *t = check_typedef (tf->type);
+
+ return htab_hash_string (TYPE_SAFE_NAME (t));
+}
+
+/* An equality function for a typedef field. */
+
+static int
+eq_typedef_field (const void *a, const void *b)
+{
+ const struct decl_field *tfa = (const struct decl_field *) a;
+ const struct decl_field *tfb = (const struct decl_field *) b;
+
+ return types_equal (tfa->type, tfb->type);
+}
+
+/* See typeprint.h. */
+
+void
+typedef_hash_table::recursively_update (struct type *t)
+{
+ int i;
+
+ 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 (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. */
+ if (*slot == NULL)
+ *slot = tdef;
+ }
+
+ /* Recurse into superclasses. */
+ for (i = 0; i < TYPE_N_BASECLASSES (t); ++i)
+ recursively_update (TYPE_BASECLASS (t, i));
+}
+
+/* See typeprint.h. */
+
+void
+typedef_hash_table::add_template_parameters (struct type *t)
+{
+ int i;
+
+ for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (t); ++i)
+ {
+ struct decl_field *tf;
+ void **slot;
+
+ /* We only want type-valued template parameters in the hash. */
+ if (SYMBOL_CLASS (TYPE_TEMPLATE_ARGUMENT (t, i)) != LOC_TYPEDEF)
+ continue;
+
+ tf = XOBNEW (&m_storage, struct decl_field);
+ tf->name = TYPE_TEMPLATE_ARGUMENT (t, i)->linkage_name ();
+ tf->type = SYMBOL_TYPE (TYPE_TEMPLATE_ARGUMENT (t, i));
+
+ slot = htab_find_slot (m_table, tf, INSERT);
+ if (*slot == NULL)
+ *slot = tf;
+ }
+}
+
+/* See typeprint.h. */
+
+typedef_hash_table::typedef_hash_table ()
+{
+ m_table = htab_create_alloc (10, hash_typedef_field, eq_typedef_field,
+ NULL, xcalloc, xfree);
+}
+
+/* Free a typedef field table. */
+
+typedef_hash_table::~typedef_hash_table ()
+{
+ htab_delete (m_table);
+}
+
+/* Helper function for typedef_hash_table::copy. */
+
+static int
+copy_typedef_hash_element (void **slot, void *nt)
+{
+ htab_t new_table = (htab_t) nt;
+ void **new_slot;
+
+ new_slot = htab_find_slot (new_table, *slot, INSERT);
+ if (*new_slot == NULL)
+ *new_slot = *slot;
+
+ return 1;
+}
+
+/* See typeprint.h. */
+
+typedef_hash_table::typedef_hash_table (const typedef_hash_table &table)
+{
+ 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,
+ return the typedef name. If it is not found, apply the
+ type-printers, if any, given by start_script_type_printers and return the
+ result. A NULL return means that the name was not found. */
+
+const char *
+typedef_hash_table::find_global_typedef (const struct type_print_options *flags,
+ struct type *t)
+{
+ char *applied;
+ void **slot;
+ struct decl_field tf, *new_tf;
+
+ if (flags->global_typedefs == NULL)
+ return NULL;
+
+ tf.name = NULL;
+ tf.type = t;
+
+ slot = htab_find_slot (flags->global_typedefs->m_table, &tf, INSERT);
+ if (*slot != NULL)
+ {
+ new_tf = (struct decl_field *) *slot;
+ return new_tf->name;
+ }
+
+ /* Put an entry into the hash table now, in case
+ apply_ext_lang_type_printers recurses. */
+ new_tf = XOBNEW (&flags->global_typedefs->m_storage, struct decl_field);
+ new_tf->name = NULL;
+ new_tf->type = t;
+
+ *slot = new_tf;
+
+ applied = apply_ext_lang_type_printers (flags->global_printers, t);
+
+ if (applied != NULL)
+ {
+ new_tf->name = obstack_strdup (&flags->global_typedefs->m_storage,
+ applied);
+ xfree (applied);
+ }
+
+ return new_tf->name;
+}
+
+/* See typeprint.h. */
+
+const char *
+typedef_hash_table::find_typedef (const struct type_print_options *flags,
+ struct type *t)
+{
+ if (flags->local_typedefs != NULL)
+ {
+ struct decl_field tf, *found;
+
+ tf.name = NULL;
+ tf.type = t;
+ found = (struct decl_field *) htab_find (flags->local_typedefs->m_table,
+ &tf);
+
+ if (found != NULL)
+ return found->name;
+ }
+
+ return find_global_typedef (flags, t);
+}
+
+\f
+
+/* Print a description of a type in the format of a
+ typedef for the current language.
+ NEW is the new name for a type TYPE. */
+
+void
+typedef_print (struct type *type, struct symbol *newobj, struct ui_file *stream)
+{
+ LA_PRINT_TYPEDEF (type, newobj, stream);
+}
+
+/* The default way to print a typedef. */
+
+void
+default_print_typedef (struct type *type, struct symbol *new_symbol,
+ struct ui_file *stream)
+{
+ error (_("Language not supported."));