/* Support for printing Java values for GDB, the GNU debugger. Copyright 1997 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" #include "value.h" #include "demangle.h" #include "valprint.h" #include "language.h" #include "jv-lang.h" #include "c-lang.h" int java_value_print (val, stream, format, pretty) value_ptr val; GDB_FILE *stream; int format; enum val_prettyprint pretty; { struct type *type = VALUE_TYPE (val); CORE_ADDR address = VALUE_ADDRESS (val) + VALUE_OFFSET (val); if (is_object_type (type)) { CORE_ADDR obj_addr = unpack_pointer (type, VALUE_CONTENTS (val)); if (obj_addr != 0) { value_ptr obj_val = value_at (TYPE_TARGET_TYPE (type), obj_addr, NULL); type = type_from_class (java_class_from_object (obj_val)); type = lookup_pointer_type (type); } } if (TYPE_CODE (type) == TYPE_CODE_PTR && ! value_logical_not (val)) { type_print (TYPE_TARGET_TYPE (type), "", stream, -1); } if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[') { value_ptr len = value_at (java_int_type, address + JAVA_OBJECT_SIZE, 0); long length = value_as_long (len); fprintf_filtered (stream, "{"); fprintf_filtered (stream, "length = %ld", length); fprintf_filtered (stream, "}"); return 0; } return (val_print (type, VALUE_CONTENTS (val), address, stream, format, 1, 0, pretty)); } int java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty) struct type *type; char *valaddr; CORE_ADDR address; GDB_FILE *stream; int format; int deref_ref; int recurse; enum val_prettyprint pretty; { register unsigned int i = 0; /* Number of characters printed */ struct type *elttype; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr, type, format, 0, stream); break; } #if 0 if (vtblprint && cp_is_vtbl_ptr_type(type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ print_address_demangle(extract_address (valaddr, TYPE_LENGTH (type)), stream, demangle); break; } #endif addr = unpack_pointer (type, valaddr); if (addr == 0) { fputs_filtered ("null", stream); return i; } elttype = check_typedef (TYPE_TARGET_TYPE (type)); { print_unpacked_pointer: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_address_demangle (addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return (0); } if (addressprint && format != 's') { fputs_filtered ("@", stream); print_longest (stream, 'x', 0, (ULONGEST) addr); } return i; } break; default: return c_val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty); } }