+static void ptype_command (char *, int);
+
+static void whatis_command (char *, int);
+
+static void whatis_exp (char *, int);
+
+const struct type_print_options type_print_raw_options =
+{
+ 1, /* raw */
+ 1, /* print_methods */
+ 1, /* print_typedefs */
+ NULL, /* local_typedefs */
+ NULL, /* global_table */
+ NULL /* global_printers */
+};
+
+/* The default flags for 'ptype' and 'whatis'. */
+
+static struct type_print_options default_ptype_flags =
+{
+ 0, /* raw */
+ 1, /* print_methods */
+ 1, /* print_typedefs */
+ NULL, /* local_typedefs */
+ NULL, /* global_table */
+ NULL /* global_printers */
+};
+
+\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
+hash_typedef_field (const void *p)
+{
+ const struct typedef_field *tf = (const struct typedef_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 typedef_field *tfa = (const struct typedef_field *) a;
+ const struct typedef_field *tfb = (const struct typedef_field *) b;
+
+ return types_equal (tfa->type, tfb->type);
+}
+
+/* Add typedefs from T to the hash table TABLE. */
+
+void
+recursively_update_typedef_hash (struct typedef_hash_table *table,
+ struct type *t)
+{
+ int i;
+
+ if (table == NULL)
+ return;
+
+ for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (t); ++i)
+ {
+ struct typedef_field *tdef = &TYPE_TYPEDEF_FIELD (t, i);
+ void **slot;
+
+ slot = htab_find_slot (table->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_typedef_hash (table, TYPE_BASECLASS (t, i));
+}
+
+/* Add template parameters from T to the typedef hash TABLE. */
+
+void
+add_template_parameters (struct typedef_hash_table *table, struct type *t)
+{
+ int i;
+
+ if (table == NULL)
+ return;
+
+ for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (t); ++i)
+ {
+ struct typedef_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 (&table->storage, struct typedef_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);
+ if (*slot == NULL)
+ *slot = tf;
+ }
+}
+
+/* Create a new typedef-lookup hash table. */
+
+struct typedef_hash_table *
+create_typedef_hash (void)
+{
+ 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;
+}
+
+/* Free a typedef field table. */
+
+void
+free_typedef_hash (struct typedef_hash_table *table)
+{
+ if (table != NULL)
+ {
+ htab_delete (table->table);
+ obstack_free (&table->storage, NULL);
+ xfree (table);
+ }
+}