Index: gdb/c-valprint.c |
diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c |
index 9949015d868ad8013c534829e3394361481bf167..7a1bb02be630d141b8c178ef00a7d2bbc933413f 100644 |
--- a/gdb/c-valprint.c |
+++ b/gdb/c-valprint.c |
@@ -31,31 +31,6 @@ |
#include "target.h" |
-/* Print function pointer with inferior address ADDRESS onto stdio |
- stream STREAM. */ |
- |
-static void |
-print_function_pointer_address (struct gdbarch *gdbarch, |
- CORE_ADDR address, |
- struct ui_file *stream, |
- int addressprint) |
-{ |
- CORE_ADDR func_addr |
- = gdbarch_convert_from_func_ptr_addr (gdbarch, address, |
- ¤t_target); |
- |
- /* If the function pointer is represented by a description, print |
- the address of the description. */ |
- if (addressprint && func_addr != address) |
- { |
- fputs_filtered ("@", stream); |
- fputs_filtered (paddress (gdbarch, address), stream); |
- fputs_filtered (": ", stream); |
- } |
- print_address_demangle (gdbarch, func_addr, stream, demangle); |
-} |
- |
- |
/* A helper for c_textual_element_type. This checks the name of the |
typedef. This is bogus but it isn't apparent that the compiler |
provides us the help we may need. */ |
@@ -141,11 +116,22 @@ 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. The semantics of the return value is |
- also identical to val_print. */ |
+ function; they are identical. */ |
-int |
+void |
c_val_print (struct type *type, const gdb_byte *valaddr, |
int embedded_offset, CORE_ADDR address, |
struct ui_file *stream, int recurse, |
@@ -159,7 +145,6 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
struct type *elttype, *unresolved_elttype; |
struct type *unresolved_type = type; |
unsigned eltlen; |
- LONGEST val; |
CORE_ADDR addr; |
CHECK_TYPEDEF (type); |
@@ -242,16 +227,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; |
@@ -272,28 +247,34 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
CORE_ADDR addr |
= extract_typed_address (valaddr + embedded_offset, type); |
- print_function_pointer_address (gdbarch, addr, stream, |
- options->addressprint); |
+ print_function_pointer_address (options, gdbarch, addr, stream); |
break; |
} |
unresolved_elttype = TYPE_TARGET_TYPE (type); |
elttype = check_typedef (unresolved_elttype); |
{ |
+ int want_space; |
+ |
addr = unpack_pointer (type, valaddr + embedded_offset); |
print_unpacked_pointer: |
+ want_space = 0; |
+ |
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 value is irrelevant except for string |
- pointers. */ |
- return (0); |
+ print_function_pointer_address (options, gdbarch, addr, stream); |
+ return; |
} |
- if (options->addressprint) |
- fputs_filtered (paddress (gdbarch, addr), stream); |
+ if (options->symbol_print) |
+ want_space = print_address_demangle (options, gdbarch, addr, |
+ stream, demangle); |
+ else if (options->addressprint) |
+ { |
+ fputs_filtered (paddress (gdbarch, addr), stream); |
+ want_space = 1; |
+ } |
/* For a pointer to a textual type, also print the string |
pointed to, unless pointer is null. */ |
@@ -302,6 +283,8 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
options->format) |
&& addr != 0) |
{ |
+ if (want_space) |
+ fputs_filtered (" ", stream); |
i = val_print_string (unresolved_elttype, NULL, |
addr, -1, |
stream, options); |
@@ -312,16 +295,22 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
CORE_ADDR vt_address = unpack_pointer (type, |
valaddr |
+ embedded_offset); |
- |
struct minimal_symbol *msymbol = |
lookup_minimal_symbol_by_pc (vt_address); |
- if ((msymbol != NULL) |
+ |
+ /* If 'symbol_print' is set, we did the work above. */ |
+ if (!options->symbol_print |
+ && (msymbol != NULL) |
&& (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) |
{ |
+ if (want_space) |
+ fputs_filtered (" ", stream); |
fputs_filtered (" <", stream); |
fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); |
fputs_filtered (">", stream); |
+ want_space = 1; |
} |
+ |
if (vt_address && options->vtblprint) |
{ |
struct value *vt_val; |
@@ -330,6 +319,9 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
struct block *block = (struct block *) NULL; |
int is_this_fld; |
+ if (want_space) |
+ fputs_filtered (" ", stream); |
+ |
if (msymbol != NULL) |
wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), |
block, VAR_DOMAIN, |
@@ -353,51 +345,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
} |
} |
} |
- |
- /* Return number of characters printed, including the |
- terminating '\0' if we reached the end. val_print_string |
- takes care including the terminating '\0' if |
- necessary. */ |
- return i; |
- } |
- 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); |
+ return; |
} |
break; |
@@ -424,8 +372,7 @@ c_val_print (struct type *type, const gdb_byte *valaddr, |
CORE_ADDR addr |
= extract_typed_address (valaddr + offset, field_type); |
- print_function_pointer_address (gdbarch, addr, stream, |
- options->addressprint); |
+ print_function_pointer_address (options, gdbarch, addr, stream); |
} |
else |
cp_print_value_fields_rtti (type, valaddr, |
@@ -435,91 +382,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 |
- { |
- 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) |
{ |
@@ -547,98 +409,38 @@ 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, _("<incomplete type>")); |
- 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); |
- return (0); |
} |
-int |
+void |
c_value_print (struct value *val, struct ui_file *stream, |
const struct value_print_options *options) |
{ |
@@ -697,22 +499,13 @@ c_value_print (struct value *val, struct ui_file *stream, |
if (value_entirely_available (val)) |
{ |
- real_type = value_rtti_target_type (val, &full, &top, &using_enc); |
+ real_type = value_rtti_indirect_type (val, &full, &top, |
+ &using_enc); |
if (real_type) |
{ |
/* RTTI entry found. */ |
- if (TYPE_CODE (type) == TYPE_CODE_PTR) |
- { |
- /* Create a pointer type pointing to the real |
- type. */ |
- type = lookup_pointer_type (real_type); |
- } |
- else |
- { |
- /* Create a reference type referencing the real |
- type. */ |
- type = lookup_reference_type (real_type); |
- } |
+ type = real_type; |
+ |
/* Need to adjust pointer value. */ |
val = value_from_pointer (type, value_as_address (val) - top); |
@@ -751,10 +544,11 @@ c_value_print (struct value *val, struct ui_file *stream, |
full ? "" : _(" [incomplete object]")); |
/* Print out object: enclosing type is same as real_type if |
full. */ |
- return val_print (value_enclosing_type (val), |
- value_contents_for_printing (val), 0, |
- value_address (val), stream, 0, |
- val, &opts, current_language); |
+ val_print (value_enclosing_type (val), |
+ value_contents_for_printing (val), 0, |
+ value_address (val), stream, 0, |
+ val, &opts, current_language); |
+ return; |
/* Note: When we look up RTTI entries, we don't get any |
information on const or volatile attributes. */ |
} |
@@ -763,17 +557,18 @@ c_value_print (struct value *val, struct ui_file *stream, |
/* No RTTI information, so let's do our best. */ |
fprintf_filtered (stream, "(%s ?) ", |
TYPE_NAME (value_enclosing_type (val))); |
- return val_print (value_enclosing_type (val), |
- value_contents_for_printing (val), 0, |
- value_address (val), stream, 0, |
- val, &opts, current_language); |
+ val_print (value_enclosing_type (val), |
+ value_contents_for_printing (val), 0, |
+ value_address (val), stream, 0, |
+ val, &opts, current_language); |
+ return; |
} |
/* Otherwise, we end up at the return outside this "if". */ |
} |
- return val_print (val_type, value_contents_for_printing (val), |
- value_embedded_offset (val), |
- value_address (val), |
- stream, 0, |
- val, &opts, current_language); |
+ val_print (val_type, value_contents_for_printing (val), |
+ value_embedded_offset (val), |
+ value_address (val), |
+ stream, 0, |
+ val, &opts, current_language); |
} |