| Index: gdb/c-typeprint.c
|
| diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
|
| index a5892b50b8b65539ffbe86e2a0cfe190620f69a3..275733714fb9777d3a56cfb116db0bacc7d0dcf9 100644
|
| --- a/gdb/c-typeprint.c
|
| +++ b/gdb/c-typeprint.c
|
| @@ -1,6 +1,5 @@
|
| /* Support for printing C and C++ types for GDB, the GNU debugger.
|
| - Copyright (C) 1986, 1988-1989, 1991-1996, 1998-2003, 2006-2012 Free
|
| - Software Foundation, Inc.
|
| + Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -32,48 +31,95 @@
|
| #include "typeprint.h"
|
| #include "cp-abi.h"
|
| #include "jv-lang.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include <errno.h>
|
| +#include "cp-support.h"
|
|
|
| static void c_type_print_varspec_prefix (struct type *,
|
| struct ui_file *,
|
| - int, int, int);
|
| + int, int, int,
|
| + const struct type_print_options *);
|
|
|
| /* Print "const", "volatile", or address space modifiers. */
|
| 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
|
| c_print_type (struct type *type,
|
| const char *varstring,
|
| struct ui_file *stream,
|
| - int show, int level)
|
| + int show, int level,
|
| + const struct type_print_options *flags)
|
| {
|
| 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);
|
| - 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
|
| - || 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);
|
| + 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)
|
| {
|
| @@ -81,10 +127,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);
|
| + if (local_name == NULL)
|
| + {
|
| + demangled_args = strchr (varstring, '(') != NULL;
|
| + c_type_print_varspec_suffix (type, stream, show,
|
| + 0, demangled_args,
|
| + flags);
|
| + }
|
| }
|
| }
|
|
|
| @@ -131,22 +180,19 @@ c_print_typedef (struct type *type,
|
| }
|
|
|
| In general, gdb should try to print the types as closely as
|
| - possible to the form that they appear in the source code.
|
| -
|
| - Note that in case of protected derivation gcc will not say
|
| - 'protected' but 'private'. The HP's aCC compiler emits specific
|
| - information for derivation via protected inheritance, so gdb can
|
| - print it out */
|
| + possible to the form that they appear in the source code. */
|
|
|
| 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)
|
| @@ -154,7 +200,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)
|
| {
|
| @@ -167,7 +216,8 @@ cp_type_print_derivation_info (struct ui_file *stream,
|
| static void
|
| cp_type_print_method_args (struct type *mtype, const char *prefix,
|
| const char *varstring, int staticp,
|
| - struct ui_file *stream)
|
| + struct ui_file *stream,
|
| + const struct type_print_options *flags)
|
| {
|
| struct field *args = TYPE_FIELDS (mtype);
|
| int nargs = TYPE_NFIELDS (mtype);
|
| @@ -186,12 +236,15 @@ cp_type_print_method_args (struct type *mtype, const char *prefix,
|
| {
|
| while (i < nargs)
|
| {
|
| - type_print (args[i++].type, "", stream, 0);
|
| + c_print_type (args[i++].type, "", stream, 0, 0, flags);
|
|
|
| if (i == nargs && varargs)
|
| fprintf_filtered (stream, ", ...");
|
| else if (i < nargs)
|
| - fprintf_filtered (stream, ", ");
|
| + {
|
| + fprintf_filtered (stream, ", ");
|
| + wrap_here (" ");
|
| + }
|
| }
|
| }
|
| else if (varargs)
|
| @@ -216,6 +269,9 @@ cp_type_print_method_args (struct type *mtype, const char *prefix,
|
|
|
| if (TYPE_VOLATILE (domain))
|
| fprintf_filtered (stream, " volatile");
|
| +
|
| + if (TYPE_RESTRICT (domain))
|
| + fprintf_filtered (stream, " restrict");
|
| }
|
| }
|
|
|
| @@ -236,7 +292,8 @@ static void
|
| c_type_print_varspec_prefix (struct type *type,
|
| struct ui_file *stream,
|
| int show, int passed_a_ptr,
|
| - int need_post_space)
|
| + int need_post_space,
|
| + const struct type_print_options *flags)
|
| {
|
| const char *name;
|
|
|
| @@ -252,39 +309,39 @@ c_type_print_varspec_prefix (struct type *type,
|
| {
|
| case TYPE_CODE_PTR:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 1, 1);
|
| + stream, show, 1, 1, flags);
|
| fprintf_filtered (stream, "*");
|
| c_type_print_modifier (type, stream, 1, need_post_space);
|
| break;
|
|
|
| case TYPE_CODE_MEMBERPTR:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 0, 0);
|
| + 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, 0, passed_a_ptr);
|
| + stream, -1, passed_a_ptr, flags);
|
| fprintf_filtered (stream, "::*");
|
| break;
|
|
|
| case TYPE_CODE_METHODPTR:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 0, 0);
|
| + stream, show, 0, 0, flags);
|
| 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, 0, passed_a_ptr);
|
| + stream, -1, passed_a_ptr, flags);
|
| fprintf_filtered (stream, "::*");
|
| break;
|
|
|
| case TYPE_CODE_REF:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 1, 0);
|
| + stream, show, 1, 0, flags);
|
| fprintf_filtered (stream, "&");
|
| c_type_print_modifier (type, stream, 1, need_post_space);
|
| break;
|
| @@ -292,21 +349,21 @@ c_type_print_varspec_prefix (struct type *type,
|
| case TYPE_CODE_METHOD:
|
| case TYPE_CODE_FUNC:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 0, 0);
|
| + stream, show, 0, 0, flags);
|
| if (passed_a_ptr)
|
| fprintf_filtered (stream, "(");
|
| break;
|
|
|
| case TYPE_CODE_ARRAY:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 0, 0);
|
| + stream, show, 0, 0, flags);
|
| if (passed_a_ptr)
|
| fprintf_filtered (stream, "(");
|
| break;
|
|
|
| case TYPE_CODE_TYPEDEF:
|
| c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type),
|
| - stream, show, 0, 0);
|
| + stream, show, passed_a_ptr, 0, flags);
|
| break;
|
|
|
| case TYPE_CODE_UNDEF:
|
| @@ -322,7 +379,6 @@ c_type_print_varspec_prefix (struct type *type,
|
| case TYPE_CODE_SET:
|
| case TYPE_CODE_RANGE:
|
| case TYPE_CODE_STRING:
|
| - case TYPE_CODE_BITSTRING:
|
| case TYPE_CODE_COMPLEX:
|
| case TYPE_CODE_NAMESPACE:
|
| case TYPE_CODE_DECFLOAT:
|
| @@ -369,6 +425,14 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
|
| did_print_modifier = 1;
|
| }
|
|
|
| + if (TYPE_RESTRICT (type))
|
| + {
|
| + if (did_print_modifier || need_pre_space)
|
| + fprintf_filtered (stream, " ");
|
| + fprintf_filtered (stream, "restrict");
|
| + did_print_modifier = 1;
|
| + }
|
| +
|
| address_space_id = address_space_int_to_name (get_type_arch (type),
|
| TYPE_INSTANCE_FLAGS (type));
|
| if (address_space_id)
|
| @@ -395,15 +459,13 @@ c_type_print_modifier (struct type *type, struct ui_file *stream,
|
|
|
| void
|
| c_type_print_args (struct type *type, struct ui_file *stream,
|
| - int linkage_name, enum language language)
|
| + int linkage_name, enum language language,
|
| + const struct type_print_options *flags)
|
| {
|
| - int i, len;
|
| - struct field *args;
|
| + int i;
|
| int printed_any = 0;
|
|
|
| fprintf_filtered (stream, "(");
|
| - args = TYPE_FIELDS (type);
|
| - len = TYPE_NFIELDS (type);
|
|
|
| for (i = 0; i < TYPE_NFIELDS (type); i++)
|
| {
|
| @@ -433,9 +495,9 @@ c_type_print_args (struct type *type, struct ui_file *stream,
|
| }
|
|
|
| if (language == language_java)
|
| - java_print_type (param_type, "", stream, -1, 0);
|
| + java_print_type (param_type, "", stream, -1, 0, flags);
|
| else
|
| - c_print_type (param_type, "", stream, -1, 0);
|
| + c_print_type (param_type, "", stream, -1, 0, flags);
|
| printed_any = 1;
|
| }
|
|
|
| @@ -604,7 +666,8 @@ void
|
| c_type_print_varspec_suffix (struct type *type,
|
| struct ui_file *stream,
|
| int show, int passed_a_ptr,
|
| - int demangled_args)
|
| + int demangled_args,
|
| + const struct type_print_options *flags)
|
| {
|
| if (type == 0)
|
| return;
|
| @@ -619,36 +682,38 @@ c_type_print_varspec_suffix (struct type *type,
|
| case TYPE_CODE_ARRAY:
|
| {
|
| LONGEST low_bound, high_bound;
|
| + int is_vector = TYPE_VECTOR (type);
|
|
|
| if (passed_a_ptr)
|
| fprintf_filtered (stream, ")");
|
|
|
| - fprintf_filtered (stream, "[");
|
| + fprintf_filtered (stream, (is_vector ?
|
| + " __attribute__ ((vector_size(" : "["));
|
| if (get_array_bounds (type, &low_bound, &high_bound))
|
| - fprintf_filtered (stream, "%d",
|
| - (int) (high_bound - low_bound + 1));
|
| - fprintf_filtered (stream, "]");
|
| + fprintf_filtered (stream, "%s",
|
| + plongest (high_bound - low_bound + 1));
|
| + fprintf_filtered (stream, (is_vector ? ")))" : "]"));
|
|
|
| c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
| - show, 0, 0);
|
| + show, 0, 0, flags);
|
| }
|
| break;
|
|
|
| case TYPE_CODE_MEMBERPTR:
|
| c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
| - show, 0, 0);
|
| + show, 0, 0, flags);
|
| break;
|
|
|
| case TYPE_CODE_METHODPTR:
|
| fprintf_filtered (stream, ")");
|
| c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
| - show, 0, 0);
|
| + show, 0, 0, flags);
|
| break;
|
|
|
| case TYPE_CODE_PTR:
|
| case TYPE_CODE_REF:
|
| c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
| - show, 1, 0);
|
| + show, 1, 0, flags);
|
| break;
|
|
|
| case TYPE_CODE_METHOD:
|
| @@ -656,14 +721,15 @@ c_type_print_varspec_suffix (struct type *type,
|
| if (passed_a_ptr)
|
| fprintf_filtered (stream, ")");
|
| if (!demangled_args)
|
| - c_type_print_args (type, stream, 0, current_language->la_language);
|
| + c_type_print_args (type, stream, 0, current_language->la_language,
|
| + flags);
|
| c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
| - show, passed_a_ptr, 0);
|
| + show, passed_a_ptr, 0, flags);
|
| break;
|
|
|
| case TYPE_CODE_TYPEDEF:
|
| c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream,
|
| - show, passed_a_ptr, 0);
|
| + show, passed_a_ptr, 0, flags);
|
| break;
|
|
|
| case TYPE_CODE_UNDEF:
|
| @@ -679,7 +745,6 @@ c_type_print_varspec_suffix (struct type *type,
|
| case TYPE_CODE_SET:
|
| case TYPE_CODE_RANGE:
|
| case TYPE_CODE_STRING:
|
| - case TYPE_CODE_BITSTRING:
|
| case TYPE_CODE_COMPLEX:
|
| case TYPE_CODE_NAMESPACE:
|
| case TYPE_CODE_DECFLOAT:
|
| @@ -693,6 +758,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.
|
| @@ -713,7 +828,7 @@ c_type_print_varspec_suffix (struct type *type,
|
|
|
| void
|
| c_type_print_base (struct type *type, struct ui_file *stream,
|
| - int show, int level)
|
| + int show, int level, const struct type_print_options *flags)
|
| {
|
| int i;
|
| int len, real_len;
|
| @@ -727,7 +842,6 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
|
|
| QUIT;
|
|
|
| - wrap_here (" ");
|
| if (type == NULL)
|
| {
|
| fputs_filtered (_("<type unknown>"), stream);
|
| @@ -745,7 +859,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;
|
| }
|
|
|
| @@ -769,207 +883,242 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
| case TYPE_CODE_METHOD:
|
| case TYPE_CODE_METHODPTR:
|
| c_type_print_base (TYPE_TARGET_TYPE (type),
|
| - stream, show, level);
|
| + stream, show, level, flags);
|
| break;
|
|
|
| case TYPE_CODE_STRUCT:
|
| - c_type_print_modifier (type, stream, 0, 1);
|
| - if (TYPE_DECLARED_CLASS (type))
|
| - fprintf_filtered (stream, "class ");
|
| - else
|
| - fprintf_filtered (stream, "struct ");
|
| - goto struct_union;
|
| -
|
| case TYPE_CODE_UNION:
|
| - c_type_print_modifier (type, stream, 0, 1);
|
| - fprintf_filtered (stream, "union ");
|
| -
|
| - struct_union:
|
| -
|
| - /* 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);
|
| - 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
|
| will display; artificial methods will be hidden. */
|
| len = TYPE_NFN_FIELDS (type);
|
| + if (!flags->print_methods)
|
| + len = 0;
|
| real_len = 0;
|
| for (i = 0; i < len; i++)
|
| {
|
| @@ -1001,7 +1150,8 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
| struct cleanup *inner_cleanup;
|
| const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
|
| int is_full_physname_constructor =
|
| - is_constructor_name (physname)
|
| + TYPE_FN_FIELD_CONSTRUCTOR (f, j)
|
| + || is_constructor_name (physname)
|
| || is_destructor_name (physname)
|
| || method_name[0] == '~';
|
|
|
| @@ -1059,8 +1209,9 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
| && !is_full_physname_constructor /* " " */
|
| && !is_type_conversion_operator (type, i, j))
|
| {
|
| - type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
|
| - "", stream, -1);
|
| + c_print_type (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
|
| + "", stream, -1, 0,
|
| + &local_flags);
|
| fputs_filtered (" ", stream);
|
| }
|
| if (TYPE_FN_FIELD_STUB (f, j))
|
| @@ -1076,15 +1227,15 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
| mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);
|
|
|
| demangled_name =
|
| - cplus_demangle (mangled_name,
|
| - DMGL_ANSI | DMGL_PARAMS);
|
| + gdb_demangle (mangled_name,
|
| + DMGL_ANSI | DMGL_PARAMS);
|
| 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);
|
| @@ -1094,7 +1245,7 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
| "",
|
| method_name,
|
| staticp,
|
| - stream);
|
| + stream, &local_flags);
|
| }
|
| else
|
| fprintf_filtered (stream,
|
| @@ -1136,35 +1287,38 @@ c_type_print_base (struct type *type, struct ui_file *stream,
|
|
|
| /* Print typedefs defined in this class. */
|
|
|
| - if (TYPE_TYPEDEF_FIELD_COUNT (type) != 0)
|
| + if (TYPE_TYPEDEF_FIELD_COUNT (type) != 0 && flags->print_typedefs)
|
| {
|
| 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);
|
| -
|
| - /* 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);
|
| - fprintf_filtered (stream, ";\n");
|
| - }
|
| - }
|
| + for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
|
| + {
|
| + struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);
|
| +
|
| + /* 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");
|
| + }
|
| + }
|
|
|
| - fprintfi_filtered (level, stream, "}");
|
| + 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:
|
| @@ -1178,7 +1332,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);
|
| }
|
| @@ -1246,7 +1400,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
|
| {
|
|
|