* c-typeprint.c (find_typedef_for_canonicalize,

print_name_maybe_canonical): New functions.
	(c_print_type): Look up type name.
	(cp_type_print_derivation_info): Add flags argument.  Use
	print_name_maybe_canonical.
	(cp_type_print_method_args): Add wrapping.
	(c_type_print_varspec_prefix): Use print_name_maybe_canonical.
	(c_type_print_template_args): New function.
	(c_type_print_base): Change wrapping.  Use
	print_name_maybe_canonical.
	<TYPE_CODE_STRUCT>: Possibly create a typedef hash, and do
	type name lookups.
	* gdbtypes.c (types_equal): No longer static.
	* gdbtypes.h (types_equal): Declare.
	* typeprint.c (type_print_raw_options, default_ptype_flags):
	Update.
	(struct typedef_hash_table): New.
	(hash_typedef_field, eq_typedef_field,
	recursively_update_typedef_hash, add_template_parameters,
	create_typedef_hash, free_typedef_hash, do_free_typedef_hash,
	make_cleanup_free_typedef_hash, copy_typedef_hash_element,
	copy_typedef_hash, find_typedef_in_hash): New functions.
	* typeprint.h (struct type_print_options) <local_typedefs>:
	New field.
	(recursively_update_typedef_hash, add_template_parameters,
	create_typedef_hash, free_typedef_hash,
	make_cleanup_free_typedef_hash, copy_typedef_hash,
	find_typedef_in_hash): Declare.
testsuite
	* gdb.base/call-sc.exp: Use "ptype/r".
	* gdb.base/volatile.exp: Don't expect "int".
	* gdb.cp/ptype-flags.cc: New file.
	* gdb.cp/ptype-flags.exp: New file.
	* gdb.cp/templates.exp: Use ptype/r.
	(test_ptype_of_templates, test_template_typedef): Likewise.
	* lib/cp-support.exp (cp_test_ptype_class): Add in_ptype_arg
	argument.  Handle template names and template parameters.
	* gdb.mi/mi-var-cmd.exp: Accept "long".
	* gdb.mi/mi-var-child.exp: Accept "long".
	* gdb.mi/mi-var-display.exp: Accept "long".
	* gdb.mi/mi2-var-child.exp: Accept "long".
This commit is contained in:
Tom Tromey 2012-11-12 17:37:38 +00:00
parent 2621e0fd5c
commit bd69fc683f
17 changed files with 879 additions and 329 deletions

View file

@ -34,6 +34,7 @@
#include "jv-lang.h"
#include "gdb_string.h"
#include <errno.h>
#include "cp-support.h"
static void c_type_print_varspec_prefix (struct type *,
struct ui_file *,
@ -45,6 +46,37 @@ static void c_type_print_modifier (struct type *,
struct ui_file *,
int, int);
/* A callback function for cp_canonicalize_string_full that uses
find_typedef_in_hash. */
static const char *
find_typedef_for_canonicalize (struct type *t, void *data)
{
return find_typedef_in_hash (data, t);
}
/* Print NAME on STREAM. If the 'raw' field of FLAGS is not set,
canonicalize NAME using the local typedefs first. */
static void
print_name_maybe_canonical (const char *name,
const struct type_print_options *flags,
struct ui_file *stream)
{
char *s = NULL;
if (!flags->raw)
s = cp_canonicalize_string_full (name,
find_typedef_for_canonicalize,
(void *) flags);
fputs_filtered (s ? s : name, stream);
xfree (s);
}
/* LEVEL is the depth to indent lines by. */
void
@ -57,27 +89,38 @@ c_print_type (struct type *type,
enum type_code code;
int demangled_args;
int need_post_space;
const char *local_name;
if (show > 0)
CHECK_TYPEDEF (type);
c_type_print_base (type, stream, show, level, flags);
code = TYPE_CODE (type);
if ((varstring != NULL && *varstring != '\0')
/* Need a space if going to print stars or brackets;
but not if we will print just a type name. */
|| ((show > 0 || TYPE_NAME (type) == 0)
&& (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
|| code == TYPE_CODE_METHOD
|| (code == TYPE_CODE_ARRAY
&& !TYPE_VECTOR (type))
|| code == TYPE_CODE_MEMBERPTR
|| code == TYPE_CODE_METHODPTR
|| code == TYPE_CODE_REF)))
fputs_filtered (" ", stream);
need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
flags);
local_name = find_typedef_in_hash (flags, type);
if (local_name != NULL)
{
fputs_filtered (local_name, stream);
if (varstring != NULL && *varstring != '\0')
fputs_filtered (" ", stream);
}
else
{
c_type_print_base (type, stream, show, level, flags);
code = TYPE_CODE (type);
if ((varstring != NULL && *varstring != '\0')
/* Need a space if going to print stars or brackets;
but not if we will print just a type name. */
|| ((show > 0 || TYPE_NAME (type) == 0)
&& (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
|| code == TYPE_CODE_METHOD
|| (code == TYPE_CODE_ARRAY
&& !TYPE_VECTOR (type))
|| code == TYPE_CODE_MEMBERPTR
|| code == TYPE_CODE_METHODPTR
|| code == TYPE_CODE_REF)))
fputs_filtered (" ", stream);
need_post_space = (varstring != NULL && strcmp (varstring, "") != 0);
c_type_print_varspec_prefix (type, stream, show, 0, need_post_space,
flags);
}
if (varstring != NULL)
{
@ -85,10 +128,13 @@ c_print_type (struct type *type,
/* For demangled function names, we have the arglist as part of
the name, so don't print an additional pair of ()'s. */
demangled_args = strchr (varstring, '(') != NULL;
c_type_print_varspec_suffix (type, stream, show,
0, demangled_args, flags);
if (local_name == NULL)
{
demangled_args = strchr (varstring, '(') != NULL;
c_type_print_varspec_suffix (type, stream, show,
0, demangled_args,
flags);
}
}
}
@ -139,13 +185,15 @@ c_print_typedef (struct type *type,
static void
cp_type_print_derivation_info (struct ui_file *stream,
struct type *type)
struct type *type,
const struct type_print_options *flags)
{
const char *name;
int i;
for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
{
wrap_here (" ");
fputs_filtered (i == 0 ? ": " : ", ", stream);
fprintf_filtered (stream, "%s%s ",
BASETYPE_VIA_PUBLIC (type, i)
@ -153,7 +201,10 @@ cp_type_print_derivation_info (struct ui_file *stream,
? "protected" : "private"),
BASETYPE_VIA_VIRTUAL (type, i) ? " virtual" : "");
name = type_name_no_tag (TYPE_BASECLASS (type, i));
fprintf_filtered (stream, "%s", name ? name : "(null)");
if (name)
print_name_maybe_canonical (name, flags, stream);
else
fprintf_filtered (stream, "(null)");
}
if (i > 0)
{
@ -191,7 +242,10 @@ cp_type_print_method_args (struct type *mtype, const char *prefix,
if (i == nargs && varargs)
fprintf_filtered (stream, ", ...");
else if (i < nargs)
fprintf_filtered (stream, ", ");
{
fprintf_filtered (stream, ", ");
wrap_here (" ");
}
}
}
else if (varargs)
@ -263,7 +317,7 @@ c_type_print_varspec_prefix (struct type *type,
stream, show, 0, 0, flags);
name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
if (name)
fputs_filtered (name, stream);
print_name_maybe_canonical (name, flags, stream);
else
c_type_print_base (TYPE_DOMAIN_TYPE (type),
stream, -1, passed_a_ptr, flags);
@ -276,7 +330,7 @@ c_type_print_varspec_prefix (struct type *type,
fprintf_filtered (stream, "(");
name = type_name_no_tag (TYPE_DOMAIN_TYPE (type));
if (name)
fputs_filtered (name, stream);
print_name_maybe_canonical (name, flags, stream);
else
c_type_print_base (TYPE_DOMAIN_TYPE (type),
stream, -1, passed_a_ptr, flags);
@ -697,6 +751,56 @@ c_type_print_varspec_suffix (struct type *type,
}
}
/* A helper for c_type_print_base that displays template
parameters and their bindings, if needed.
TABLE is the local bindings table to use. If NULL, no printing is
done. Note that, at this point, TABLE won't have any useful
information in it -- but it is also used as a flag to
print_name_maybe_canonical to activate searching the global typedef
table.
TYPE is the type whose template arguments are being displayed.
STREAM is the stream on which to print. */
static void
c_type_print_template_args (const struct type_print_options *flags,
struct type *type, struct ui_file *stream)
{
int first = 1, i;
if (flags->raw)
return;
for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
{
struct symbol *sym = TYPE_TEMPLATE_ARGUMENT (type, i);
if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
continue;
if (first)
{
wrap_here (" ");
fprintf_filtered (stream, _("[with %s = "),
SYMBOL_LINKAGE_NAME (sym));
first = 0;
}
else
{
fputs_filtered (", ", stream);
wrap_here (" ");
fprintf_filtered (stream, "%s = ", SYMBOL_LINKAGE_NAME (sym));
}
c_print_type (SYMBOL_TYPE (sym), "", stream, -1, 0, flags);
}
if (!first)
fputs_filtered (_("] "), stream);
}
/* Print the name of the type (or the ultimate pointer target,
function value or array element), or the description of a structure
or union.
@ -731,7 +835,6 @@ c_type_print_base (struct type *type, struct ui_file *stream,
QUIT;
wrap_here (" ");
if (type == NULL)
{
fputs_filtered (_("<type unknown>"), stream);
@ -749,7 +852,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
&& TYPE_NAME (type) != NULL)
{
c_type_print_modifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
return;
}
@ -778,193 +881,230 @@ c_type_print_base (struct type *type, struct ui_file *stream,
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
c_type_print_modifier (type, stream, 0, 1);
if (TYPE_CODE (type) == TYPE_CODE_UNION)
fprintf_filtered (stream, "union ");
else if (TYPE_DECLARED_CLASS (type))
fprintf_filtered (stream, "class ");
else
fprintf_filtered (stream, "struct ");
{
struct type_print_options local_flags = *flags;
struct type_print_options semi_local_flags = *flags;
struct cleanup *local_cleanups = make_cleanup (null_cleanup, NULL);
/* Print the tag if it exists. The HP aCC compiler emits a
spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed
enum}" tag for unnamed struct/union/enum's, which we don't
want to print. */
if (TYPE_TAG_NAME (type) != NULL
&& strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
{
fputs_filtered (TYPE_TAG_NAME (type), stream);
if (show > 0)
fputs_filtered (" ", stream);
}
wrap_here (" ");
if (show < 0)
{
/* If we just printed a tag name, no need to print anything
else. */
if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}");
}
else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
{
struct type *basetype;
int vptr_fieldno;
local_flags.local_typedefs = NULL;
semi_local_flags.local_typedefs = NULL;
cp_type_print_derivation_info (stream, type);
if (!flags->raw)
{
if (flags->local_typedefs)
local_flags.local_typedefs
= copy_typedef_hash (flags->local_typedefs);
else
local_flags.local_typedefs = create_typedef_hash ();
fprintf_filtered (stream, "{\n");
if (TYPE_NFIELDS (type) == 0 && TYPE_NFN_FIELDS (type) == 0
&& TYPE_TYPEDEF_FIELD_COUNT (type) == 0)
{
if (TYPE_STUB (type))
fprintfi_filtered (level + 4, stream,
_("<incomplete type>\n"));
else
fprintfi_filtered (level + 4, stream,
_("<no data fields>\n"));
}
make_cleanup_free_typedef_hash (local_flags.local_typedefs);
}
/* Start off with no specific section type, so we can print
one for the first field we find, and use that section type
thereafter until we find another type. */
c_type_print_modifier (type, stream, 0, 1);
if (TYPE_CODE (type) == TYPE_CODE_UNION)
fprintf_filtered (stream, "union ");
else if (TYPE_DECLARED_CLASS (type))
fprintf_filtered (stream, "class ");
else
fprintf_filtered (stream, "struct ");
section_type = s_none;
/* Print the tag if it exists. The HP aCC compiler emits a
spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed
enum}" tag for unnamed struct/union/enum's, which we don't
want to print. */
if (TYPE_TAG_NAME (type) != NULL
&& strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
{
/* When printing the tag name, we are still effectively
printing in the outer context, hence the use of FLAGS
here. */
print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream);
if (show > 0)
fputs_filtered (" ", stream);
}
/* For a class, if all members are private, there's no need
for a "private:" label; similarly, for a struct or union
masquerading as a class, if all members are public, there's
no need for a "public:" label. */
if (show < 0)
{
/* If we just printed a tag name, no need to print anything
else. */
if (TYPE_TAG_NAME (type) == NULL)
fprintf_filtered (stream, "{...}");
}
else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
{
struct type *basetype;
int vptr_fieldno;
if (TYPE_DECLARED_CLASS (type))
{
QUIT;
len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
if (!TYPE_FIELD_PRIVATE (type, i))
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);
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);
/* Now add in the local typedefs. */
recursively_update_typedef_hash (local_flags.local_typedefs, type);
fprintf_filtered (stream, "{\n");
if (TYPE_NFIELDS (type) == 0 && TYPE_NFN_FIELDS (type) == 0
&& TYPE_TYPEDEF_FIELD_COUNT (type) == 0)
{
if (TYPE_STUB (type))
fprintfi_filtered (level + 4, stream,
_("<incomplete type>\n"));
else
fprintfi_filtered (level + 4, stream,
_("<no data fields>\n"));
}
/* Start off with no specific section type, so we can print
one for the first field we find, and use that section type
thereafter until we find another type. */
section_type = s_none;
/* For a class, if all members are private, there's no need
for a "private:" label; similarly, for a struct or union
masquerading as a class, if all members are public, there's
no need for a "public:" label. */
if (TYPE_DECLARED_CLASS (type))
{
QUIT;
len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
if (!TYPE_FIELD_PRIVATE (type, i))
{
need_access_label = 1;
break;
}
QUIT;
if (!need_access_label)
{
need_access_label = 1;
break;
len2 = TYPE_NFN_FIELDS (type);
for (j = 0; j < len2; j++)
{
len = TYPE_FN_FIELDLIST_LENGTH (type, j);
for (i = 0; i < len; i++)
if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
j), i))
{
need_access_label = 1;
break;
}
if (need_access_label)
break;
}
}
QUIT;
if (!need_access_label)
{
len2 = TYPE_NFN_FIELDS (type);
for (j = 0; j < len2; j++)
}
else
{
QUIT;
len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
if (TYPE_FIELD_PRIVATE (type, i)
|| TYPE_FIELD_PROTECTED (type, i))
{
len = TYPE_FN_FIELDLIST_LENGTH (type, j);
for (i = 0; i < len; i++)
if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
j), i))
{
need_access_label = 1;
break;
}
if (need_access_label)
break;
need_access_label = 1;
break;
}
}
}
else
{
QUIT;
len = TYPE_NFIELDS (type);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
if (TYPE_FIELD_PRIVATE (type, i)
|| TYPE_FIELD_PROTECTED (type, i))
QUIT;
if (!need_access_label)
{
need_access_label = 1;
break;
len2 = TYPE_NFN_FIELDS (type);
for (j = 0; j < len2; j++)
{
QUIT;
len = TYPE_FN_FIELDLIST_LENGTH (type, j);
for (i = 0; i < len; i++)
if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type,
j), i)
|| TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
j),
i))
{
need_access_label = 1;
break;
}
if (need_access_label)
break;
}
}
QUIT;
if (!need_access_label)
{
len2 = TYPE_NFN_FIELDS (type);
for (j = 0; j < len2; j++)
{
QUIT;
len = TYPE_FN_FIELDLIST_LENGTH (type, j);
for (i = 0; i < len; i++)
if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type,
j), i)
|| TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
j),
i))
}
/* If there is a base class for this type,
do not print the field that it occupies. */
len = TYPE_NFIELDS (type);
vptr_fieldno = get_vptr_fieldno (type, &basetype);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
{
QUIT;
/* If we have a virtual table pointer, omit it. Even if
virtual table pointers are not specifically marked in
the debug info, they should be artificial. */
if ((i == vptr_fieldno && type == basetype)
|| TYPE_FIELD_ARTIFICIAL (type, i))
continue;
if (need_access_label)
{
if (TYPE_FIELD_PROTECTED (type, i))
{
if (section_type != s_protected)
{
need_access_label = 1;
break;
section_type = s_protected;
fprintfi_filtered (level + 2, stream,
"protected:\n");
}
if (need_access_label)
break;
}
}
}
}
else if (TYPE_FIELD_PRIVATE (type, i))
{
if (section_type != s_private)
{
section_type = s_private;
fprintfi_filtered (level + 2, stream,
"private:\n");
}
}
else
{
if (section_type != s_public)
{
section_type = s_public;
fprintfi_filtered (level + 2, stream,
"public:\n");
}
}
}
/* If there is a base class for this type,
do not print the field that it occupies. */
len = TYPE_NFIELDS (type);
vptr_fieldno = get_vptr_fieldno (type, &basetype);
for (i = TYPE_N_BASECLASSES (type); i < len; i++)
{
QUIT;
/* If we have a virtual table pointer, omit it. Even if
virtual table pointers are not specifically marked in
the debug info, they should be artificial. */
if ((i == vptr_fieldno && type == basetype)
|| TYPE_FIELD_ARTIFICIAL (type, i))
continue;
if (need_access_label)
{
if (TYPE_FIELD_PROTECTED (type, i))
{
if (section_type != s_protected)
{
section_type = s_protected;
fprintfi_filtered (level + 2, stream,
"protected:\n");
}
}
else if (TYPE_FIELD_PRIVATE (type, i))
{
if (section_type != s_private)
{
section_type = s_private;
fprintfi_filtered (level + 2, stream,
"private:\n");
}
}
else
{
if (section_type != s_public)
{
section_type = s_public;
fprintfi_filtered (level + 2, stream,
"public:\n");
}
}
}
print_spaces_filtered (level + 4, stream);
if (field_is_static (&TYPE_FIELD (type, i)))
fprintf_filtered (stream, "static ");
c_print_type (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4, flags);
if (!field_is_static (&TYPE_FIELD (type, i))
&& TYPE_FIELD_PACKED (type, i))
{
/* It is a bitfield. This code does not attempt
to look at the bitpos and reconstruct filler,
unnamed fields. This would lead to misleading
results if the compiler does not put out fields
for such things (I don't know what it does). */
fprintf_filtered (stream, " : %d",
TYPE_FIELD_BITSIZE (type, i));
}
fprintf_filtered (stream, ";\n");
}
print_spaces_filtered (level + 4, stream);
if (field_is_static (&TYPE_FIELD (type, i)))
fprintf_filtered (stream, "static ");
c_print_type (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4,
&local_flags);
if (!field_is_static (&TYPE_FIELD (type, i))
&& TYPE_FIELD_PACKED (type, i))
{
/* It is a bitfield. This code does not attempt
to look at the bitpos and reconstruct filler,
unnamed fields. This would lead to misleading
results if the compiler does not put out fields
for such things (I don't know what it does). */
fprintf_filtered (stream, " : %d",
TYPE_FIELD_BITSIZE (type, i));
}
fprintf_filtered (stream, ";\n");
}
/* If there are both fields and methods, put a blank line
between them. Make sure to count only method that we
@ -1062,7 +1202,8 @@ c_type_print_base (struct type *type, struct ui_file *stream,
&& !is_type_conversion_operator (type, i, j))
{
c_print_type (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
"", stream, -1, 0, flags);
"", stream, -1, 0,
&local_flags);
fputs_filtered (" ", stream);
}
if (TYPE_FN_FIELD_STUB (f, j))
@ -1083,10 +1224,10 @@ c_type_print_base (struct type *type, struct ui_file *stream,
if (demangled_name == NULL)
{
/* In some cases (for instance with the HP
demangling), if a function has more than 10
arguments, the demangling will fail.
Let's try to reconstruct the function
signature from the symbol information. */
demangling), if a function has more than 10
arguments, the demangling will fail.
Let's try to reconstruct the function
signature from the symbol information. */
if (!TYPE_FN_FIELD_STUB (f, j))
{
int staticp = TYPE_FN_FIELD_STATIC_P (f, j);
@ -1096,7 +1237,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
"",
method_name,
staticp,
stream, flags);
stream, &local_flags);
}
else
fprintf_filtered (stream,
@ -1143,30 +1284,40 @@ c_type_print_base (struct type *type, struct ui_file *stream,
if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0)
fprintf_filtered (stream, "\n");
for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
{
struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);
for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
{
struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);
struct typedef_hash_table *table2;
/* Dereference the typedef declaration itself. */
gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF);
target = TYPE_TARGET_TYPE (target);
/* Dereference the typedef declaration itself. */
gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF);
target = TYPE_TARGET_TYPE (target);
print_spaces_filtered (level + 4, stream);
fprintf_filtered (stream, "typedef ");
c_print_type (target, TYPE_TYPEDEF_FIELD_NAME (type, i),
stream, show - 1, level + 4, flags);
fprintf_filtered (stream, ";\n");
}
}
print_spaces_filtered (level + 4, stream);
fprintf_filtered (stream, "typedef ");
fprintfi_filtered (level, stream, "}");
/* We want to print typedefs with substitutions
from the template parameters or globally-known
typedefs but not local typedefs. */
c_print_type (target,
TYPE_TYPEDEF_FIELD_NAME (type, i),
stream, show - 1, level + 4,
&semi_local_flags);
fprintf_filtered (stream, ";\n");
}
}
if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
fprintfi_filtered (level,
stream, _(" (Local at %s:%d)\n"),
TYPE_LOCALTYPE_FILE (type),
TYPE_LOCALTYPE_LINE (type));
}
fprintfi_filtered (level, stream, "}");
if (TYPE_LOCALTYPE_PTR (type) && show >= 0)
fprintfi_filtered (level,
stream, _(" (Local at %s:%d)\n"),
TYPE_LOCALTYPE_FILE (type),
TYPE_LOCALTYPE_LINE (type));
}
do_cleanups (local_cleanups);
}
break;
case TYPE_CODE_ENUM:
@ -1180,7 +1331,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
if (TYPE_TAG_NAME (type) != NULL
&& strncmp (TYPE_TAG_NAME (type), "{unnamed", 8))
{
fputs_filtered (TYPE_TAG_NAME (type), stream);
print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream);
if (show > 0)
fputs_filtered (" ", stream);
}
@ -1248,7 +1399,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
if (TYPE_NAME (type) != NULL)
{
c_type_print_modifier (type, stream, 0, 1);
fputs_filtered (TYPE_NAME (type), stream);
print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
}
else
{