* 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:
parent
2621e0fd5c
commit
bd69fc683f
17 changed files with 879 additions and 329 deletions
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue