diff options
author | Tom Tromey <tromey@redhat.com> | 2012-11-12 17:37:38 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2012-11-12 17:37:38 +0000 |
commit | bd69fc683f383772bb8fab43c5d4af8d0cd4a8b4 (patch) | |
tree | 9749d8fbee083798c2657964bd816fd1795a6300 /gdb | |
parent | 2621e0fd5c40e316dfac2a492972a1344c6a0583 (diff) | |
download | gdb-bd69fc683f383772bb8fab43c5d4af8d0cd4a8b4.zip gdb-bd69fc683f383772bb8fab43c5d4af8d0cd4a8b4.tar.gz gdb-bd69fc683f383772bb8fab43c5d4af8d0cd4a8b4.tar.bz2 |
* 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".
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 31 | ||||
-rw-r--r-- | gdb/c-typeprint.c | 617 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 2 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 2 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 15 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/call-sc.exp | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/volatile.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/ptype-flags.cc | 47 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/ptype-flags.exp | 85 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/templates.exp | 46 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-child.exp | 75 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-cmd.exp | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi-var-display.exp | 12 | ||||
-rw-r--r-- | gdb/testsuite/gdb.mi/mi2-var-child.exp | 42 | ||||
-rw-r--r-- | gdb/testsuite/lib/cp-support.exp | 17 | ||||
-rw-r--r-- | gdb/typeprint.c | 196 | ||||
-rw-r--r-- | gdb/typeprint.h | 21 |
17 files changed, 885 insertions, 335 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 78cf6c6..fcf5ffc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,36 @@ 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, replace_typedefs_qualified_name, replace_typedefs): Add finder, data arguments. Call as needed. diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 6c47376..c6f8bb2 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -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 "); - - /* 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; - - cp_type_print_derivation_info (stream, 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) - { - len2 = TYPE_NFN_FIELDS (type); - for (j = 0; j < len2; j++) + { + struct type_print_options local_flags = *flags; + struct type_print_options semi_local_flags = *flags; + struct cleanup *local_cleanups = make_cleanup (null_cleanup, NULL); + + local_flags.local_typedefs = NULL; + semi_local_flags.local_typedefs = NULL; + + 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 (); + + make_cleanup_free_typedef_hash (local_flags.local_typedefs); + } + + 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 "); + + /* 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); + } + + 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; + + 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)) { - 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++) + { + 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)) { - 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; + need_access_label = 1; + 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)) + { + need_access_label = 1; + break; + } + if (need_access_label) + break; + } + } + } - /* If there is a base class for this type, - do not print the field that it occupies. */ + /* 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; + 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 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"); - } - } - } + 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); + + print_spaces_filtered (level + 4, stream); + fprintf_filtered (stream, "typedef "); + + /* 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"); + } + } - /* Dereference the typedef declaration itself. */ - gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF); - target = TYPE_TARGET_TYPE (target); + fprintfi_filtered (level, stream, "}"); - 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"); - } - } - - 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)); + } - 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 { diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 149d31f..d322004 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -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. */ diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 59a6a65..d5a7cf5 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -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 */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 2b9f905..9e04326 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,5 +1,20 @@ 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 "ptype" from calls to cp_test_ptype_class. (test_enums): Likewise. diff --git a/gdb/testsuite/gdb.base/call-sc.exp b/gdb/testsuite/gdb.base/call-sc.exp index 1b2a495..703b37f 100644 --- a/gdb/testsuite/gdb.base/call-sc.exp +++ b/gdb/testsuite/gdb.base/call-sc.exp @@ -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)" } diff --git a/gdb/testsuite/gdb.base/volatile.exp b/gdb/testsuite/gdb.base/volatile.exp index ade9d66..1f34b83 100644 --- a/gdb/testsuite/gdb.base/volatile.exp +++ b/gdb/testsuite/gdb.base/volatile.exp @@ -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.*" diff --git a/gdb/testsuite/gdb.cp/ptype-flags.cc b/gdb/testsuite/gdb.cp/ptype-flags.cc new file mode 100644 index 0000000..3077f73 --- /dev/null +++ b/gdb/testsuite/gdb.cp/ptype-flags.cc @@ -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; +} diff --git a/gdb/testsuite/gdb.cp/ptype-flags.exp b/gdb/testsuite/gdb.cp/ptype-flags.exp new file mode 100644 index 0000000..f544807 --- /dev/null +++ b/gdb/testsuite/gdb.cp/ptype-flags.exp @@ -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 diff --git a/gdb/testsuite/gdb.cp/templates.exp b/gdb/testsuite/gdb.cp/templates.exp index 47915b1..9ebb3bd 100644 --- a/gdb/testsuite/gdb.cp/templates.exp +++ b/gdb/testsuite/gdb.cp/templates.exp @@ -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> >" } diff --git a/gdb/testsuite/gdb.mi/mi-var-child.exp b/gdb/testsuite/gdb.mi/mi-var-child.exp index 1d72311..7e61684 100644 --- a/gdb/testsuite/gdb.mi/mi-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi-var-child.exp @@ -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" diff --git a/gdb/testsuite/gdb.mi/mi-var-cmd.exp b/gdb/testsuite/gdb.mi/mi-var-cmd.exp index 4c560a7..345e94b 100644 --- a/gdb/testsuite/gdb.mi/mi-var-cmd.exp +++ b/gdb/testsuite/gdb.mi/mi-var-cmd.exp @@ -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 diff --git a/gdb/testsuite/gdb.mi/mi-var-display.exp b/gdb/testsuite/gdb.mi/mi-var-display.exp index 5cb5f26..251f948 100644 --- a/gdb/testsuite/gdb.mi/mi-var-display.exp +++ b/gdb/testsuite/gdb.mi/mi-var-display.exp @@ -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 diff --git a/gdb/testsuite/gdb.mi/mi2-var-child.exp b/gdb/testsuite/gdb.mi/mi2-var-child.exp index fdf12f7..6a3823f 100644 --- a/gdb/testsuite/gdb.mi/mi2-var-child.exp +++ b/gdb/testsuite/gdb.mi/mi2-var-child.exp @@ -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" diff --git a/gdb/testsuite/lib/cp-support.exp b/gdb/testsuite/lib/cp-support.exp index 1414ffc..173fc08 100644 --- a/gdb/testsuite/lib/cp-support.exp +++ b/gdb/testsuite/lib/cp-support.exp @@ -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 } diff --git a/gdb/typeprint.c b/gdb/typeprint.c index 509b3ee..0e1c93c 100644 --- a/gdb/typeprint.c +++ b/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. */ diff --git a/gdb/typeprint.h b/gdb/typeprint.h index 1e15097..71bac01 100644 --- a/gdb/typeprint.h +++ b/gdb/typeprint.h @@ -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, |