mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-15 04:31:49 +08:00
* 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
@ -1,3 +1,34 @@
|
||||
2012-11-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2012-11-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* cp-support.c (inspect_type,
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -2406,7 +2406,7 @@ integer_types_same_name_p (const char *first, const char *second)
|
||||
/* Compares type A to type B returns 1 if the represent the same type
|
||||
0 otherwise. */
|
||||
|
||||
static int
|
||||
int
|
||||
types_equal (struct type *a, struct type *b)
|
||||
{
|
||||
/* Identical type pointers. */
|
||||
|
@ -1657,4 +1657,6 @@ extern struct type *copy_type_recursive (struct objfile *objfile,
|
||||
|
||||
extern struct type *copy_type (const struct type *type);
|
||||
|
||||
extern int types_equal (struct type *, struct type *);
|
||||
|
||||
#endif /* GDBTYPES_H */
|
||||
|
@ -1,3 +1,18 @@
|
||||
2012-11-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* 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".
|
||||
|
||||
2012-11-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.cp/classes.exp (test_ptype_class_objects): Remove
|
||||
|
@ -89,13 +89,13 @@ proc start_scalars_test { type } {
|
||||
# check that type matches what was passed in
|
||||
set test "ptype; ${testfile}"
|
||||
set foo_t "xxx"
|
||||
gdb_test_multiple "ptype ${type}" "${test}" {
|
||||
gdb_test_multiple "ptype/r ${type}" "${test}" {
|
||||
-re "type = (\[^\r\n\]*)\r\n$gdb_prompt $" {
|
||||
set foo_t "$expect_out(1,string)"
|
||||
pass "$test (${foo_t})"
|
||||
}
|
||||
}
|
||||
gdb_test "ptype foo" "type = ${foo_t}" "ptype foo; ${testfile} $expect_out(1,string)"
|
||||
gdb_test "ptype/r foo" "type = ${foo_t}" "ptype foo; ${testfile} $expect_out(1,string)"
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,7 +156,7 @@ local_compiler_xfail_check
|
||||
gdb_test "ptype veneer" "type = volatile short( int)? \\* volatile.*"
|
||||
|
||||
local_compiler_xfail_check
|
||||
gdb_test "ptype video" "type = volatile (unsigned short|short unsigned)( int) \\* volatile.*"
|
||||
gdb_test "ptype video" "type = volatile (unsigned short|short unsigned) \\* volatile.*"
|
||||
|
||||
local_compiler_xfail_check
|
||||
gdb_test "ptype vacuum" "type = volatile long( int)? \\* volatile.*"
|
||||
|
47
gdb/testsuite/gdb.cp/ptype-flags.cc
Normal file
47
gdb/testsuite/gdb.cp/ptype-flags.cc
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright 2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template<typename S>
|
||||
class Simple
|
||||
{
|
||||
S val;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Base
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Holder : public Base<T>
|
||||
{
|
||||
public:
|
||||
Simple<T> t;
|
||||
Simple<T*> tstar;
|
||||
|
||||
typedef Simple< Simple<T> > Z;
|
||||
|
||||
Z z;
|
||||
|
||||
double method(void) { return 23.0; }
|
||||
};
|
||||
|
||||
Holder<int> value;
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
85
gdb/testsuite/gdb.cp/ptype-flags.exp
Normal file
85
gdb/testsuite/gdb.cp/ptype-flags.exp
Normal file
@ -0,0 +1,85 @@
|
||||
# Copyright 2012 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
set nl "\[\r\n\]+"
|
||||
|
||||
if { [skip_cplus_tests] } { continue }
|
||||
|
||||
load_lib "cp-support.exp"
|
||||
|
||||
standard_testfile .cc
|
||||
|
||||
if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] then {
|
||||
perror "couldn't run to breakpoint"
|
||||
return
|
||||
}
|
||||
|
||||
gdb_test_no_output "set language c++" ""
|
||||
gdb_test_no_output "set width 0" ""
|
||||
|
||||
proc do_check {name {flags ""} {show_typedefs 1} {show_methods 1} {raw 0}} {
|
||||
set contents {
|
||||
{ base "public Base<T>" }
|
||||
{ field public "Simple<T> t;" }
|
||||
{ field public "Simple<T*> tstar;" }
|
||||
}
|
||||
|
||||
if {$raw} {
|
||||
lappend contents { field public "Holder<int>::Z z;" }
|
||||
} else {
|
||||
lappend contents { field public "Z z;" }
|
||||
}
|
||||
|
||||
if {$show_typedefs} {
|
||||
lappend contents { typedef public "typedef Simple<Simple<T> > Z;" }
|
||||
}
|
||||
|
||||
if {$show_methods} {
|
||||
lappend contents { method public "double method();" }
|
||||
}
|
||||
|
||||
if {$raw} {
|
||||
regsub -all -- "T" $contents "int" contents
|
||||
}
|
||||
|
||||
cp_test_ptype_class value $name "class" "Holder<int>" $contents \
|
||||
"" {} $flags
|
||||
}
|
||||
|
||||
do_check "basic test"
|
||||
do_check "no methods" "/m" 1 0
|
||||
do_check "no typedefs" "/t" 0 1
|
||||
do_check "no methods or typedefs" "/mt" 0 0
|
||||
|
||||
do_check "raw" "/r" 1 1 1
|
||||
do_check "raw no methods" "/rm" 1 0 1
|
||||
do_check "raw no typedefs" "/rt" 0 1 1
|
||||
do_check "raw no methods or typedefs" "/rmt" 0 0 1
|
||||
|
||||
gdb_test_no_output "set print type methods off"
|
||||
do_check "basic test, default methods off" "" 1 0
|
||||
do_check "methods, default methods off" "/M" 1 1
|
||||
do_check "no typedefs, default methods off" "/t" 0 0
|
||||
do_check "methods, no typedefs, default methods off" "/Mt" 0 1
|
||||
|
||||
gdb_test_no_output "set print type typedefs off"
|
||||
do_check "basic test, default methods+typedefs off" "" 0 0
|
||||
do_check "methods, default methods+typedefs off" "/M" 0 1
|
||||
do_check "typedefs, default methods+typedefs off" "/T" 1 0
|
||||
do_check "methods typedefs, default methods+typedefs off" "/MT" 1 1
|
@ -40,7 +40,7 @@ proc test_ptype_of_templates {} {
|
||||
global gdb_prompt
|
||||
global ws
|
||||
|
||||
gdb_test_multiple "ptype T5<int>" "ptype T5<int>" {
|
||||
gdb_test_multiple "ptype/r T5<int>" "ptype T5<int>" {
|
||||
-re "type = class T5<int> \{${ws}public:${ws}static int X;${ws}int x;${ws}int val;${ws}T5<int> & operator=\\(T5<int> const ?&\\);${ws}T5\\(int\\);${ws}T5\\((T5<int> const|const T5<int>) ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\}\r\n$gdb_prompt $" {
|
||||
xfail "ptype T5<int> -- new without size_t"
|
||||
}
|
||||
@ -63,7 +63,7 @@ proc test_ptype_of_templates {} {
|
||||
}
|
||||
}
|
||||
|
||||
gdb_test_multiple "ptype t5i" "ptype t5i" {
|
||||
gdb_test_multiple "ptype/r t5i" "ptype t5i" {
|
||||
-re "type = class T5<int> \\{${ws}public:${ws}static int X;${ws}int x;${ws}int val;\r\n${ws}T5\\(int\\);${ws}T5\\(T5<int> const ?&\\);${ws}~T5\\((void|)\\);${ws}static void \\* operator new\\(unsigned( int| long)?\\);${ws}static void operator delete\\(void ?\\*\\);${ws}int value\\((void|)\\);${ws}\\}\r\n$gdb_prompt $" {
|
||||
xfail "ptype T5<int> -- with several fixes from 4.17 -- without size_t"
|
||||
}
|
||||
@ -226,11 +226,13 @@ proc test_template_typedef {} {
|
||||
proc test_template_args {} {
|
||||
|
||||
set empty_re "Empty *<void *\\(FunctionArg *<int>\\)>"
|
||||
gdb_test "ptype empty" \
|
||||
"type = (struct|class) $empty_re {.*<no data fields>.*}"
|
||||
gdb_test "ptype/r empty" \
|
||||
"type = (struct|class) $empty_re {.*<no data fields>.*}" \
|
||||
"ptype empty"
|
||||
|
||||
gdb_test "ptype arg" \
|
||||
"type = (struct|class) FunctionArg<int> {.*int method\\($empty_re \\&\\);.*}"
|
||||
gdb_test "ptype/r arg" \
|
||||
"type = (struct|class) FunctionArg<int> {.*int method\\($empty_re \\&\\);.*}" \
|
||||
"ptype arg"
|
||||
}
|
||||
|
||||
proc do_tests {} {
|
||||
@ -291,7 +293,7 @@ gdb_test "print fvpchar" \
|
||||
# NOTE: carlton/2003-02-26: However, because of a bug in the way GDB
|
||||
# handles nested types, we don't get this right in the DWARF-2 case.
|
||||
|
||||
gdb_test_multiple "ptype Foo" "ptype Foo" {
|
||||
gdb_test_multiple "ptype/r Foo" "ptype Foo" {
|
||||
-re "type = template <(class |)T> (class |)Foo \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Foo<volatile char \\*>\r\n\[ \t\]*(class |)Foo<char>\r\n\[ \t\]*(class |)Foo<int>\r\n$gdb_prompt $" {
|
||||
pass "ptype Foo"
|
||||
}
|
||||
@ -312,7 +314,7 @@ gdb_test_multiple "ptype Foo" "ptype Foo" {
|
||||
|
||||
# ptype Foo<int>
|
||||
|
||||
gdb_test_multiple "ptype fint" "ptype fint" {
|
||||
gdb_test_multiple "ptype/r fint" "ptype fint" {
|
||||
-re "type = (class |)Foo<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int foo\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype fint"
|
||||
}
|
||||
@ -323,7 +325,7 @@ gdb_test_multiple "ptype fint" "ptype fint" {
|
||||
|
||||
# ptype Foo<char>
|
||||
|
||||
gdb_test_multiple "ptype fchar" "ptype fchar" {
|
||||
gdb_test_multiple "ptype/r fchar" "ptype fchar" {
|
||||
-re "type = (class |)Foo<char> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*.*char foo\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype fchar"
|
||||
}
|
||||
@ -334,7 +336,7 @@ gdb_test_multiple "ptype fchar" "ptype fchar" {
|
||||
|
||||
# ptype Foo<volatile char *>
|
||||
|
||||
gdb_test_multiple "ptype fvpchar" "ptype fvpchar" {
|
||||
gdb_test_multiple "ptype/r fvpchar" "ptype fvpchar" {
|
||||
-re "type = (class |)Foo<volatile char ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*char.*\\*t;\r\n\r\n\[ \t\]*.*char \\* foo\\(int,.*char.*\\*\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype fvpchar"
|
||||
}
|
||||
@ -374,7 +376,7 @@ gdb_test_multiple "print Foo<volatile char*>::foo" "print Foo<volatile char*>::f
|
||||
# Template Bar<T, int>
|
||||
|
||||
# same as Foo for g++
|
||||
gdb_test_multiple "ptype Bar" "ptype Bar" {
|
||||
gdb_test_multiple "ptype/r Bar" "ptype Bar" {
|
||||
-re "type = template <(class |)T, (class |)sz> (class |)Bar \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Bar<int,(\\(int\\)|)1>\r\n\[ \t\]*(class |)Bar<int,(\\(int\\)|)33>\r\n$gdb_prompt $" {
|
||||
pass "ptype Bar"
|
||||
}
|
||||
@ -394,7 +396,7 @@ gdb_test_multiple "ptype Bar" "ptype Bar" {
|
||||
|
||||
# ptype Bar<int,33>
|
||||
|
||||
gdb_test_multiple "ptype bint" "ptype bint" {
|
||||
gdb_test_multiple "ptype/r bint" "ptype bint" {
|
||||
-re "type = (class |)Bar<int, ?(\\(int\\)|)33> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype bint"
|
||||
}
|
||||
@ -405,7 +407,7 @@ gdb_test_multiple "ptype bint" "ptype bint" {
|
||||
|
||||
# ptype Bar<int, (4>3)>
|
||||
|
||||
gdb_test_multiple "ptype bint2" "ptype bint2" {
|
||||
gdb_test_multiple "ptype/r bint2" "ptype bint2" {
|
||||
-re "type = (class |)Bar<int, ?(\\(int\\)|)1> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int bar\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype bint2"
|
||||
}
|
||||
@ -417,7 +419,7 @@ gdb_test_multiple "ptype bint2" "ptype bint2" {
|
||||
# Template Baz<T, char>
|
||||
|
||||
# Same as Foo, for g++
|
||||
gdb_test_multiple "ptype Baz" "ptype Baz" {
|
||||
gdb_test_multiple "ptype/r Baz" "ptype Baz" {
|
||||
-re "type = template <(class |)T, ?(class |)sz> (class |)Baz \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Baz<char,(\\(char\\)|)97>\r\n\[ \t\]*(class |)Baz<int,(\\(char\\)|)115>\r\n$gdb_prompt $" {
|
||||
pass "ptype Baz"
|
||||
}
|
||||
@ -441,7 +443,7 @@ gdb_test_multiple "ptype Baz" "ptype Baz" {
|
||||
|
||||
# ptype Baz<int, 's'>
|
||||
|
||||
gdb_test_multiple "ptype bazint" "ptype bazint" {
|
||||
gdb_test_multiple "ptype/r bazint" "ptype bazint" {
|
||||
-re "type = (class |)Baz<int, ?(\\(char\\)|)(115|\\'s\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int baz\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype bazint"
|
||||
}
|
||||
@ -452,7 +454,7 @@ gdb_test_multiple "ptype bazint" "ptype bazint" {
|
||||
|
||||
# ptype Baz<char, 'a'>
|
||||
|
||||
gdb_test_multiple "ptype bazint2" "ptype bazint2" {
|
||||
gdb_test_multiple "ptype/r bazint2" "ptype bazint2" {
|
||||
-re "type = (class |)Baz<char, ?(\\(char\\)|)(97|\\'a\\')> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*char t;\r\n\r\n\[ \t\]*.*char baz\\(int, char\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype bazint2"
|
||||
}
|
||||
@ -463,7 +465,7 @@ gdb_test_multiple "ptype bazint2" "ptype bazint2" {
|
||||
|
||||
# Template Qux<T, int (*f)(int) >
|
||||
# Same as Foo for g++
|
||||
gdb_test_multiple "ptype Qux" "ptype Qux" {
|
||||
gdb_test_multiple "ptype/r Qux" "ptype Qux" {
|
||||
-re "type = template <(class |)T, ?(class |)sz> (class |)Qux \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*T t;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Qux<int,&string>\r\n\[ \t\]*(class |)Qux<char,&string>\r\n$gdb_prompt $" {
|
||||
pass "ptype Qux"
|
||||
}
|
||||
@ -486,7 +488,7 @@ gdb_test_multiple "ptype Qux" "ptype Qux" {
|
||||
|
||||
# pt Qux<int,&string>
|
||||
|
||||
gdb_test_multiple "ptype quxint" "ptype quxint" {
|
||||
gdb_test_multiple "ptype/r quxint" "ptype quxint" {
|
||||
-re "type = class Qux<int, ?& ?string> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int qux\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype quxint"
|
||||
}
|
||||
@ -505,7 +507,7 @@ gdb_test_multiple "ptype quxint" "ptype quxint" {
|
||||
# Template Spec<T1, T2>
|
||||
|
||||
# Same as Foo for g++
|
||||
gdb_test_multiple "ptype Spec" "ptype Spec" {
|
||||
gdb_test_multiple "ptype/r Spec" "ptype Spec" {
|
||||
-re "type = template <(class |)T1, (class |)T2> (class |)Spec \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\\}\r\ntemplate instantiations:\r\n\[ \t\]*(class |)Spec<int,int \\*>\r\n\[ \t\]*(class |)Spec<int,char>\r\n$gdb_prompt $" {
|
||||
pass "ptype Spec"
|
||||
}
|
||||
@ -524,7 +526,7 @@ gdb_test_multiple "ptype Spec" "ptype Spec" {
|
||||
|
||||
# pt Spec<char,0>
|
||||
|
||||
gdb_test_multiple "ptype siip" "ptype siip" {
|
||||
gdb_test_multiple "ptype/r siip" "ptype siip" {
|
||||
-re "type = class Spec<int, ?int ?\\*> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\r\n\[ \t\]*.*int spec\\(int ?\\*\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype siip"
|
||||
}
|
||||
@ -535,7 +537,7 @@ gdb_test_multiple "ptype siip" "ptype siip" {
|
||||
|
||||
# pt Garply<int>
|
||||
|
||||
gdb_test_multiple "ptype Garply<int>" "ptype Garply<int>" {
|
||||
gdb_test_multiple "ptype/r Garply<int>" "ptype Garply<int>" {
|
||||
-re "type = class Garply<int> \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*int t;\r\n\r\n\[ \t\]*.*int garply\\(int, int\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype Garply<int>"
|
||||
}
|
||||
@ -546,7 +548,7 @@ gdb_test_multiple "ptype Garply<int>" "ptype Garply<int>" {
|
||||
|
||||
# ptype of nested template name
|
||||
|
||||
gdb_test_multiple "ptype Garply<Garply<char> >" "ptype Garply<Garply<char> >" {
|
||||
gdb_test_multiple "ptype/r Garply<Garply<char> >" "ptype Garply<Garply<char> >" {
|
||||
-re "type = (class |)Garply<Garply<char> > \\{\r\n\[ \t\]*public:\r\n\[ \t\]*int x;\r\n\[ \t\]*.*(class |)Garply<char> t;\r\n\r\n\[ \t\]*.*(class |)Garply<char> garply\\(int, (class |)Garply<char>\\);\r\n\\}\r\n$gdb_prompt $" {
|
||||
pass "ptype Garply<Garply<char> >"
|
||||
}
|
||||
|
@ -64,14 +64,14 @@ mi_list_varobj_children "struct_declarations" {
|
||||
{struct_declarations.integer integer 0 int}
|
||||
{struct_declarations.character character 0 char}
|
||||
{struct_declarations.char_ptr char_ptr 1 "char \\*"}
|
||||
{struct_declarations.long_int long_int 0 "long int"}
|
||||
{struct_declarations.long_int long_int 0 "long"}
|
||||
{struct_declarations.int_ptr_ptr int_ptr_ptr 1 "int \\*\\*"}
|
||||
{struct_declarations.long_array long_array 12 "long int \\[12\\]"}
|
||||
{struct_declarations.long_array long_array 12 "long \\[12\\]"}
|
||||
{struct_declarations.func_ptr func_ptr 0 "void \\(\\*\\)\\((void)?\\)"}
|
||||
{struct_declarations.func_ptr_struct func_ptr_struct 0 \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long int\\))?"}
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long\\))?"}
|
||||
{struct_declarations.func_ptr_ptr func_ptr_ptr 0 \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)"}
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long)?\\)"}
|
||||
{struct_declarations.u1 u1 4 "union \\{\\.\\.\\.\\}"}
|
||||
{struct_declarations.s2 s2 4 "struct \\{\\.\\.\\.\\}"}
|
||||
} "get children of struct_declarations"
|
||||
@ -150,7 +150,8 @@ mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr" \
|
||||
|
||||
# Test: c_variable-4.15
|
||||
# Desc: children of struct_declarations.long_array
|
||||
mi_list_array_varobj_children "struct_declarations.long_array" 12 "long int" \
|
||||
mi_list_array_varobj_children "struct_declarations.long_array" 12 \
|
||||
"long" \
|
||||
"get children of struct_declarations.long_array"
|
||||
|
||||
# Test: c_variable-4.16
|
||||
@ -199,7 +200,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_ptr" \
|
||||
mi_list_varobj_children "struct_declarations.u1" {
|
||||
{struct_declarations.u1.a a 0 int}
|
||||
{struct_declarations.u1.b b 1 {char \*}}
|
||||
{struct_declarations.u1.c c 0 {long int}}
|
||||
{struct_declarations.u1.c c 0 {long}}
|
||||
{struct_declarations.u1.d d 0 {enum foo}}
|
||||
} "get children of struct_declarations.u1"
|
||||
|
||||
@ -215,7 +216,7 @@ mi_list_varobj_children "struct_declarations.s2" {
|
||||
{struct_declarations.s2.u2 u2 3 {union \{\.\.\.\}}}
|
||||
{struct_declarations.s2.g g 0 int}
|
||||
{struct_declarations.s2.h h 0 char}
|
||||
{struct_declarations.s2.i i 10 {long int \[10\]}}
|
||||
{struct_declarations.s2.i i 10 {long \[10\]}}
|
||||
} "get children of struct_declarations.s2"
|
||||
|
||||
#gdbtk_test c_variable-4.25 {children of struct_declarations.s2} {
|
||||
@ -289,7 +290,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.u1.d" \
|
||||
# Desc: children of struct_declarations.s2.u2
|
||||
mi_list_varobj_children "struct_declarations.s2.u2" {
|
||||
{"struct_declarations.s2.u2.u1s1" "u1s1" 4 {struct \{\.\.\.\}}}
|
||||
{struct_declarations.s2.u2.f f 0 "long int"}
|
||||
{struct_declarations.s2.u2.f f 0 "long"}
|
||||
{struct_declarations.s2.u2.u1s2 u1s2 2 {struct \{\.\.\.\}}}
|
||||
} "get children of struct_declarations.s2.u2"
|
||||
|
||||
@ -327,7 +328,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.s2.h" \
|
||||
# Desc: children of struct_declarations.s2.i
|
||||
set t {}
|
||||
for {set i 0} {$i < 10} {incr i} {
|
||||
lappend t [list struct_declarations.s2.i.$i $i 0 "long int"]
|
||||
lappend t [list struct_declarations.s2.i.$i $i 0 "long"]
|
||||
}
|
||||
mi_list_varobj_children struct_declarations.s2.i $t \
|
||||
"get children of struct_declarations.s2.i"
|
||||
@ -481,14 +482,14 @@ mi_list_varobj_children "weird" {
|
||||
{weird.integer integer 0 int}
|
||||
{weird.character character 0 char}
|
||||
{weird.char_ptr char_ptr 1 "char \\*"}
|
||||
{weird.long_int long_int 0 "long int"}
|
||||
{weird.long_int long_int 0 "long"}
|
||||
{weird.int_ptr_ptr int_ptr_ptr 1 "int \\*\\*"}
|
||||
{weird.long_array long_array 12 "long int \\[12\\]"}
|
||||
{weird.long_array long_array 12 "long \\[12\\]"}
|
||||
{weird.func_ptr func_ptr 0 "void \\(\\*\\)\\((void)?\\)"}
|
||||
{weird.func_ptr_struct func_ptr_struct 0 \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long int\\))?"}
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long\\))?"}
|
||||
{weird.func_ptr_ptr func_ptr_ptr 0 \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)"}
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long)?\\)"}
|
||||
{weird.u1 u1 4 "union \\{\\.\\.\\.\\}"}
|
||||
{weird.s2 s2 4 "struct \\{\\.\\.\\.\\}"}
|
||||
} "get children of weird"
|
||||
@ -502,7 +503,7 @@ mi_gdb_test "-var-info-num-children weird" \
|
||||
|
||||
# Test: c_variable-4.84
|
||||
# Desc: children of weird->long_array
|
||||
mi_list_array_varobj_children weird.long_array 12 "long int" \
|
||||
mi_list_array_varobj_children weird.long_array 12 "long" \
|
||||
"get children of weird.long_array"
|
||||
#gdbtk_test c_variable-4.84 {children of weird->long_array} {
|
||||
# get_children weird.long_array
|
||||
@ -783,18 +784,18 @@ mi_gdb_test "-var-update --all-values *" \
|
||||
"update all vars struct_declarations.long_array.11 changed, print values."
|
||||
|
||||
mi_list_varobj_children {struct_declarations.long_array --all-values} {
|
||||
{struct_declarations.long_array.0 0 0 "long int" 1234}
|
||||
{struct_declarations.long_array.1 1 0 "long int" 2345}
|
||||
{struct_declarations.long_array.2 2 0 "long int" 3456}
|
||||
{struct_declarations.long_array.3 3 0 "long int" 4567}
|
||||
{struct_declarations.long_array.4 4 0 "long int" 5678}
|
||||
{struct_declarations.long_array.5 5 0 "long int" 6789}
|
||||
{struct_declarations.long_array.6 6 0 "long int" 7890}
|
||||
{struct_declarations.long_array.7 7 0 "long int" 8901}
|
||||
{struct_declarations.long_array.8 8 0 "long int" 9012}
|
||||
{struct_declarations.long_array.9 9 0 "long int" 1234}
|
||||
{struct_declarations.long_array.10 10 0 "long int" 3456}
|
||||
{struct_declarations.long_array.11 11 0 "long int" 5678}
|
||||
{struct_declarations.long_array.0 0 0 "long" 1234}
|
||||
{struct_declarations.long_array.1 1 0 "long" 2345}
|
||||
{struct_declarations.long_array.2 2 0 "long" 3456}
|
||||
{struct_declarations.long_array.3 3 0 "long" 4567}
|
||||
{struct_declarations.long_array.4 4 0 "long" 5678}
|
||||
{struct_declarations.long_array.5 5 0 "long" 6789}
|
||||
{struct_declarations.long_array.6 6 0 "long" 7890}
|
||||
{struct_declarations.long_array.7 7 0 "long" 8901}
|
||||
{struct_declarations.long_array.8 8 0 "long" 9012}
|
||||
{struct_declarations.long_array.9 9 0 "long" 1234}
|
||||
{struct_declarations.long_array.10 10 0 "long" 3456}
|
||||
{struct_declarations.long_array.11 11 0 "long" 5678}
|
||||
} "listing of names and values of children"
|
||||
|
||||
mi_list_varobj_children {struct_declarations --simple-values} \
|
||||
@ -802,14 +803,14 @@ mi_list_varobj_children {struct_declarations --simple-values} \
|
||||
{struct_declarations.integer integer 0 int 123} \
|
||||
{struct_declarations.character character 0 char {0 '\\\\000'}} \
|
||||
[list struct_declarations.char_ptr char_ptr 1 "char \\*" "$hex \\\\\"hello\\\\\""] \
|
||||
{struct_declarations.long_int long_int 0 "long int" 0} \
|
||||
{struct_declarations.long_int long_int 0 "long" 0} \
|
||||
[list struct_declarations.int_ptr_ptr int_ptr_ptr 1 "int \\*\\*" "$hex"] \
|
||||
{struct_declarations.long_array long_array 12 "long int \\[12\\]"} \
|
||||
{struct_declarations.long_array long_array 12 "long \\[12\\]"} \
|
||||
[list struct_declarations.func_ptr func_ptr 0 "void \\(\\*\\)\\((void)?\\)" "(@$hex: |)$hex <nothing>"] \
|
||||
{struct_declarations.func_ptr_struct func_ptr_struct 0 \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long int\\))?" 0x0} \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long\\))?" 0x0} \
|
||||
{struct_declarations.func_ptr_ptr func_ptr_ptr 0 \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)" 0x0} \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long)?\\)" 0x0} \
|
||||
{struct_declarations.u1 u1 4 "union \\{\\.\\.\\.\\}"} \
|
||||
{struct_declarations.s2 s2 4 "struct \\{\\.\\.\\.\\}"} \
|
||||
] "listing of children, simple types: names, type and values, complex types: names and types"
|
||||
@ -913,7 +914,7 @@ mi_create_varobj "psnp->long_ptr" "psnp->long_ptr" \
|
||||
# Test: c_variable-5.20
|
||||
# Desc: children of psnp->long_ptr
|
||||
mi_list_varobj_children "psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr} {\*psnp->long_ptr} 1 {long int \*\*\*}}
|
||||
{{psnp->long_ptr.\*psnp->long_ptr} {\*psnp->long_ptr} 1 {long \*\*\*}}
|
||||
} "get children of psnp->long_ptr"
|
||||
|
||||
# Test: c_variable-5.21
|
||||
@ -925,7 +926,7 @@ mi_gdb_test "-var-info-num-children psnp->long_ptr" \
|
||||
# Test: c_variable-5.22
|
||||
# Desc: children of *(psnp->long_ptr)
|
||||
mi_list_varobj_children "psnp->long_ptr.*psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr} {\*\*psnp->long_ptr} 1 {long int \*\*}}
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr} {\*\*psnp->long_ptr} 1 {long \*\*}}
|
||||
} "get children of psnp->long_ptr.*psnp->long_ptr"
|
||||
|
||||
|
||||
@ -939,7 +940,7 @@ mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr" \
|
||||
# Desc: children of *(*(psnp->long_ptr))
|
||||
mi_list_varobj_children "psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr.\*\*\*psnp->long_ptr} \
|
||||
{\*\*\*psnp->long_ptr} 1 {long int \*}}
|
||||
{\*\*\*psnp->long_ptr} 1 {long \*}}
|
||||
} "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
|
||||
|
||||
# Test: c_variable-5.25
|
||||
@ -952,7 +953,7 @@ mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_
|
||||
# Desc: children of *(*(*(psnp->long_ptr)))
|
||||
mi_list_varobj_children "psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr.\*\*\*psnp->long_ptr.\*\*\*\*psnp->long_ptr}
|
||||
{\*\*\*\*psnp->long_ptr} 0 {long int}}
|
||||
{\*\*\*\*psnp->long_ptr} 0 {long}}
|
||||
} "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
|
||||
|
||||
# Test: c_variable-5.27
|
||||
@ -995,7 +996,7 @@ mi_gdb_test "-var-info-num-children psnp->ptrs" \
|
||||
# Desc: children of psnp->ptrs[0]
|
||||
mi_list_varobj_children "psnp->ptrs.0" {
|
||||
{psnp->ptrs.0.char_ptr char_ptr 1 {char \*\*\*\*}}
|
||||
{psnp->ptrs.0.long_ptr long_ptr 1 {long int \*\*\*\*}}
|
||||
{psnp->ptrs.0.long_ptr long_ptr 1 {long \*\*\*\*}}
|
||||
{psnp->ptrs.0.ptrs ptrs 3 {struct _struct_n_pointer \*\[3\]}}
|
||||
{psnp->ptrs.0.next next 4 {struct _struct_n_pointer \*}}
|
||||
} "get children of psnp->ptrs.0"
|
||||
@ -1010,7 +1011,7 @@ mi_gdb_test "-var-info-num-children psnp->ptrs.0" \
|
||||
# Desc: children of psnp->ptrs[0]->next
|
||||
mi_list_varobj_children "psnp->ptrs.0.next" {
|
||||
{psnp->ptrs.0.next.char_ptr char_ptr 1 {char \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.long_ptr long_ptr 1 {long int \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.long_ptr long_ptr 1 {long \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.ptrs ptrs 3 {struct _struct_n_pointer \*\[3\]}}
|
||||
{psnp->ptrs.0.next.next next 4 {struct _struct_n_pointer \*}}
|
||||
} "get children of psnp->ptrs.0.next"
|
||||
@ -1100,7 +1101,7 @@ mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_
|
||||
# Desc: children of psnp->ptrs[0]->next->next
|
||||
mi_list_varobj_children "psnp->ptrs.0.next.next" {
|
||||
{psnp->ptrs.0.next.next.char_ptr char_ptr 1 {char \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.next.long_ptr long_ptr 1 {long int \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.next.long_ptr long_ptr 1 {long \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.next.ptrs ptrs 3 {struct _struct_n_pointer \*\[3\]}}
|
||||
{psnp->ptrs.0.next.next.next next 4 {struct _struct_n_pointer \*}}
|
||||
} "get children of psnp->ptrs.0.next.next"
|
||||
|
@ -83,9 +83,9 @@ mi_create_varobj_checked lcharacter lcharacter\[0\] char "create local variable
|
||||
|
||||
mi_create_varobj_checked lpcharacter lpcharacter {char \*} "create local variable lpcharacter"
|
||||
|
||||
mi_create_varobj_checked llong llong "long int" "create local variable llong"
|
||||
mi_create_varobj_checked llong llong "long" "create local variable llong"
|
||||
|
||||
mi_create_varobj_checked lplong lplong {long int \*} "create local variable lplong"
|
||||
mi_create_varobj_checked lplong lplong {long \*} "create local variable lplong"
|
||||
|
||||
mi_create_varobj_checked lfloat lfloat float "create local variable lfloat"
|
||||
|
||||
@ -408,7 +408,7 @@ mi_continue_to subroutine1
|
||||
# Desc: create variable for locals i,l in subroutine1
|
||||
mi_create_varobj_checked i i int "create i"
|
||||
|
||||
mi_create_varobj_checked l l {long int \*} "create l"
|
||||
mi_create_varobj_checked l l {long \*} "create l"
|
||||
|
||||
# Test: c_variable-2.11
|
||||
# Desc: create do_locals_tests local in subroutine1
|
||||
|
@ -215,14 +215,14 @@ mi_list_varobj_children weird {
|
||||
{weird.integer integer 0 int}
|
||||
{weird.character character 0 char}
|
||||
{weird.char_ptr char_ptr 1 "char \\*"}
|
||||
{weird.long_int long_int 0 "long int"}
|
||||
{weird.long_int long_int 0 "long"}
|
||||
{weird.int_ptr_ptr int_ptr_ptr 1 "int \\*\\*"}
|
||||
{weird.long_array long_array 10 "long int \\[10\\]"}
|
||||
{weird.long_array long_array 10 "long \\[10\\]"}
|
||||
{weird.func_ptr func_ptr 0 "void \\(\\*\\)\\((void)?\\)"}
|
||||
{weird.func_ptr_struct func_ptr_struct 0 \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long int\\))?"}
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long\\))?"}
|
||||
{weird.func_ptr_ptr func_ptr_ptr 0 \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)"}
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long)?\\)"}
|
||||
{weird.u1 u1 4 "union \\{\\.\\.\\.\\}"}
|
||||
{weird.s2 s2 4 "struct \\{\\.\\.\\.\\}"}
|
||||
} "get children local variable weird"
|
||||
@ -443,7 +443,7 @@ mi_gdb_test "-var-info-num-children anonu" \
|
||||
mi_list_varobj_children "anonu" {
|
||||
{anonu.a a 0 int}
|
||||
{anonu.b b 0 char}
|
||||
{anonu.c c 0 "long int"}
|
||||
{anonu.c c 0 "long"}
|
||||
} "get children of anonu"
|
||||
|
||||
# Test: c_variable-7.30
|
||||
@ -520,7 +520,7 @@ mi_gdb_test "-var-info-num-children anons" \
|
||||
mi_list_varobj_children anons {
|
||||
{anons.a a 0 int}
|
||||
{anons.b b 0 char}
|
||||
{anons.c c 0 "long int"}
|
||||
{anons.c c 0 "long"}
|
||||
} "get children of anons"
|
||||
|
||||
# Test: c_variable-7.50
|
||||
|
@ -63,14 +63,14 @@ mi_list_varobj_children "struct_declarations" {
|
||||
{struct_declarations.integer integer 0 int}
|
||||
{struct_declarations.character character 0 char}
|
||||
{struct_declarations.char_ptr char_ptr 1 "char \\*"}
|
||||
{struct_declarations.long_int long_int 0 "long int"}
|
||||
{struct_declarations.long_int long_int 0 "long"}
|
||||
{struct_declarations.int_ptr_ptr int_ptr_ptr 1 "int \\*\\*"}
|
||||
{struct_declarations.long_array long_array 10 "long int \\[10\\]"}
|
||||
{struct_declarations.long_array long_array 10 "long \\[10\\]"}
|
||||
{struct_declarations.func_ptr func_ptr 0 "void \\(\\*\\)\\((void)?\\)"}
|
||||
{struct_declarations.func_ptr_struct func_ptr_struct 0 \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long int\\))?"}
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long\\))?"}
|
||||
{struct_declarations.func_ptr_ptr func_ptr_ptr 0 \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)"}
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long)?\\)"}
|
||||
{struct_declarations.u1 u1 4 "union \\{\\.\\.\\.\\}"}
|
||||
{struct_declarations.s2 s2 4 "struct \\{\\.\\.\\.\\}"}
|
||||
} "get children of struct_declarations"
|
||||
@ -150,7 +150,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.int_ptr_ptr" \
|
||||
|
||||
# Test: c_variable-4.15
|
||||
# Desc: children of struct_declarations.long_array
|
||||
mi_list_array_varobj_children "struct_declarations.long_array" 10 "long int" \
|
||||
mi_list_array_varobj_children "struct_declarations.long_array" 10 "long" \
|
||||
"get children of struct_declarations.long_array"
|
||||
|
||||
# Test: c_variable-4.16
|
||||
@ -199,7 +199,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.func_ptr_ptr" \
|
||||
mi_list_varobj_children "struct_declarations.u1" {
|
||||
{struct_declarations.u1.a a 0 int}
|
||||
{struct_declarations.u1.b b 1 {char \*}}
|
||||
{struct_declarations.u1.c c 0 {long int}}
|
||||
{struct_declarations.u1.c c 0 {long}}
|
||||
{struct_declarations.u1.d d 0 {enum foo}}
|
||||
} "get children of struct_declarations.u1"
|
||||
|
||||
@ -215,7 +215,7 @@ mi_list_varobj_children "struct_declarations.s2" {
|
||||
{struct_declarations.s2.u2 u2 3 {union \{\.\.\.\}}}
|
||||
{struct_declarations.s2.g g 0 int}
|
||||
{struct_declarations.s2.h h 0 char}
|
||||
{struct_declarations.s2.i i 10 {long int \[10\]}}
|
||||
{struct_declarations.s2.i i 10 {long \[10\]}}
|
||||
} "get children of struct_declarations.s2"
|
||||
|
||||
#gdbtk_test c_variable-4.25 {children of struct_declarations.s2} {
|
||||
@ -289,7 +289,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.u1.d" \
|
||||
# Desc: children of struct_declarations.s2.u2
|
||||
mi_list_varobj_children "struct_declarations.s2.u2" {
|
||||
{"struct_declarations.s2.u2.u1s1" "u1s1" 4 {struct \{\.\.\.\}}}
|
||||
{struct_declarations.s2.u2.f f 0 "long int"}
|
||||
{struct_declarations.s2.u2.f f 0 "long"}
|
||||
{struct_declarations.s2.u2.u1s2 u1s2 2 {struct \{\.\.\.\}}}
|
||||
} "get children of struct_declarations.s2.u2"
|
||||
|
||||
@ -327,7 +327,7 @@ mi_gdb_test "-var-info-num-children struct_declarations.s2.h" \
|
||||
# Desc: children of struct_declarations.s2.i
|
||||
set t {}
|
||||
for {set i 0} {$i < 10} {incr i} {
|
||||
lappend t [list struct_declarations.s2.i.$i $i 0 "long int"]
|
||||
lappend t [list struct_declarations.s2.i.$i $i 0 "long"]
|
||||
}
|
||||
mi_list_varobj_children struct_declarations.s2.i $t \
|
||||
"get children of struct_declarations.s2.i"
|
||||
@ -481,14 +481,14 @@ mi_list_varobj_children "weird" {
|
||||
{weird.integer integer 0 int}
|
||||
{weird.character character 0 char}
|
||||
{weird.char_ptr char_ptr 1 "char \\*"}
|
||||
{weird.long_int long_int 0 "long int"}
|
||||
{weird.long_int long_int 0 "long"}
|
||||
{weird.int_ptr_ptr int_ptr_ptr 1 "int \\*\\*"}
|
||||
{weird.long_array long_array 10 "long int \\[10\\]"}
|
||||
{weird.long_array long_array 10 "long \\[10\\]"}
|
||||
{weird.func_ptr func_ptr 0 "void \\(\\*\\)\\((void)?\\)"}
|
||||
{weird.func_ptr_struct func_ptr_struct 0 \
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long int\\))?"}
|
||||
"struct _struct_decl \\(\\*\\)(\\(int, char \\*, long\\))?"}
|
||||
{weird.func_ptr_ptr func_ptr_ptr 0 \
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long int)?\\)"}
|
||||
"struct _struct_decl \\*\\(\\*\\)\\((int, char \\*, long)?\\)"}
|
||||
{weird.u1 u1 4 "union \\{\\.\\.\\.\\}"}
|
||||
{weird.s2 s2 4 "struct \\{\\.\\.\\.\\}"}
|
||||
} "get children of weird"
|
||||
@ -502,7 +502,7 @@ mi_gdb_test "-var-info-num-children weird" \
|
||||
|
||||
# Test: c_variable-4.84
|
||||
# Desc: children of weird->long_array
|
||||
mi_list_array_varobj_children weird.long_array 10 "long int" \
|
||||
mi_list_array_varobj_children weird.long_array 10 "long" \
|
||||
"get children of weird.long_array"
|
||||
#gdbtk_test c_variable-4.84 {children of weird->long_array} {
|
||||
# get_children weird.long_array
|
||||
@ -865,7 +865,7 @@ mi_create_varobj "psnp->long_ptr" "psnp->long_ptr" \
|
||||
# Test: c_variable-5.20
|
||||
# Desc: children of psnp->long_ptr
|
||||
mi_list_varobj_children "psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr} {\*psnp->long_ptr} 1 {long int \*\*\*}}
|
||||
{{psnp->long_ptr.\*psnp->long_ptr} {\*psnp->long_ptr} 1 {long \*\*\*}}
|
||||
} "get children of psnp->long_ptr"
|
||||
|
||||
# Test: c_variable-5.21
|
||||
@ -877,7 +877,7 @@ mi_gdb_test "-var-info-num-children psnp->long_ptr" \
|
||||
# Test: c_variable-5.22
|
||||
# Desc: children of *(psnp->long_ptr)
|
||||
mi_list_varobj_children "psnp->long_ptr.*psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr} {\*\*psnp->long_ptr} 1 {long int \*\*}}
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr} {\*\*psnp->long_ptr} 1 {long \*\*}}
|
||||
} "get children of psnp->long_ptr.*psnp->long_ptr"
|
||||
|
||||
|
||||
@ -891,7 +891,7 @@ mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr" \
|
||||
# Desc: children of *(*(psnp->long_ptr))
|
||||
mi_list_varobj_children "psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr.\*\*\*psnp->long_ptr} \
|
||||
{\*\*\*psnp->long_ptr} 1 {long int \*}}
|
||||
{\*\*\*psnp->long_ptr} 1 {long \*}}
|
||||
} "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr"
|
||||
|
||||
# Test: c_variable-5.25
|
||||
@ -904,7 +904,7 @@ mi_gdb_test "-var-info-num-children psnp->long_ptr.*psnp->long_ptr.**psnp->long_
|
||||
# Desc: children of *(*(*(psnp->long_ptr)))
|
||||
mi_list_varobj_children "psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr" {
|
||||
{{psnp->long_ptr.\*psnp->long_ptr.\*\*psnp->long_ptr.\*\*\*psnp->long_ptr.\*\*\*\*psnp->long_ptr}
|
||||
{\*\*\*\*psnp->long_ptr} 0 {long int}}
|
||||
{\*\*\*\*psnp->long_ptr} 0 {long}}
|
||||
} "get children of psnp->long_ptr.*psnp->long_ptr.**psnp->long_ptr.***psnp->long_ptr"
|
||||
|
||||
# Test: c_variable-5.27
|
||||
@ -948,7 +948,7 @@ mi_gdb_test "-var-info-num-children psnp->ptrs" \
|
||||
# Desc: children of psnp->ptrs[0]
|
||||
mi_list_varobj_children "psnp->ptrs.0" {
|
||||
{psnp->ptrs.0.char_ptr char_ptr 1 {char \*\*\*\*}}
|
||||
{psnp->ptrs.0.long_ptr long_ptr 1 {long int \*\*\*\*}}
|
||||
{psnp->ptrs.0.long_ptr long_ptr 1 {long \*\*\*\*}}
|
||||
{psnp->ptrs.0.ptrs ptrs 3 {struct _struct_n_pointer \*\[3\]}}
|
||||
{psnp->ptrs.0.next next 4 {struct _struct_n_pointer \*}}
|
||||
} "get children of psnp->ptrs.0"
|
||||
@ -963,7 +963,7 @@ mi_gdb_test "-var-info-num-children psnp->ptrs.0" \
|
||||
# Desc: children of psnp->ptrs[0]->next
|
||||
mi_list_varobj_children "psnp->ptrs.0.next" {
|
||||
{psnp->ptrs.0.next.char_ptr char_ptr 1 {char \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.long_ptr long_ptr 1 {long int \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.long_ptr long_ptr 1 {long \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.ptrs ptrs 3 {struct _struct_n_pointer \*\[3\]}}
|
||||
{psnp->ptrs.0.next.next next 4 {struct _struct_n_pointer \*}}
|
||||
} "get children of psnp->ptrs.0.next"
|
||||
@ -1053,7 +1053,7 @@ mi_gdb_test "-var-info-num-children psnp->ptrs.0.next.char_ptr.*char_ptr.**char_
|
||||
# Desc: children of psnp->ptrs[0]->next->next
|
||||
mi_list_varobj_children "psnp->ptrs.0.next.next" {
|
||||
{psnp->ptrs.0.next.next.char_ptr char_ptr 1 {char \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.next.long_ptr long_ptr 1 {long int \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.next.long_ptr long_ptr 1 {long \*\*\*\*}}
|
||||
{psnp->ptrs.0.next.next.ptrs ptrs 3 {struct _struct_n_pointer \*\[3\]}}
|
||||
{psnp->ptrs.0.next.next.next next 4 {struct _struct_n_pointer \*}}
|
||||
} "get children of psnp->ptrs.0.next.next"
|
||||
|
@ -100,6 +100,8 @@ proc cp_check_errata { expected_string actual_string errata_table } {
|
||||
# demangler syntax adjustment, so you have to make a bigger table
|
||||
# with lines for each output variation.
|
||||
#
|
||||
# IN_PTYPE_ARG are arguments to pass to ptype. The default is "/r".
|
||||
#
|
||||
# gdb can vary the output of ptype in several ways:
|
||||
#
|
||||
# . CLASS/STRUCT
|
||||
@ -178,15 +180,16 @@ proc cp_check_errata { expected_string actual_string errata_table } {
|
||||
#
|
||||
# -- chastain 2004-08-07
|
||||
|
||||
proc cp_test_ptype_class { in_exp in_testname in_key in_tag in_class_table { in_tail "" } { in_errata_table { } } } {
|
||||
proc cp_test_ptype_class { in_exp in_testname in_key in_tag in_class_table { in_tail "" } { in_errata_table { } } { in_ptype_arg /r } } {
|
||||
global gdb_prompt
|
||||
set wsopt "\[\r\n\t \]*"
|
||||
|
||||
# The test name defaults to the command.
|
||||
# The test name defaults to the command, but without the
|
||||
# arguments, for historical reasons.
|
||||
|
||||
if { "$in_testname" == "" } then { set in_testname "ptype $in_exp" }
|
||||
|
||||
set in_command "ptype $in_exp"
|
||||
set in_command "ptype${in_ptype_arg} $in_exp"
|
||||
|
||||
# Save class tables in a history array for reuse.
|
||||
|
||||
@ -232,13 +235,13 @@ proc cp_test_ptype_class { in_exp in_testname in_key in_tag in_class_table { in_
|
||||
|
||||
set parse_okay 0
|
||||
gdb_test_multiple "$in_command" "$in_testname // parse failed" {
|
||||
-re "type = (struct|class)${wsopt}(\[A-Za-z0-9_\]*)${wsopt}((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" {
|
||||
-re "type = (struct|class)${wsopt}(\[^ \t\]*)${wsopt}(\\\[with .*\\\]${wsopt})?((:\[^\{\]*)?)${wsopt}\{(.*)\}${wsopt}(\[^\r\n\]*)\[\r\n\]+$gdb_prompt $" {
|
||||
set parse_okay 1
|
||||
set actual_key $expect_out(1,string)
|
||||
set actual_tag $expect_out(2,string)
|
||||
set actual_base_string $expect_out(3,string)
|
||||
set actual_body $expect_out(5,string)
|
||||
set actual_tail $expect_out(6,string)
|
||||
set actual_base_string $expect_out(4,string)
|
||||
set actual_body $expect_out(6,string)
|
||||
set actual_tail $expect_out(7,string)
|
||||
}
|
||||
}
|
||||
if { ! $parse_okay } then { return }
|
||||
|
196
gdb/typeprint.c
196
gdb/typeprint.c
@ -51,7 +51,8 @@ const struct type_print_options type_print_raw_options =
|
||||
{
|
||||
1, /* raw */
|
||||
1, /* print_methods */
|
||||
1 /* print_typedefs */
|
||||
1, /* print_typedefs */
|
||||
NULL /* local_typedefs */
|
||||
};
|
||||
|
||||
/* The default flags for 'ptype' and 'whatis'. */
|
||||
@ -60,11 +61,202 @@ static struct type_print_options default_ptype_flags =
|
||||
{
|
||||
0, /* raw */
|
||||
1, /* print_methods */
|
||||
1 /* print_typedefs */
|
||||
1, /* print_typedefs */
|
||||
NULL /* local_typedefs */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* 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 = 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 = a;
|
||||
const struct typedef_field *tfb = 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* A cleanup for freeing a typedef_hash_table. */
|
||||
|
||||
static void
|
||||
do_free_typedef_hash (void *arg)
|
||||
{
|
||||
free_typedef_hash (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. */
|
||||
|
||||
static int
|
||||
copy_typedef_hash_element (void **slot, void *nt)
|
||||
{
|
||||
htab_t new_table = nt;
|
||||
void **new_slot;
|
||||
|
||||
new_slot = htab_find_slot (new_table, *slot, INSERT);
|
||||
if (*new_slot == NULL)
|
||||
*new_slot = *slot;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
const char *
|
||||
find_typedef_in_hash (const struct type_print_options *flags, struct type *t)
|
||||
{
|
||||
struct typedef_field tf, *found;
|
||||
|
||||
if (flags->local_typedefs == NULL)
|
||||
return NULL;
|
||||
|
||||
tf.name = NULL;
|
||||
tf.type = t;
|
||||
found = htab_find (flags->local_typedefs->table, &tf);
|
||||
|
||||
return found == NULL ? NULL : found->name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
enum language;
|
||||
struct ui_file;
|
||||
struct typedef_hash_table;
|
||||
|
||||
struct type_print_options
|
||||
{
|
||||
@ -33,10 +34,30 @@ struct type_print_options
|
||||
|
||||
/* True means print typedefs in a class. */
|
||||
unsigned int print_typedefs : 1;
|
||||
|
||||
/* If not NULL, a local typedef hash table used when printing a
|
||||
type. */
|
||||
struct typedef_hash_table *local_typedefs;
|
||||
};
|
||||
|
||||
extern const struct type_print_options type_print_raw_options;
|
||||
|
||||
void recursively_update_typedef_hash (struct typedef_hash_table *,
|
||||
struct type *);
|
||||
|
||||
void add_template_parameters (struct typedef_hash_table *, struct type *);
|
||||
|
||||
struct typedef_hash_table *create_typedef_hash (void);
|
||||
|
||||
void free_typedef_hash (struct typedef_hash_table *);
|
||||
|
||||
struct cleanup *make_cleanup_free_typedef_hash (struct typedef_hash_table *);
|
||||
|
||||
struct typedef_hash_table *copy_typedef_hash (struct typedef_hash_table *);
|
||||
|
||||
const char *find_typedef_in_hash (const struct type_print_options *,
|
||||
struct type *);
|
||||
|
||||
void print_type_scalar (struct type * type, LONGEST, struct ui_file *);
|
||||
|
||||
void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
|
||||
|
Loading…
Reference in New Issue
Block a user