aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Bothner <per@bothner.com>1997-10-03 23:05:12 +0000
committerPer Bothner <per@bothner.com>1997-10-03 23:05:12 +0000
commit8d2755a953cfc95a09b19010aa47d9c998079acf (patch)
treef5fa6eb95035e87b5ba5b7e8f1375065371c707b
parenta3e8c5b712d92489860090317327dd80d00893a6 (diff)
downloadgdb-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.
-rw-r--r--gdb/ChangeLog19
-rw-r--r--gdb/c-lang.h2
-rw-r--r--gdb/cp-valprint.c2
-rw-r--r--gdb/jv-exp.y33
-rw-r--r--gdb/jv-lang.c182
-rw-r--r--gdb/jv-valprint.c307
-rw-r--r--gdb/parse.c5
-rw-r--r--gdb/parser-defs.h3
8 files changed, 524 insertions, 29 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0660c4c..7801d17 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,22 @@
+Fri Oct 3 15:49:18 1997 Per Bothner <bothner@cygnus.com>
+
+ * 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.
+
Fri Oct 3 09:52:26 1997 Mark Alexander <marka@cygnus.com>
* config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16
diff --git a/gdb/c-lang.h b/gdb/c-lang.h
index c7b2f55..e38df8e 100644
--- a/gdb/c-lang.h
+++ b/gdb/c-lang.h
@@ -59,6 +59,8 @@ c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
extern int vtblprint; /* Controls printing of vtbl's */
+extern int static_field_print;
+
extern void
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index e6790a4..f4edef8 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
int vtblprint; /* Controls printing of vtbl's */
int objectprint; /* Controls looking up an object's derived type
using what we find in its vtables. */
-static int static_field_print; /* Controls printing of static fields. */
+int static_field_print; /* Controls printing of static fields. */
static struct obstack dont_print_vb_obstack;
static struct obstack dont_print_statmem_obstack;
diff --git a/gdb/jv-exp.y b/gdb/jv-exp.y
index 22067a6..9e4c261 100644
--- a/gdb/jv-exp.y
+++ b/gdb/jv-exp.y
@@ -210,7 +210,7 @@ StringLiteral:
}
;
-Literal :
+Literal:
INTEGER_LITERAL
{ write_exp_elt_opcode (OP_LONG);
write_exp_elt_type ($1.type);
@@ -426,6 +426,8 @@ Dims_opt:
FieldAccess:
Primary '.' SimpleName
{ push_fieldnames ($3); }
+| VARIABLE '.' SimpleName
+ { push_fieldnames ($3); }
/*| SUPER '.' SimpleName { FIXME } */
;
@@ -442,10 +444,10 @@ ArrayAccess:
Name '[' Expression ']'
/* FIXME - This is nasty - need to shuffle expr stack. */
{ error ("`Name[Expr]' not implemented yet - try `(Name)[Expr]'"); }
+| VARIABLE '[' Expression ']'
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
| PrimaryNoNewArray '[' Expression ']'
- {
- warning("array subscripts not implemented for Java");
- write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+ { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
;
PostfixExpression:
@@ -503,7 +505,27 @@ CastExpression:
{ write_exp_elt_opcode (UNOP_CAST);
write_exp_elt_type (java_array_type ($2, $3));
write_exp_elt_opcode (UNOP_CAST); }
-| '(' Expression ')' UnaryExpressionNotPlusMinus /* FIXME */
+| '(' Expression ')' UnaryExpressionNotPlusMinus
+ {
+ int exp_size = expout_ptr;
+ int last_exp_size = length_of_subexp(expout, expout_ptr);
+ struct type *type;
+ int i;
+ int base = expout_ptr - last_exp_size - 3;
+ if (base < 0 || expout->elts[base+2].opcode != OP_TYPE)
+ error ("invalid cast expression");
+ type = expout->elts[base+1].type;
+ /* Remove the 'Expression' and slide the
+ UnaryExpressionNotPlusMinus down to replace it. */
+ for (i = 0; i < last_exp_size; i++)
+ expout->elts[base + i] = expout->elts[base + i + 3];
+ expout_ptr -= 3;
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+ type = lookup_pointer_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ write_exp_elt_type (type);
+ write_exp_elt_opcode (UNOP_CAST);
+ }
| '(' Name Dims ')' UnaryExpressionNotPlusMinus
{ write_exp_elt_opcode (UNOP_CAST);
write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
@@ -1277,6 +1299,7 @@ push_qualified_expression_name (name, dot_index)
dot_index++; /* Skip '.' */
name.ptr += dot_index;
name.length -= dot_index;
+ dot_index = 0;
while (dot_index < name.length && name.ptr[dot_index] != '.')
dot_index++;
token.ptr = name.ptr;
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 2c0f7f1..0aec002 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -143,7 +143,7 @@ add_class_symbol (type, addr)
obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
memset (sym, 0, sizeof (struct symbol));
SYMBOL_LANGUAGE (sym) = language_java;
- SYMBOL_NAME (sym) = TYPE_NAME (type);
+ SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
/* SYMBOL_VALUE (sym) = valu;*/
SYMBOL_TYPE (sym) = type;
@@ -177,7 +177,7 @@ java_lookup_class (name)
type = alloc_type (objfile);
TYPE_CODE (type) = TYPE_CODE_STRUCT;
INIT_CPLUS_SPECIFIC (type);
- TYPE_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack);
+ TYPE_TAG_NAME (type) = obsavestring (name, strlen(name), &objfile->type_obstack);
TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
TYPE ? = addr;
return type;
@@ -213,7 +213,22 @@ value_ptr
java_class_from_object (obj_val)
value_ptr obj_val;
{
- value_ptr dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure");
+ /* This is all rather inefficient, since the offsets of dtable and
+ class are fixed. FIXME */
+ value_ptr dtable_val;
+
+ if (TYPE_CODE (VALUE_TYPE (obj_val)) == TYPE_CODE_PTR
+ && TYPE_LENGTH (TYPE_TARGET_TYPE (VALUE_TYPE (obj_val))) == 0)
+ {
+ struct symbol *sym;
+ sym = lookup_symbol ("Hjava_lang_Object", NULL, STRUCT_NAMESPACE,
+ (int *) 0, (struct symtab **) NULL);
+ if (sym != NULL)
+ obj_val = value_at (VALUE_TYPE (sym),
+ value_as_pointer (obj_val), NULL);
+ }
+
+ dtable_val = value_struct_elt (&obj_val, NULL, "dtable", NULL, "structure");
return value_struct_elt (&dtable_val, NULL, "class", NULL, "structure");
}
@@ -303,7 +318,7 @@ type_from_class (clas)
}
ALLOCATE_CPLUS_STRUCT_TYPE (type);
- TYPE_NAME (type) = name;
+ TYPE_TAG_NAME (type) = name;
add_class_symtab_symbol (add_class_symbol (type, addr));
return java_link_class_type (type, clas);
@@ -318,7 +333,7 @@ java_link_class_type (type, clas)
{
value_ptr temp;
char *unqualified_name;
- char *name = TYPE_NAME (type);
+ char *name = TYPE_TAG_NAME (type);
int ninterfaces, nfields, nmethods;
int type_is_object = 0;
struct fn_field *fn_fields;
@@ -385,15 +400,22 @@ java_link_class_type (type, clas)
}
- temp = clas;
- temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
- TYPE_LENGTH (type) = value_as_long (temp);
+ if (name[0] == '[' && tsuper != NULL)
+ {
+ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */
+ }
+ else
+ {
+ temp = clas;
+ temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
+ TYPE_LENGTH (type) = value_as_long (temp);
+ }
fields = NULL;
nfields--; /* First set up dummy "class" field. */
SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
- TYPE_FIELD_NAME (type, nfields) = "super";
+ TYPE_FIELD_NAME (type, nfields) = "class";
TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
SET_TYPE_FIELD_PRIVATE (type, nfields);
@@ -556,7 +578,7 @@ is_object_type (type)
return 0;
while (TYPE_N_BASECLASSES (ttype) > 0)
ttype = TYPE_BASECLASS (ttype, 0);
- name = TYPE_NAME (ttype);
+ name = TYPE_TAG_NAME (ttype);
if (name != NULL && strcmp (name, "java.lang.Object") == 0)
return 1;
name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0;
@@ -674,6 +696,69 @@ java_value_string (ptr, len)
error ("not implemented - java_value_string"); /* FIXME */
}
+/* Print the character C on STREAM as part of the contents of a literal
+ string whose delimiter is QUOTER. Note that that format for printing
+ characters and strings is language specific. */
+
+void
+java_emit_char (c, stream, quoter)
+ register int c;
+ GDB_FILE *stream;
+ int quoter;
+{
+ if (PRINT_LITERAL_FORM (c))
+ {
+ if (c == '\\' || c == quoter)
+ {
+ fputs_filtered ("\\", stream);
+ }
+ fprintf_filtered (stream, "%c", c);
+ }
+ else
+ {
+ switch (c)
+ {
+ case '\n':
+ fputs_filtered ("\\n", stream);
+ break;
+ case '\b':
+ fputs_filtered ("\\b", stream);
+ break;
+ case '\t':
+ fputs_filtered ("\\t", stream);
+ break;
+ case '\f':
+ fputs_filtered ("\\f", stream);
+ break;
+ case '\r':
+ fputs_filtered ("\\r", stream);
+ break;
+ case '\033':
+ fputs_filtered ("\\e", stream);
+ break;
+ case '\007':
+ fputs_filtered ("\\a", stream);
+ break;
+ default:
+ if (c < 256)
+ fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
+ else
+ fprintf_filtered (stream, "\\u%.4x", (unsigned int) c);
+ break;
+ }
+ }
+}
+
+void
+java_printchar (c, stream)
+ int c;
+ GDB_FILE *stream;
+{
+ fputs_filtered ("'", stream);
+ java_emit_char (c, stream, '\'');
+ fputs_filtered ("'", stream);
+}
+
static value_ptr
evaluate_subexp_java (expect_type, exp, pos, noside)
struct type *expect_type;
@@ -683,8 +768,10 @@ evaluate_subexp_java (expect_type, exp, pos, noside)
{
int pc = *pos;
int i;
+ char *name;
enum exp_opcode op = exp->elts[*pos].opcode;
- value_ptr arg1;
+ value_ptr arg1, arg2;
+ struct type *type;
switch (op)
{
case UNOP_IND:
@@ -700,6 +787,70 @@ evaluate_subexp_java (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
return value_ind (arg1);
+
+ case BINOP_SUBSCRIPT:
+ (*pos)++;
+ arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
+ if (noside == EVAL_SKIP)
+ goto nosideret;
+ /* If the user attempts to subscript something that is not an
+ array or pointer type (like a plain int variable for example),
+ then report this as an error. */
+
+ COERCE_REF (arg1);
+ type = check_typedef (VALUE_TYPE (arg1));
+ name = TYPE_NAME (type);
+ if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ {
+ type = check_typedef (TYPE_TARGET_TYPE (type));
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ && TYPE_TAG_NAME (type) != NULL
+ && TYPE_TAG_NAME (type)[0] == '[')
+ {
+ CORE_ADDR address;
+ long length, index;
+ struct type *el_type;
+ char buf4[4];
+
+ value_ptr clas = java_class_from_object(arg1);
+ value_ptr temp = clas;
+ /* Get CLASS_ELEMENT_TYPE of the array type. */
+ temp = value_struct_elt (&temp, NULL, "methods",
+ NULL, "structure");
+ VALUE_TYPE (temp) = VALUE_TYPE (clas);
+ el_type = type_from_class (temp);
+ if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
+ el_type = lookup_pointer_type (el_type);
+
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (el_type, VALUE_LVAL (arg1));
+ address = value_as_pointer (arg1);
+ address += JAVA_OBJECT_SIZE;
+ read_memory (address, buf4, 4);
+ length = (long) extract_signed_integer (buf4, 4);
+ index = (long) value_as_long (arg2);
+ if (index >= length || index < 0)
+ error ("array index (%ld) out of bounds (length: %ld)",
+ index, length);
+ address = (address + 4) + index * TYPE_LENGTH (el_type);
+ return value_at (el_type, address, NULL);
+ }
+ }
+ else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+ {
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
+ else
+ return value_subscript (arg1, arg2);
+ }
+ if (name == NULL)
+ name == TYPE_TAG_NAME (type);
+ if (name)
+ error ("cannot subscript something of type `%s'", name);
+ else
+ error ("cannot subscript requested type");
+
case OP_STRING:
(*pos)++;
i = longest_to_int (exp->elts[pc + 1].longconst);
@@ -707,9 +858,10 @@ evaluate_subexp_java (expect_type, exp, pos, noside)
if (noside == EVAL_SKIP)
goto nosideret;
return java_value_string (&exp->elts[pc + 2].string, i);
+
case STRUCTOP_STRUCT:
arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
- /* Convert object field (such as .class) to reference. */
+ /* Convert object field (such as TYPE.class) to reference. */
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
arg1 = value_addr (arg1);
return arg1;
@@ -791,7 +943,7 @@ const struct language_defn java_language_defn = {
java_parse,
java_error,
evaluate_subexp_java,
- c_printchar, /* Print a character constant */
+ java_printchar, /* Print a character constant */
c_printstr, /* Function to print string constant */
java_create_fundamental_type, /* Create fundamental type in this language */
java_print_type, /* Print a type using appropriate syntax */
@@ -802,14 +954,14 @@ const struct language_defn java_language_defn = {
{"%ld", "", "d", ""}, /* Decimal format info */
{"0x%lx", "0x", "x", ""}, /* Hex format info */
java_op_print_tab, /* expression operators for printing */
- 1, /* c-style arrays */
+ 0, /* not c-style arrays */
0, /* String lower bound */
&builtin_type_char, /* Type of string elements */
LANG_MAGIC
};
void
-_initialize_jave_language ()
+_initialize_java_language ()
{
java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
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,
diff --git a/gdb/parse.c b/gdb/parse.c
index e4ff571..7a9410f 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -59,9 +59,6 @@ free_funcalls PARAMS ((void));
static void
prefixify_expression PARAMS ((struct expression *));
-static int
-length_of_subexp PARAMS ((struct expression *, int));
-
static void
prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int));
@@ -525,7 +522,7 @@ prefixify_expression (expr)
/* Return the number of exp_elements in the subexpression of EXPR
whose last exp_element is at index ENDPOS - 1 in EXPR. */
-static int
+int
length_of_subexp (expr, endpos)
register struct expression *expr;
register int endpos;
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 60c12e6..fed5411 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -133,6 +133,9 @@ pop_type PARAMS ((void));
extern int
pop_type_int PARAMS ((void));
+extern int
+length_of_subexp PARAMS ((struct expression *, int));
+
extern struct type *follow_types PARAMS ((struct type *));
/* During parsing of a C expression, the pointer to the next character