From e88acd96184003169ba2c23cfd807243da100d72 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 1 Mar 2012 19:27:18 +0000 Subject: [PATCH] * valprint.h (struct generic_val_print_decorations): New. (generic_val_print): Declare. * valprint.c (generic_val_print): New function. * p-valprint.c (p_decorations): New global. (pascal_val_print) : Call generic_val_print. * m2-valprint.c (m2_decorations): New global. (m2_val_print) : Call generic_val_print. * f-valprint.c (f_decorations): New global. (f_val_print): Use print_function_pointer_address. : Call generic_val_print. * c-valprint.c (c_decorations): New global. (c_val_print) : Call generic_val_print. * ada-valprint.c (ada_val_print_1) : Remove case. --- gdb/ChangeLog | 30 ++++ gdb/ada-valprint.c | 8 - gdb/c-valprint.c | 270 ++++------------------------------ gdb/f-valprint.c | 167 ++++----------------- gdb/m2-valprint.c | 210 +++++---------------------- gdb/p-valprint.c | 213 ++++----------------------- gdb/valprint.c | 355 +++++++++++++++++++++++++++++++++++++++++++++ gdb/valprint.h | 30 ++++ 8 files changed, 539 insertions(+), 744 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8f254096732..bccff36991e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,33 @@ +2012-03-01 Tom Tromey + + * valprint.h (struct generic_val_print_decorations): New. + (generic_val_print): Declare. + * valprint.c (generic_val_print): New function. + * p-valprint.c (p_decorations): New global. + (pascal_val_print) : Call generic_val_print. + * m2-valprint.c (m2_decorations): New global. + (m2_val_print) : Call generic_val_print. + * f-valprint.c (f_decorations): New global. + (f_val_print): Use print_function_pointer_address. + : Call + generic_val_print. + * c-valprint.c (c_decorations): New global. + (c_val_print) : Call generic_val_print. + * ada-valprint.c (ada_val_print_1) : Remove + case. + 2012-03-01 Tom Tromey * valprint.c (val_print): Update. diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c index 2e44898ca01..a8351ddd74d 100644 --- a/gdb/ada-valprint.c +++ b/gdb/ada-valprint.c @@ -842,14 +842,6 @@ ada_val_print_1 (struct type *type, const gdb_byte *valaddr, } break; - case TYPE_CODE_FLAGS: - if (options->format) - val_print_scalar_formatted (type, valaddr, offset_aligned, - original_value, options, 0, stream); - else - val_print_type_code_flags (type, valaddr + offset_aligned, stream); - break; - case TYPE_CODE_FLT: if (options->format) { diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 12cbb9cd7e1..d1fd56d7ad8 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -116,6 +116,18 @@ c_textual_element_type (struct type *type, char format) return 0; } +/* Decorations for C. */ + +static const struct generic_val_print_decorations c_decorations = +{ + "", + " + ", + " * I", + "true", + "false", + "void" +}; + /* See val_print for a description of the various parameters of this function; they are identical. */ @@ -216,16 +228,6 @@ c_val_print (struct type *type, const gdb_byte *valaddr, addr = address + embedded_offset; goto print_unpacked_pointer; - case TYPE_CODE_MEMBERPTR: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); - break; - case TYPE_CODE_METHODPTR: cplus_print_method_ptr (valaddr + embedded_offset, type, stream); break; @@ -329,45 +331,6 @@ c_val_print (struct type *type, const gdb_byte *valaddr, } break; - case TYPE_CODE_REF: - elttype = check_typedef (TYPE_TARGET_TYPE (type)); - if (options->addressprint) - { - CORE_ADDR addr - = extract_typed_address (valaddr + embedded_offset, type); - - fprintf_filtered (stream, "@"); - fputs_filtered (paddress (gdbarch, addr), stream); - if (options->deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ - if (options->deref_ref) - { - if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) - { - struct value *deref_val; - - deref_val = coerce_ref_if_computed (original_value); - if (deref_val != NULL) - { - /* More complicated computed references are not supported. */ - gdb_assert (embedded_offset == 0); - } - else - deref_val = value_at (TYPE_TARGET_TYPE (type), - unpack_pointer (type, - (valaddr - + embedded_offset))); - - common_val_print (deref_val, stream, recurse, options, - current_language); - } - else - fputs_filtered ("???", stream); - } - break; - case TYPE_CODE_UNION: if (recurse && !options->unionprint) { @@ -402,122 +365,6 @@ c_val_print (struct type *type, const gdb_byte *valaddr, NULL, 0); break; - case TYPE_CODE_ENUM: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr + embedded_offset); - for (i = 0; i < len; i++) - { - QUIT; - if (val == TYPE_FIELD_BITPOS (type, i)) - { - break; - } - } - if (i < len) - { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - else if (TYPE_FLAG_ENUM (type)) - { - int first = 1; - - /* We have a "flag" enum, so we try to decompose it into - pieces as appropriate. A flag enum has disjoint - constants by definition. */ - fputs_filtered ("(", stream); - for (i = 0; i < len; ++i) - { - QUIT; - - if ((val & TYPE_FIELD_BITPOS (type, i)) != 0) - { - if (!first) - fputs_filtered (" | ", stream); - first = 0; - - val &= ~TYPE_FIELD_BITPOS (type, i); - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - } - - if (first || val != 0) - { - if (!first) - fputs_filtered (" | ", stream); - fputs_filtered ("unknown: ", stream); - print_longest (stream, 'd', 0, val); - } - - fputs_filtered (")", stream); - } - else - print_longest (stream, 'd', 0, val); - break; - - case TYPE_CODE_FLAGS: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - val_print_type_code_flags (type, valaddr + embedded_offset, - stream); - break; - - case TYPE_CODE_FUNC: - case TYPE_CODE_METHOD: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - /* FIXME, we should consider, at least for ANSI C language, - eliminating the distinction made between FUNCs and POINTERs - to FUNCs. */ - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - /* Try to print what function it points to, and its address. */ - print_address_demangle (gdbarch, address, stream, demangle); - break; - - case TYPE_CODE_BOOL: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (val == 0) - fputs_filtered ("false", stream); - else if (val == 1) - fputs_filtered ("true", stream); - else - print_longest (stream, 'd', 0, val); - } - break; - - case TYPE_CODE_RANGE: - /* FIXME: create_range_type does not set the unsigned bit in a - range type (I think it probably should copy it from the - target type), so we won't print values which are too large to - fit in a signed integer correctly. */ - /* FIXME: Doesn't handle ranges of enums correctly. (Can't just - print with the target type, though, because the size of our - type and the target type might differ). */ - /* FALLTHROUGH */ - case TYPE_CODE_INT: if (options->format || options->output_format) { @@ -545,92 +392,33 @@ c_val_print (struct type *type, const gdb_byte *valaddr, } break; - case TYPE_CODE_CHAR: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else + case TYPE_CODE_MEMBERPTR: + if (!options->format) { - val = unpack_long (type, valaddr + embedded_offset); - if (TYPE_UNSIGNED (type)) - fprintf_filtered (stream, "%u", (unsigned int) val); - else - fprintf_filtered (stream, "%d", (int) val); - fputs_filtered (" ", stream); - LA_PRINT_CHAR (val, unresolved_type, stream); + cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); + break; } - break; + /* FALLTHROUGH */ + case TYPE_CODE_REF: + case TYPE_CODE_ENUM: + case TYPE_CODE_FLAGS: + case TYPE_CODE_FUNC: + case TYPE_CODE_METHOD: + case TYPE_CODE_BOOL: + case TYPE_CODE_RANGE: case TYPE_CODE_FLT: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - } - else - { - print_floating (valaddr + embedded_offset, type, stream); - } - break; - case TYPE_CODE_DECFLOAT: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_decimal_floating (valaddr + embedded_offset, - type, stream); - break; - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; - case TYPE_CODE_ERROR: - fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); - break; - case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which - don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a - "struct foo *bar" and no complete type for struct foo in that - file. */ - fprintf_filtered (stream, _("")); - break; - case TYPE_CODE_COMPLEX: - if (options->format) - val_print_scalar_formatted (TYPE_TARGET_TYPE (type), - valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_floating (valaddr + embedded_offset, - TYPE_TARGET_TYPE (type), - stream); - fprintf_filtered (stream, " + "); - if (options->format) - val_print_scalar_formatted (TYPE_TARGET_TYPE (type), - valaddr, - embedded_offset - + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), - original_value, - options, 0, stream); - else - print_floating (valaddr + embedded_offset - + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), - TYPE_TARGET_TYPE (type), - stream); - fprintf_filtered (stream, " * I"); - break; - + case TYPE_CODE_CHAR: default: - error (_("Invalid C/C++ type code %d in symbol table."), - TYPE_CODE (type)); + generic_val_print (type, valaddr, embedded_offset, address, + stream, recurse, original_value, options, + &c_decorations); + break; } gdb_flush (stream); } diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 2738cebe5f6..62a71363d96 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -242,6 +242,18 @@ Type node corrupt! F77 arrays cannot have %d subscripts (%d Max)"), } +/* Decorations for Fortran. */ + +static const struct generic_val_print_decorations f_decorations = +{ + "(", + ",", + ")", + ".TRUE.", + ".FALSE.", + "VOID", +}; + /* See val_print for a description of the various parameters of this function; they are identical. */ @@ -304,7 +316,8 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ - print_address_demangle (gdbarch, addr, stream, demangle); + print_function_pointer_address (gdbarch, addr, stream, + options->addressprint); return; } @@ -323,63 +336,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, } break; - case TYPE_CODE_REF: - elttype = check_typedef (TYPE_TARGET_TYPE (type)); - if (options->addressprint) - { - CORE_ADDR addr - = extract_typed_address (valaddr + embedded_offset, type); - - fprintf_filtered (stream, "@"); - fputs_filtered (paddress (gdbarch, addr), stream); - if (options->deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ - if (options->deref_ref) - { - if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) - { - struct value *deref_val; - - deref_val = coerce_ref_if_computed (original_value); - if (deref_val != NULL) - { - /* More complicated computed references are not supported. */ - gdb_assert (embedded_offset == 0); - } - else - deref_val = value_at (TYPE_TARGET_TYPE (type), - unpack_pointer (type, - (valaddr - + embedded_offset))); - - common_val_print (deref_val, stream, recurse, - options, current_language); - } - else - fputs_filtered ("???", stream); - } - break; - - case TYPE_CODE_FUNC: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - /* FIXME, we should consider, at least for ANSI C language, eliminating - the distinction made between FUNCs and POINTERs to FUNCs. */ - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - /* Try to print what function it points to, and its address. */ - print_address_demangle (gdbarch, address, stream, demangle); - break; - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: if (options->format || options->output_format) { struct value_print_options opts = *options; @@ -396,7 +353,7 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, Since we don't know whether the value is really intended to be used as an integer or a character, print the character equivalent as well. */ - if (TYPE_LENGTH (type) == 1 || TYPE_CODE (type) == TYPE_CODE_CHAR) + if (TYPE_LENGTH (type) == 1) { LONGEST c; @@ -407,84 +364,6 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, } break; - case TYPE_CODE_FLAGS: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - val_print_type_code_flags (type, valaddr + embedded_offset, stream); - break; - - case TYPE_CODE_FLT: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_floating (valaddr + embedded_offset, type, stream); - break; - - case TYPE_CODE_VOID: - fprintf_filtered (stream, "VOID"); - break; - - case TYPE_CODE_ERROR: - fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); - break; - - case TYPE_CODE_RANGE: - /* FIXME, we should not ever have to print one of these yet. */ - fprintf_filtered (stream, ""); - break; - - case TYPE_CODE_BOOL: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = extract_unsigned_integer (valaddr + embedded_offset, - TYPE_LENGTH (type), byte_order); - if (val == 0) - fprintf_filtered (stream, ".FALSE."); - else if (val == 1) - fprintf_filtered (stream, ".TRUE."); - else - /* Not a legitimate logical type, print as an integer. */ - { - /* Bash the type code temporarily. */ - TYPE_CODE (type) = TYPE_CODE_INT; - val_print (type, valaddr, embedded_offset, - address, stream, recurse, - original_value, options, current_language); - /* Restore the type code so later uses work as intended. */ - TYPE_CODE (type) = TYPE_CODE_BOOL; - } - } - break; - - case TYPE_CODE_COMPLEX: - type = TYPE_TARGET_TYPE (type); - fputs_filtered ("(", stream); - print_floating (valaddr + embedded_offset, type, stream); - fputs_filtered (",", stream); - print_floating (valaddr + embedded_offset + TYPE_LENGTH (type), - type, stream); - fputs_filtered (")", stream); - break; - - case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which don't use - dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" - and no complete type for struct foo in that file. */ - fprintf_filtered (stream, ""); - break; - case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: /* Starting from the Fortran 90 standard, Fortran supports derived @@ -504,8 +383,22 @@ f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, fprintf_filtered (stream, " )"); break; + case TYPE_CODE_REF: + case TYPE_CODE_FUNC: + case TYPE_CODE_FLAGS: + case TYPE_CODE_FLT: + case TYPE_CODE_VOID: + case TYPE_CODE_ERROR: + case TYPE_CODE_RANGE: + case TYPE_CODE_UNDEF: + case TYPE_CODE_COMPLEX: + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: default: - error (_("Invalid F77 type code %d in symbol table."), TYPE_CODE (type)); + generic_val_print (type, valaddr, embedded_offset, address, + stream, recurse, original_value, options, + &f_decorations); + break; } gdb_flush (stream); } diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c index dade010be91..9e1c1ff435c 100644 --- a/gdb/m2-valprint.c +++ b/gdb/m2-valprint.c @@ -288,6 +288,17 @@ m2_print_array_contents (struct type *type, const gdb_byte *valaddr, } } +/* Decorations for Modula 2. */ + +static const struct generic_val_print_decorations m2_decorations = +{ + "", + " + ", + " * I", + "TRUE", + "FALSE", + "void" +}; /* See val_print for a description of the various parameters of this function; they are identical. */ @@ -372,36 +383,6 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, } break; - case TYPE_CODE_REF: - elttype = check_typedef (TYPE_TARGET_TYPE (type)); - if (options->addressprint) - { - CORE_ADDR addr - = extract_typed_address (valaddr + embedded_offset, type); - - fprintf_filtered (stream, "@"); - fputs_filtered (paddress (gdbarch, addr), stream); - if (options->deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ - if (options->deref_ref) - { - if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) - { - struct value *deref_val = - value_at - (TYPE_TARGET_TYPE (type), - unpack_pointer (type, valaddr + embedded_offset)); - - common_val_print (deref_val, stream, recurse, options, - current_language); - } - else - fputs_filtered ("???", stream); - } - break; - case TYPE_CODE_UNION: if (recurse && !options->unionprint) { @@ -422,134 +403,6 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, options, NULL, 0); break; - case TYPE_CODE_ENUM: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr + embedded_offset); - for (i = 0; i < len; i++) - { - QUIT; - if (val == TYPE_FIELD_BITPOS (type, i)) - { - break; - } - } - if (i < len) - { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - else - { - print_longest (stream, 'd', 0, val); - } - break; - - case TYPE_CODE_FUNC: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - /* FIXME, we should consider, at least for ANSI C language, eliminating - the distinction made between FUNCs and POINTERs to FUNCs. */ - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - /* Try to print what function it points to, and its address. */ - print_address_demangle (gdbarch, address, stream, demangle); - break; - - case TYPE_CODE_BOOL: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (val == 0) - fputs_filtered ("FALSE", stream); - else if (val == 1) - fputs_filtered ("TRUE", stream); - else - fprintf_filtered (stream, "%ld)", (long int) val); - } - break; - - case TYPE_CODE_RANGE: - if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) - { - m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset, - address, stream, recurse, original_value, options); - break; - } - /* FIXME: create_range_type does not set the unsigned bit in a - range type (I think it probably should copy it from the target - type), so we won't print values which are too large to - fit in a signed integer correctly. */ - /* FIXME: Doesn't handle ranges of enums correctly. (Can't just - print with the target type, though, because the size of our type - and the target type might differ). */ - /* FALLTHROUGH */ - - case TYPE_CODE_INT: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - val_print_type_code_int (type, valaddr + embedded_offset, stream); - break; - - case TYPE_CODE_CHAR: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (TYPE_UNSIGNED (type)) - fprintf_filtered (stream, "%u", (unsigned int) val); - else - fprintf_filtered (stream, "%d", (int) val); - fputs_filtered (" ", stream); - LA_PRINT_CHAR ((unsigned char) val, type, stream); - } - break; - - case TYPE_CODE_FLT: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - print_floating (valaddr + embedded_offset, type, stream); - break; - - case TYPE_CODE_METHOD: - break; - case TYPE_CODE_BITSTRING: case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); @@ -624,23 +477,38 @@ m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, } break; - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; + case TYPE_CODE_RANGE: + if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) + { + m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset, + address, stream, recurse, original_value, options); + break; + } + /* FIXME: create_range_type does not set the unsigned bit in a + range type (I think it probably should copy it from the target + type), so we won't print values which are too large to + fit in a signed integer correctly. */ + /* FIXME: Doesn't handle ranges of enums correctly. (Can't just + print with the target type, though, because the size of our type + and the target type might differ). */ + /* FALLTHROUGH */ + case TYPE_CODE_REF: + case TYPE_CODE_ENUM: + case TYPE_CODE_FUNC: + case TYPE_CODE_INT: + case TYPE_CODE_FLT: + case TYPE_CODE_METHOD: + case TYPE_CODE_VOID: case TYPE_CODE_ERROR: - fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); - break; - case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which don't use - dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" - and no complete type for struct foo in that file. */ - fprintf_filtered (stream, _("")); - break; - + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: default: - error (_("Invalid m2 type code %d in symbol table."), TYPE_CODE (type)); + generic_val_print (type, valaddr, embedded_offset, address, + stream, recurse, original_value, options, + &m2_decorations); + break; } gdb_flush (stream); } diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c index a46f3440fbc..d6373aedd4e 100644 --- a/gdb/p-valprint.c +++ b/gdb/p-valprint.c @@ -41,6 +41,18 @@ #include "exceptions.h" +/* Decorations for Pascal. */ + +static const struct generic_val_print_decorations p_decorations = +{ + "", + " + ", + " * I", + "true", + "false", + "void" +}; + /* See val_print for a description of the various parameters of this function; they are identical. */ @@ -249,42 +261,20 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, return; case TYPE_CODE_REF: - elttype = check_typedef (TYPE_TARGET_TYPE (type)); - if (options->addressprint) - { - CORE_ADDR addr - = extract_typed_address (valaddr + embedded_offset, type); - - fprintf_filtered (stream, "@"); - fputs_filtered (paddress (gdbarch, addr), stream); - if (options->deref_ref) - fputs_filtered (": ", stream); - } - /* De-reference the reference. */ - if (options->deref_ref) - { - if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) - { - struct value *deref_val; - - deref_val = coerce_ref_if_computed (original_value); - if (deref_val != NULL) - { - /* More complicated computed references are not supported. */ - gdb_assert (embedded_offset == 0); - } - else - deref_val = value_at (TYPE_TARGET_TYPE (type), - unpack_pointer (type, - (valaddr - + embedded_offset))); - - common_val_print (deref_val, stream, recurse + 1, options, - current_language); - } - else - fputs_filtered ("???", stream); - } + case TYPE_CODE_ENUM: + case TYPE_CODE_FLAGS: + case TYPE_CODE_FUNC: + case TYPE_CODE_RANGE: + case TYPE_CODE_INT: + case TYPE_CODE_FLT: + case TYPE_CODE_VOID: + case TYPE_CODE_ERROR: + case TYPE_CODE_UNDEF: + case TYPE_CODE_BOOL: + case TYPE_CODE_CHAR: + generic_val_print (type, valaddr, embedded_offset, address, + stream, recurse, original_value, options, + &p_decorations); break; case TYPE_CODE_UNION: @@ -331,142 +321,6 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, } break; - case TYPE_CODE_ENUM: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - len = TYPE_NFIELDS (type); - val = unpack_long (type, valaddr + embedded_offset); - for (i = 0; i < len; i++) - { - QUIT; - if (val == TYPE_FIELD_BITPOS (type, i)) - { - break; - } - } - if (i < len) - { - fputs_filtered (TYPE_FIELD_NAME (type, i), stream); - } - else - { - print_longest (stream, 'd', 0, val); - } - break; - - case TYPE_CODE_FLAGS: - if (options->format) - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - else - val_print_type_code_flags (type, valaddr + embedded_offset, stream); - break; - - case TYPE_CODE_FUNC: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - break; - } - /* FIXME, we should consider, at least for ANSI C language, eliminating - the distinction made between FUNCs and POINTERs to FUNCs. */ - fprintf_filtered (stream, "{"); - type_print (type, "", stream, -1); - fprintf_filtered (stream, "} "); - /* Try to print what function it points to, and its address. */ - print_address_demangle (gdbarch, address, stream, demangle); - break; - - case TYPE_CODE_BOOL: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (val == 0) - fputs_filtered ("false", stream); - else if (val == 1) - fputs_filtered ("true", stream); - else - { - fputs_filtered ("true (", stream); - fprintf_filtered (stream, "%ld)", (long int) val); - } - } - break; - - case TYPE_CODE_RANGE: - /* FIXME: create_range_type does not set the unsigned bit in a - range type (I think it probably should copy it from the target - type), so we won't print values which are too large to - fit in a signed integer correctly. */ - /* FIXME: Doesn't handle ranges of enums correctly. (Can't just - print with the target type, though, because the size of our type - and the target type might differ). */ - /* FALLTHROUGH */ - - case TYPE_CODE_INT: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val_print_type_code_int (type, valaddr + embedded_offset, stream); - } - break; - - case TYPE_CODE_CHAR: - if (options->format || options->output_format) - { - struct value_print_options opts = *options; - - opts.format = (options->format ? options->format - : options->output_format); - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, &opts, 0, stream); - } - else - { - val = unpack_long (type, valaddr + embedded_offset); - if (TYPE_UNSIGNED (type)) - fprintf_filtered (stream, "%u", (unsigned int) val); - else - fprintf_filtered (stream, "%d", (int) val); - fputs_filtered (" ", stream); - LA_PRINT_CHAR ((unsigned char) val, type, stream); - } - break; - - case TYPE_CODE_FLT: - if (options->format) - { - val_print_scalar_formatted (type, valaddr, embedded_offset, - original_value, options, 0, stream); - } - else - { - print_floating (valaddr + embedded_offset, type, stream); - } - break; - case TYPE_CODE_BITSTRING: case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); @@ -549,21 +403,6 @@ pascal_val_print (struct type *type, const gdb_byte *valaddr, } break; - case TYPE_CODE_VOID: - fprintf_filtered (stream, "void"); - break; - - case TYPE_CODE_ERROR: - fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); - break; - - case TYPE_CODE_UNDEF: - /* This happens (without TYPE_FLAG_STUB set) on systems which don't use - dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" - and no complete type for struct foo in that file. */ - fprintf_filtered (stream, ""); - break; - default: error (_("Invalid pascal type code %d in symbol table."), TYPE_CODE (type)); diff --git a/gdb/valprint.c b/gdb/valprint.c index 6c20bd9f4d3..0037cb9f304 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -312,6 +312,361 @@ val_print_invalid_address (struct ui_file *stream) fprintf_filtered (stream, _("")); } +/* A generic val_print that is suitable for use by language + implementations of the la_val_print method. This function can + handle most type codes, though not all, notably exception + TYPE_CODE_UNION and TYPE_CODE_STRUCT, which must be implemented by + the caller. + + Most arguments are as to val_print. + + The additional DECORATIONS argument can be used to customize the + output in some small, language-specific ways. */ + +void +generic_val_print (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int recurse, + const struct value *original_value, + const struct value_print_options *options, + const struct generic_val_print_decorations *decorations) +{ + struct gdbarch *gdbarch = get_type_arch (type); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + unsigned int i = 0; /* Number of characters printed. */ + unsigned len; + struct type *elttype, *unresolved_elttype; + struct type *unresolved_type = type; + unsigned eltlen; + LONGEST val; + CORE_ADDR addr; + + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) + { + case TYPE_CODE_ARRAY: + unresolved_elttype = TYPE_TARGET_TYPE (type); + elttype = check_typedef (unresolved_elttype); + if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) + { + LONGEST low_bound, high_bound; + + if (!get_array_bounds (type, &low_bound, &high_bound)) + error (_("Could not determine the array high bound")); + + if (options->prettyprint_arrays) + { + print_spaces_filtered (2 + 2 * recurse, stream); + } + + fprintf_filtered (stream, "{"); + val_print_array_elements (type, valaddr, embedded_offset, + address, stream, + recurse, original_value, options, 0); + fprintf_filtered (stream, "}"); + break; + } + /* Array of unspecified length: treat like pointer to first + elt. */ + addr = address + embedded_offset; + goto print_unpacked_pointer; + + case TYPE_CODE_MEMBERPTR: + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + break; + + case TYPE_CODE_PTR: + if (options->format && options->format != 's') + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + break; + } + unresolved_elttype = TYPE_TARGET_TYPE (type); + elttype = check_typedef (unresolved_elttype); + { + addr = unpack_pointer (type, valaddr + embedded_offset); + print_unpacked_pointer: + + if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) + { + /* Try to print what function it points to. */ + print_function_pointer_address (gdbarch, addr, stream, + options->addressprint); + return; + } + + if (options->addressprint) + fputs_filtered (paddress (gdbarch, addr), stream); + } + break; + + case TYPE_CODE_REF: + elttype = check_typedef (TYPE_TARGET_TYPE (type)); + if (options->addressprint) + { + CORE_ADDR addr + = extract_typed_address (valaddr + embedded_offset, type); + + fprintf_filtered (stream, "@"); + fputs_filtered (paddress (gdbarch, addr), stream); + if (options->deref_ref) + fputs_filtered (": ", stream); + } + /* De-reference the reference. */ + if (options->deref_ref) + { + if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) + { + struct value *deref_val; + + deref_val = coerce_ref_if_computed (original_value); + if (deref_val != NULL) + { + /* More complicated computed references are not supported. */ + gdb_assert (embedded_offset == 0); + } + else + deref_val = value_at (TYPE_TARGET_TYPE (type), + unpack_pointer (type, + (valaddr + + embedded_offset))); + + common_val_print (deref_val, stream, recurse, options, + current_language); + } + else + fputs_filtered ("???", stream); + } + break; + + case TYPE_CODE_ENUM: + if (options->format) + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + break; + } + len = TYPE_NFIELDS (type); + val = unpack_long (type, valaddr + embedded_offset); + for (i = 0; i < len; i++) + { + QUIT; + if (val == TYPE_FIELD_BITPOS (type, i)) + { + break; + } + } + if (i < len) + { + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + } + else if (TYPE_FLAG_ENUM (type)) + { + int first = 1; + + /* We have a "flag" enum, so we try to decompose it into + pieces as appropriate. A flag enum has disjoint + constants by definition. */ + fputs_filtered ("(", stream); + for (i = 0; i < len; ++i) + { + QUIT; + + if ((val & TYPE_FIELD_BITPOS (type, i)) != 0) + { + if (!first) + fputs_filtered (" | ", stream); + first = 0; + + val &= ~TYPE_FIELD_BITPOS (type, i); + fputs_filtered (TYPE_FIELD_NAME (type, i), stream); + } + } + + if (first || val != 0) + { + if (!first) + fputs_filtered (" | ", stream); + fputs_filtered ("unknown: ", stream); + print_longest (stream, 'd', 0, val); + } + + fputs_filtered (")", stream); + } + else + print_longest (stream, 'd', 0, val); + break; + + case TYPE_CODE_FLAGS: + if (options->format) + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + else + val_print_type_code_flags (type, valaddr + embedded_offset, + stream); + break; + + case TYPE_CODE_FUNC: + case TYPE_CODE_METHOD: + if (options->format) + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + break; + } + /* FIXME, we should consider, at least for ANSI C language, + eliminating the distinction made between FUNCs and POINTERs + to FUNCs. */ + fprintf_filtered (stream, "{"); + type_print (type, "", stream, -1); + fprintf_filtered (stream, "} "); + /* Try to print what function it points to, and its address. */ + print_address_demangle (gdbarch, address, stream, demangle); + break; + + case TYPE_CODE_BOOL: + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, &opts, 0, stream); + } + else + { + val = unpack_long (type, valaddr + embedded_offset); + if (val == 0) + fputs_filtered (decorations->false_name, stream); + else if (val == 1) + fputs_filtered (decorations->true_name, stream); + else + print_longest (stream, 'd', 0, val); + } + break; + + case TYPE_CODE_RANGE: + /* FIXME: create_range_type does not set the unsigned bit in a + range type (I think it probably should copy it from the + target type), so we won't print values which are too large to + fit in a signed integer correctly. */ + /* FIXME: Doesn't handle ranges of enums correctly. (Can't just + print with the target type, though, because the size of our + type and the target type might differ). */ + + /* FALLTHROUGH */ + + case TYPE_CODE_INT: + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, &opts, 0, stream); + } + else + val_print_type_code_int (type, valaddr + embedded_offset, stream); + break; + + case TYPE_CODE_CHAR: + if (options->format || options->output_format) + { + struct value_print_options opts = *options; + + opts.format = (options->format ? options->format + : options->output_format); + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, &opts, 0, stream); + } + else + { + val = unpack_long (type, valaddr + embedded_offset); + if (TYPE_UNSIGNED (type)) + fprintf_filtered (stream, "%u", (unsigned int) val); + else + fprintf_filtered (stream, "%d", (int) val); + fputs_filtered (" ", stream); + LA_PRINT_CHAR (val, unresolved_type, stream); + } + break; + + case TYPE_CODE_FLT: + if (options->format) + { + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + } + else + { + print_floating (valaddr + embedded_offset, type, stream); + } + break; + + case TYPE_CODE_DECFLOAT: + if (options->format) + val_print_scalar_formatted (type, valaddr, embedded_offset, + original_value, options, 0, stream); + else + print_decimal_floating (valaddr + embedded_offset, + type, stream); + break; + + case TYPE_CODE_VOID: + fputs_filtered (decorations->void_name, stream); + break; + + case TYPE_CODE_ERROR: + fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); + break; + + case TYPE_CODE_UNDEF: + /* This happens (without TYPE_FLAG_STUB set) on systems which + don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a + "struct foo *bar" and no complete type for struct foo in that + file. */ + fprintf_filtered (stream, _("")); + break; + + case TYPE_CODE_COMPLEX: + fprintf_filtered (stream, "%s", decorations->complex_prefix); + if (options->format) + val_print_scalar_formatted (TYPE_TARGET_TYPE (type), + valaddr, embedded_offset, + original_value, options, 0, stream); + else + print_floating (valaddr + embedded_offset, + TYPE_TARGET_TYPE (type), + stream); + fprintf_filtered (stream, "%s", decorations->complex_infix); + if (options->format) + val_print_scalar_formatted (TYPE_TARGET_TYPE (type), + valaddr, + embedded_offset + + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), + original_value, + options, 0, stream); + else + print_floating (valaddr + embedded_offset + + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), + TYPE_TARGET_TYPE (type), + stream); + fprintf_filtered (stream, "%s", decorations->complex_suffix); + break; + + case TYPE_CODE_UNION: + case TYPE_CODE_STRUCT: + case TYPE_CODE_METHODPTR: + default: + error (_("Unhandled type code %d in symbol table."), + TYPE_CODE (type)); + } + gdb_flush (stream); +} + /* Print using the given LANGUAGE the data of type TYPE located at VALADDR + EMBEDDED_OFFSET (within GDB), which came from the inferior at address ADDRESS + EMBEDDED_OFFSET, onto stdio stream diff --git a/gdb/valprint.h b/gdb/valprint.h index 234a18a18cb..56c0c92c01c 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -163,6 +163,36 @@ extern void val_print_unavailable (struct ui_file *stream); extern void val_print_invalid_address (struct ui_file *stream); +/* An instance of this is passed to generic_val_print and describes + some language-specific ways to print things. */ + +struct generic_val_print_decorations +{ + /* Printing complex numbers: what to print before, between the + elements, and after. */ + + const char *complex_prefix; + const char *complex_infix; + const char *complex_suffix; + + /* Boolean true and false. */ + + const char *true_name; + const char *false_name; + + /* What to print when we see TYPE_CODE_VOID. */ + + const char *void_name; +}; + + +extern void generic_val_print (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int recurse, + const struct value *original_value, + const struct value_print_options *options, + const struct generic_val_print_decorations *); + extern void generic_emit_char (int c, struct type *type, struct ui_file *stream, int quoter, const char *encoding); -- 2.39.2