X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fcp-valprint.c;h=e6a99ecb873e84175248e440fc7914f3aceaae4c;hb=b786c521573fce15b05c4b879e05f9cc592e1e4b;hp=ff3908d3e79a9bd212c964d749f96ddbba9bff4c;hpb=de4127a3b22abd0e9e69f61f6e52b5f891050ffd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index ff3908d3e7..e6a99ecb87 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -1,8 +1,7 @@ /* Support for printing C++ values for GDB, the GNU debugger. - Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 1986, 1988-1989, 1991-1997, 2000-2003, 2005-2012 Free + Software Foundation, Inc. This file is part of GDB. @@ -37,6 +36,7 @@ #include "cp-support.h" #include "language.h" #include "python/python.h" +#include "exceptions.h" /* Controls printing of vtbl's. */ static void @@ -98,7 +98,7 @@ const char vtbl_ptr_name[] = "__vtbl_ptr_type"; int cp_is_vtbl_ptr_type (struct type *type) { - char *typename = type_name_no_tag (type); + const char *typename = type_name_no_tag (type); return (typename != NULL && !strcmp (typename, vtbl_ptr_name)); } @@ -210,7 +210,9 @@ cp_print_value_fields (struct type *type, struct type *real_type, { int statmem_obstack_initial_size = 0; int stat_array_obstack_initial_size = 0; - + struct type *vptr_basetype = NULL; + int vptr_fieldno; + if (dont_print_statmem == 0) { statmem_obstack_initial_size = @@ -225,6 +227,7 @@ cp_print_value_fields (struct type *type, struct type *real_type, } } + vptr_fieldno = get_vptr_fieldno (type, &vptr_basetype); for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ @@ -316,16 +319,15 @@ cp_print_value_fields (struct type *type, struct type *real_type, TYPE_FIELD_BITPOS (type, i), TYPE_FIELD_BITSIZE (type, i))) { - fputs_filtered (_(""), stream); + val_print_optimized_out (stream); } else { struct value_print_options opts = *options; opts.deref_ref = 0; - v = value_from_longest - (TYPE_FIELD_TYPE (type, i), - unpack_field_as_long (type, valaddr + offset, i)); + + v = value_field_bitfield (type, i, valaddr, offset, val); common_val_print (v, stream, recurse + 1, &opts, current_language); @@ -340,15 +342,40 @@ cp_print_value_fields (struct type *type, struct type *real_type, } else if (field_is_static (&TYPE_FIELD (type, i))) { - struct value *v = value_static_field (type, i); - - if (v == NULL) - fputs_filtered ("", stream); + volatile struct gdb_exception ex; + struct value *v = NULL; + + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + v = value_static_field (type, i); + } + + if (ex.reason < 0) + fprintf_filtered (stream, + _(""), + ex.message); + else if (v == NULL) + val_print_optimized_out (stream); else cp_print_static_field (TYPE_FIELD_TYPE (type, i), v, stream, recurse + 1, options); } + else if (i == vptr_fieldno && type == vptr_basetype) + { + int i_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; + struct type *i_type = TYPE_FIELD_TYPE (type, i); + + if (valprint_check_validity (stream, i_type, i_offset, val)) + { + CORE_ADDR addr; + + addr = extract_typed_address (valaddr + i_offset, i_type); + print_function_pointer_address (options, + get_type_arch (type), + addr, stream); + } + } else { struct value_print_options opts = *options; @@ -483,12 +510,13 @@ cp_print_value (struct type *type, struct type *real_type, for (i = 0; i < n_baseclasses; i++) { - int boffset; + int boffset = 0; int skip; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); - char *basename = TYPE_NAME (baseclass); - const gdb_byte *base_valaddr; - const struct value *base_val; + const char *basename = TYPE_NAME (baseclass); + const gdb_byte *base_valaddr = NULL; + const struct value *base_val = NULL; + volatile struct gdb_exception ex; if (BASETYPE_VIA_VIRTUAL (type, i)) { @@ -508,34 +536,50 @@ cp_print_value (struct type *type, struct type *real_type, thisoffset = offset; thistype = real_type; - boffset = baseclass_offset (type, i, valaddr + offset, - address + offset); - skip = ((boffset == -1) || (boffset + offset) < 0); - - if (BASETYPE_VIA_VIRTUAL (type, i)) + TRY_CATCH (ex, RETURN_MASK_ERROR) { - /* The virtual base class pointer might have been clobbered - by the user program. Make sure that it still points to a - valid memory location. */ + boffset = baseclass_offset (type, i, valaddr, offset, address, val); + } + if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR) + skip = -1; + else if (ex.reason < 0) + skip = 1; + else + { + skip = 0; - if (boffset != -1 - && ((boffset + offset) < 0 - || (boffset + offset) >= TYPE_LENGTH (real_type))) + if (BASETYPE_VIA_VIRTUAL (type, i)) { - /* FIXME (alloca): unsafe if baseclass is really really - large. */ - gdb_byte *buf = alloca (TYPE_LENGTH (baseclass)); - - if (target_read_memory (address + boffset, buf, - TYPE_LENGTH (baseclass)) != 0) - skip = 1; - base_val = value_from_contents_and_address (baseclass, - buf, - address + boffset); - thisoffset = 0; - boffset = 0; - thistype = baseclass; - base_valaddr = value_contents_for_printing_const (base_val); + /* The virtual base class pointer might have been + clobbered by the user program. Make sure that it + still points to a valid memory location. */ + + if ((boffset + offset) < 0 + || (boffset + offset) >= TYPE_LENGTH (real_type)) + { + gdb_byte *buf; + struct cleanup *back_to; + + buf = xmalloc (TYPE_LENGTH (baseclass)); + back_to = make_cleanup (xfree, buf); + + if (target_read_memory (address + boffset, buf, + TYPE_LENGTH (baseclass)) != 0) + skip = 1; + base_val = value_from_contents_and_address (baseclass, + buf, + address + boffset); + thisoffset = 0; + boffset = 0; + thistype = baseclass; + base_valaddr = value_contents_for_printing_const (base_val); + do_cleanups (back_to); + } + else + { + base_valaddr = valaddr; + base_val = val; + } } else { @@ -543,11 +587,6 @@ cp_print_value (struct type *type, struct type *real_type, base_val = val; } } - else - { - base_valaddr = valaddr; - base_val = val; - } /* Now do the printing. */ if (options->pretty) @@ -561,9 +600,10 @@ cp_print_value (struct type *type, struct type *real_type, fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); - - if (skip) - fprintf_filtered (stream, ""); + if (skip < 0) + val_print_unavailable (stream); + else if (skip > 0) + val_print_invalid_address (stream); else { int result = 0; @@ -775,7 +815,7 @@ cp_print_class_member (const gdb_byte *valaddr, struct type *type, if (domain != NULL) { - char *name; + const char *name; fputs_filtered (prefix, stream); name = type_name_no_tag (domain);