mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 17:40:49 +00:00
* 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.
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user