diff options
author | Per Bothner <per@bothner.com> | 1997-10-03 23:05:12 +0000 |
---|---|---|
committer | Per Bothner <per@bothner.com> | 1997-10-03 23:05:12 +0000 |
commit | 8d2755a953cfc95a09b19010aa47d9c998079acf (patch) | |
tree | f5fa6eb95035e87b5ba5b7e8f1375065371c707b /gdb/jv-valprint.c | |
parent | a3e8c5b712d92489860090317327dd80d00893a6 (diff) | |
download | gdb-8d2755a953cfc95a09b19010aa47d9c998079acf.zip gdb-8d2755a953cfc95a09b19010aa47d9c998079acf.tar.gz gdb-8d2755a953cfc95a09b19010aa47d9c998079acf.tar.bz2 |
* c-lang.h, cp-valprint.c (static_field_print): Make non-static.
* parse.c, parser-defs.h (length_of_subexp): Make non-static.
* jv-exp.y (FieldAccess): Handle dollar-VARIABLE as primary.
(ArrayAccess): Likewise. Also remove warnings.
(CastExpression): Implement (typename) UnaryExpression.
(push_qualified_expression_name): Fix small bug.
* jv-lang.c: Use TYPE_TAG_NAME, not TYPE_NAME for class names.
(_initialize_jave_language): Fix typo (jave -> java).
(java_language): Java does *not* have C-style arrays.
(java_class_from_object): Make more general (and complicated).
(java_link_class_type): Fix typo "super" -> "class". Handle arrays.
(java_emit_char, java_printchar): New function.
(evaluate_subexp_java case BINOP_SUBSCRIPT): Handle Java arrays.
* jv-valprint.c (java_value_print): Implement printing of Java arrays.
(java_print_value_fields): New function.
(java_val_print): Better printing of TYPE_CODE_CHAR, TYPE_CODE_STRUCT.
Diffstat (limited to 'gdb/jv-valprint.c')
-rw-r--r-- | gdb/jv-valprint.c | 307 |
1 files changed, 303 insertions, 4 deletions
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c index b4afa1e..d46c4b8 100644 --- a/gdb/jv-valprint.c +++ b/gdb/jv-valprint.c @@ -56,10 +56,95 @@ java_value_print (val, stream, format, pretty) 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); + char buf4[4]; + long length; + unsigned int things_printed = 0; + int i = 0; + int reps; + read_memory (address + JAVA_OBJECT_SIZE, buf4, 4); + length = (long) extract_signed_integer (buf4, 4); + fprintf_filtered (stream, "{length: %ld", length); + if (TYPE_TAG_NAME (type)[1] == 'L' + || TYPE_TAG_NAME (type)[1] == '[') + { + CORE_ADDR element, next_element; + address += JAVA_OBJECT_SIZE + 4; /* Skip object header and length. */ + while (i < length && things_printed < print_max) + { + char buf[TARGET_PTR_BIT / HOST_CHAR_BIT]; + fputs_filtered (", ", stream); + wrap_here (n_spaces (2)); + if (i > 0) + element = next_element; + else + { + read_memory (address, buf, sizeof(buf)); + address += TARGET_PTR_BIT / HOST_CHAR_BIT; + element = extract_address (buf, sizeof(buf)); + } + for (reps = 1; i + reps < length; reps++) + { + read_memory (address, buf, sizeof(buf)); + address += TARGET_PTR_BIT / HOST_CHAR_BIT; + next_element = extract_address (buf, sizeof(buf)); + if (next_element != element) + break; + } + if (reps == 1) + fprintf_filtered (stream, "%d: ", i); + else + fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); + if (element == 0) + fprintf_filtered (stream, "null"); + else + fprintf_filtered (stream, "@%x", element); + things_printed++; + i += reps; + } + } + else + { + struct type *el_type = java_primitive_type (TYPE_TAG_NAME (type)[1]); + value_ptr v = allocate_value (el_type); + value_ptr next_v = allocate_value (el_type); + VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4; + VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v); + + while (i < length && things_printed < print_max) + { + fputs_filtered (", ", stream); + wrap_here (n_spaces (2)); + if (i > 0) + { + value_ptr tmp = next_v; next_v = v; v = tmp; + } + else + { + VALUE_LAZY (v) = 1; + VALUE_OFFSET (v) = 0; + } + VALUE_OFFSET (next_v) = VALUE_OFFSET (v); + for (reps = 1; i + reps < length; reps++) + { + VALUE_LAZY (next_v) = 1; + VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type); + if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v), + TYPE_LENGTH (el_type)) != 0) + break; + } + if (reps == 1) + fprintf_filtered (stream, "%d: ", i); + else + fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); + val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, + stream, format, 2, 1, pretty); + things_printed++; + i += reps; + } + } + + if (i < length) + fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } @@ -68,6 +153,206 @@ java_value_print (val, stream, format, pretty) stream, format, 1, 0, pretty)); } +/* TYPE, VALADDR, ADDRESS, STREAM, RECURSE, and PRETTY have the + same meanings as in cp_print_value and c_val_print. + + DONT_PRINT is an array of baseclass types that we + should not print, or zero if called from top level. */ + +void +java_print_value_fields (type, valaddr, address, stream, + format, recurse, pretty) + struct type *type; + char *valaddr; + CORE_ADDR address; + GDB_FILE *stream; + int format; + int recurse; + enum val_prettyprint pretty; +{ + int i, len, n_baseclasses; + + CHECK_TYPEDEF (type); + + fprintf_filtered (stream, "{"); + len = TYPE_NFIELDS (type); + n_baseclasses = TYPE_N_BASECLASSES (type); + + if (n_baseclasses > 0) + { + int i, n_baseclasses = TYPE_N_BASECLASSES (type); + + for (i = 0; i < n_baseclasses; i++) + { + int boffset; + struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); + char *basename = TYPE_NAME (baseclass); + char *base_valaddr; + + if (BASETYPE_VIA_VIRTUAL (type, i)) + continue; + + if (basename != NULL && strcmp (basename, "java.lang.Object") == 0) + continue; + + boffset = 0; + + if (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 * (recurse+1), stream); + } + fputs_filtered ("<", stream); + /* Not sure what the best notation is in the case where there is no + baseclass name. */ + fputs_filtered (basename ? basename : "", stream); + fputs_filtered ("> = ", stream); + + base_valaddr = valaddr; + + java_print_value_fields (baseclass, base_valaddr, address + boffset, + stream, format, recurse+1, pretty); + fputs_filtered (", ", stream); + + flush_it: + ; + } + + } + + if (!len && n_baseclasses == 1) + fprintf_filtered (stream, "<No data fields>"); + else + { + extern int inspect_it; + int fields_seen = 0; + + for (i = n_baseclasses; i < len; i++) + { + /* If requested, skip printing of static fields. */ + if (TYPE_FIELD_STATIC (type, i)) + { + char *name = TYPE_FIELD_NAME (type, i); + if (!static_field_print) + continue; + if (name != NULL && strcmp (name, "class") == 0) + continue; + } + if (fields_seen) + fprintf_filtered (stream, ", "); + else if (n_baseclasses > 0) + { + if (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 + 2 * recurse, stream); + fputs_filtered ("members of ", stream); + fputs_filtered (type_name_no_tag (type), stream); + fputs_filtered (": ", stream); + } + } + fields_seen = 1; + + if (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 + 2 * recurse, stream); + } + else + { + wrap_here (n_spaces (2 + 2 * recurse)); + } + if (inspect_it) + { + if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) + fputs_filtered ("\"( ptr \"", stream); + else + fputs_filtered ("\"( nodef \"", stream); + if (TYPE_FIELD_STATIC (type, i)) + fputs_filtered ("static ", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); + fputs_filtered ("\" \"", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); + fputs_filtered ("\") \"", stream); + } + else + { + annotate_field_begin (TYPE_FIELD_TYPE (type, i)); + + if (TYPE_FIELD_STATIC (type, i)) + fputs_filtered ("static ", stream); + fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), + language_cplus, + DMGL_PARAMS | DMGL_ANSI); + annotate_field_name_end (); + fputs_filtered (": ", stream); + annotate_field_value (); + } + + if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) + { + value_ptr v; + + /* Bitfields require special handling, especially due to byte + order problems. */ + if (TYPE_FIELD_IGNORE (type, i)) + { + fputs_filtered ("<optimized out or zero length>", stream); + } + else + { + v = value_from_longest (TYPE_FIELD_TYPE (type, i), + unpack_field_as_long (type, valaddr, i)); + + val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0, + stream, format, 0, recurse + 1, pretty); + } + } + else + { + if (TYPE_FIELD_IGNORE (type, i)) + { + fputs_filtered ("<optimized out or zero length>", stream); + } + else if (TYPE_FIELD_STATIC (type, i)) + { + value_ptr v = value_static_field (type, i); + if (v == NULL) + fputs_filtered ("<optimized out>", stream); + else + { + struct type *t = check_typedef (VALUE_TYPE (v)); + if (TYPE_CODE (t) == TYPE_CODE_STRUCT) + v = value_addr (v); + val_print (VALUE_TYPE (v), + VALUE_CONTENTS (v), VALUE_ADDRESS (v), + stream, format, 0, recurse+1, pretty); + } + } + else + { + val_print (TYPE_FIELD_TYPE (type, i), + valaddr + TYPE_FIELD_BITPOS (type, i) / 8, + address + TYPE_FIELD_BITPOS (type, i) / 8, + stream, format, 0, recurse + 1, pretty); + } + } + annotate_field_end (); + } + + if (pretty) + { + fprintf_filtered (stream, "\n"); + print_spaces_filtered (2 * recurse, stream); + } + } + fprintf_filtered (stream, "}"); +} + int java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty) @@ -130,6 +415,20 @@ java_val_print (type, valaddr, address, stream, format, deref_ref, recurse, } return i; } + case TYPE_CODE_CHAR: + format = format ? format : output_format; + if (format) + { + print_scalar_formatted (valaddr, type, format, 0, stream); + } + else + { + LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream); + } + break; + case TYPE_CODE_STRUCT: + java_print_value_fields (type, valaddr, address, stream, format, + recurse, pretty); break; default: return c_val_print (type, valaddr, address, stream, format, |