aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-valprint.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/cp-valprint.c')
-rw-r--r--gdb/cp-valprint.c46
1 files changed, 40 insertions, 6 deletions
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index 3e9beb6..167c6d4 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -295,7 +295,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
opts.deref_ref = 0;
val_print (TYPE_FIELD_TYPE (type, i),
valaddr, offset + TYPE_FIELD_BITPOS (type, i) / 8,
- address + TYPE_FIELD_BITPOS (type, i) / 8,
+ address,
stream, recurse + 1, &opts,
current_language);
}
@@ -321,6 +321,39 @@ cp_print_value_fields (struct type *type, struct type *real_type,
fprintf_filtered (stream, "}");
}
+/* Like cp_print_value_fields, but find the runtime type of the object
+ and pass it as the `real_type' argument to cp_print_value_fields.
+ This function is a hack to work around the fact that
+ common_val_print passes the embedded offset to val_print, but not
+ the enclosing type. */
+
+void
+cp_print_value_fields_rtti (struct type *type,
+ const gdb_byte *valaddr, int offset,
+ CORE_ADDR address,
+ struct ui_file *stream, int recurse,
+ const struct value_print_options *options,
+ struct type **dont_print_vb, int dont_print_statmem)
+{
+ struct value *value;
+ int full, top, using_enc;
+ struct type *real_type;
+
+ /* Ugh, we have to convert back to a value here. */
+ value = value_from_contents_and_address (type, valaddr + offset,
+ address + offset);
+ /* We don't actually care about most of the result here -- just the
+ type. We already have the correct offset, due to how val_print
+ was initially called. */
+ real_type = value_rtti_type (value, &full, &top, &using_enc);
+ if (!real_type)
+ real_type = type;
+
+ cp_print_value_fields (type, real_type, valaddr, offset,
+ address, stream, recurse, options,
+ dont_print_vb, dont_print_statmem);
+}
+
/* Special val_print routine to avoid printing multiple copies of virtual
baseclasses. */
@@ -373,7 +406,7 @@ cp_print_value (struct type *type, struct type *real_type,
thisoffset = offset;
thistype = real_type;
- boffset = baseclass_offset (type, i, valaddr + offset, address);
+ boffset = baseclass_offset (type, i, valaddr + offset, address + offset);
skip = ((boffset == -1) || (boffset + offset) < 0) ? 1 : -1;
if (BASETYPE_VIA_VIRTUAL (type, i))
@@ -384,7 +417,7 @@ cp_print_value (struct type *type, struct type *real_type,
if (boffset != -1
&& ((boffset + offset) < 0
- || (boffset + offset) >= TYPE_LENGTH (type)))
+ || (boffset + offset) >= TYPE_LENGTH (real_type)))
{
/* FIXME (alloca): unsafe if baseclass is really really large. */
gdb_byte *buf = alloca (TYPE_LENGTH (baseclass));
@@ -427,14 +460,14 @@ cp_print_value (struct type *type, struct type *real_type,
if (!options->raw)
result = apply_val_pretty_printer (baseclass, base_valaddr,
thisoffset + boffset,
- address + boffset,
+ address,
stream, recurse,
options,
current_language);
if (!result)
cp_print_value_fields (baseclass, thistype, base_valaddr,
- thisoffset + boffset, address + boffset,
+ thisoffset + boffset, address,
stream, recurse, options,
((struct type **)
obstack_base (&dont_print_vb_obstack)),
@@ -501,7 +534,8 @@ cp_print_static_field (struct type *type,
sizeof (CORE_ADDR));
CHECK_TYPEDEF (type);
- cp_print_value_fields (type, type, value_contents_all (val),
+ cp_print_value_fields (type, value_enclosing_type (val),
+ value_contents_all (val),
value_embedded_offset (val), addr,
stream, recurse, options, NULL, 1);
return;