* 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:
parent
a3e8c5b712
commit
8d2755a953
8 changed files with 524 additions and 29 deletions
|
@ -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>
|
Fri Oct 3 09:52:26 1997 Mark Alexander <marka@cygnus.com>
|
||||||
|
|
||||||
* config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16
|
* config/mips/tm-mips.h (MAKE_MSYMBOL_SPECIAL): Force MIPS16
|
||||||
|
|
|
@ -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 vtblprint; /* Controls printing of vtbl's */
|
||||||
|
|
||||||
|
extern int static_field_print;
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
|
cp_print_class_member PARAMS ((char *, struct type *, GDB_FILE *, char *));
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
int vtblprint; /* Controls printing of vtbl's */
|
int vtblprint; /* Controls printing of vtbl's */
|
||||||
int objectprint; /* Controls looking up an object's derived type
|
int objectprint; /* Controls looking up an object's derived type
|
||||||
using what we find in its vtables. */
|
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_vb_obstack;
|
||||||
static struct obstack dont_print_statmem_obstack;
|
static struct obstack dont_print_statmem_obstack;
|
||||||
|
|
33
gdb/jv-exp.y
33
gdb/jv-exp.y
|
@ -210,7 +210,7 @@ StringLiteral:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
Literal :
|
Literal:
|
||||||
INTEGER_LITERAL
|
INTEGER_LITERAL
|
||||||
{ write_exp_elt_opcode (OP_LONG);
|
{ write_exp_elt_opcode (OP_LONG);
|
||||||
write_exp_elt_type ($1.type);
|
write_exp_elt_type ($1.type);
|
||||||
|
@ -426,6 +426,8 @@ Dims_opt:
|
||||||
FieldAccess:
|
FieldAccess:
|
||||||
Primary '.' SimpleName
|
Primary '.' SimpleName
|
||||||
{ push_fieldnames ($3); }
|
{ push_fieldnames ($3); }
|
||||||
|
| VARIABLE '.' SimpleName
|
||||||
|
{ push_fieldnames ($3); }
|
||||||
/*| SUPER '.' SimpleName { FIXME } */
|
/*| SUPER '.' SimpleName { FIXME } */
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -442,10 +444,10 @@ ArrayAccess:
|
||||||
Name '[' Expression ']'
|
Name '[' Expression ']'
|
||||||
/* FIXME - This is nasty - need to shuffle expr stack. */
|
/* FIXME - This is nasty - need to shuffle expr stack. */
|
||||||
{ error ("`Name[Expr]' not implemented yet - try `(Name)[Expr]'"); }
|
{ error ("`Name[Expr]' not implemented yet - try `(Name)[Expr]'"); }
|
||||||
|
| VARIABLE '[' Expression ']'
|
||||||
|
{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
|
||||||
| PrimaryNoNewArray '[' Expression ']'
|
| PrimaryNoNewArray '[' Expression ']'
|
||||||
{
|
{ write_exp_elt_opcode (BINOP_SUBSCRIPT); }
|
||||||
warning("array subscripts not implemented for Java");
|
|
||||||
write_exp_elt_opcode (BINOP_SUBSCRIPT); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
PostfixExpression:
|
PostfixExpression:
|
||||||
|
@ -503,7 +505,27 @@ CastExpression:
|
||||||
{ write_exp_elt_opcode (UNOP_CAST);
|
{ write_exp_elt_opcode (UNOP_CAST);
|
||||||
write_exp_elt_type (java_array_type ($2, $3));
|
write_exp_elt_type (java_array_type ($2, $3));
|
||||||
write_exp_elt_opcode (UNOP_CAST); }
|
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
|
| '(' Name Dims ')' UnaryExpressionNotPlusMinus
|
||||||
{ write_exp_elt_opcode (UNOP_CAST);
|
{ write_exp_elt_opcode (UNOP_CAST);
|
||||||
write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
|
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 '.' */
|
dot_index++; /* Skip '.' */
|
||||||
name.ptr += dot_index;
|
name.ptr += dot_index;
|
||||||
name.length -= dot_index;
|
name.length -= dot_index;
|
||||||
|
dot_index = 0;
|
||||||
while (dot_index < name.length && name.ptr[dot_index] != '.')
|
while (dot_index < name.length && name.ptr[dot_index] != '.')
|
||||||
dot_index++;
|
dot_index++;
|
||||||
token.ptr = name.ptr;
|
token.ptr = name.ptr;
|
||||||
|
|
182
gdb/jv-lang.c
182
gdb/jv-lang.c
|
@ -143,7 +143,7 @@ add_class_symbol (type, addr)
|
||||||
obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
|
obstack_alloc (&dynamics_objfile->symbol_obstack, sizeof (struct symbol));
|
||||||
memset (sym, 0, sizeof (struct symbol));
|
memset (sym, 0, sizeof (struct symbol));
|
||||||
SYMBOL_LANGUAGE (sym) = language_java;
|
SYMBOL_LANGUAGE (sym) = language_java;
|
||||||
SYMBOL_NAME (sym) = TYPE_NAME (type);
|
SYMBOL_NAME (sym) = TYPE_TAG_NAME (type);
|
||||||
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
|
||||||
/* SYMBOL_VALUE (sym) = valu;*/
|
/* SYMBOL_VALUE (sym) = valu;*/
|
||||||
SYMBOL_TYPE (sym) = type;
|
SYMBOL_TYPE (sym) = type;
|
||||||
|
@ -177,7 +177,7 @@ java_lookup_class (name)
|
||||||
type = alloc_type (objfile);
|
type = alloc_type (objfile);
|
||||||
TYPE_CODE (type) = TYPE_CODE_STRUCT;
|
TYPE_CODE (type) = TYPE_CODE_STRUCT;
|
||||||
INIT_CPLUS_SPECIFIC (type);
|
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_FLAGS (type) |= TYPE_FLAG_STUB;
|
||||||
TYPE ? = addr;
|
TYPE ? = addr;
|
||||||
return type;
|
return type;
|
||||||
|
@ -213,7 +213,22 @@ value_ptr
|
||||||
java_class_from_object (obj_val)
|
java_class_from_object (obj_val)
|
||||||
value_ptr 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");
|
return value_struct_elt (&dtable_val, NULL, "class", NULL, "structure");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +318,7 @@ type_from_class (clas)
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOCATE_CPLUS_STRUCT_TYPE (type);
|
ALLOCATE_CPLUS_STRUCT_TYPE (type);
|
||||||
TYPE_NAME (type) = name;
|
TYPE_TAG_NAME (type) = name;
|
||||||
|
|
||||||
add_class_symtab_symbol (add_class_symbol (type, addr));
|
add_class_symtab_symbol (add_class_symbol (type, addr));
|
||||||
return java_link_class_type (type, clas);
|
return java_link_class_type (type, clas);
|
||||||
|
@ -318,7 +333,7 @@ java_link_class_type (type, clas)
|
||||||
{
|
{
|
||||||
value_ptr temp;
|
value_ptr temp;
|
||||||
char *unqualified_name;
|
char *unqualified_name;
|
||||||
char *name = TYPE_NAME (type);
|
char *name = TYPE_TAG_NAME (type);
|
||||||
int ninterfaces, nfields, nmethods;
|
int ninterfaces, nfields, nmethods;
|
||||||
int type_is_object = 0;
|
int type_is_object = 0;
|
||||||
struct fn_field *fn_fields;
|
struct fn_field *fn_fields;
|
||||||
|
@ -385,15 +400,22 @@ java_link_class_type (type, clas)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
temp = clas;
|
if (name[0] == '[' && tsuper != NULL)
|
||||||
temp = value_struct_elt (&temp, NULL, "bfsize", NULL, "structure");
|
{
|
||||||
TYPE_LENGTH (type) = value_as_long (temp);
|
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;
|
fields = NULL;
|
||||||
nfields--; /* First set up dummy "class" field. */
|
nfields--; /* First set up dummy "class" field. */
|
||||||
SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
|
SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields),
|
||||||
VALUE_ADDRESS (clas) + VALUE_OFFSET (clas));
|
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);
|
TYPE_FIELD_TYPE (type, nfields) = VALUE_TYPE (clas);
|
||||||
SET_TYPE_FIELD_PRIVATE (type, nfields);
|
SET_TYPE_FIELD_PRIVATE (type, nfields);
|
||||||
|
|
||||||
|
@ -556,7 +578,7 @@ is_object_type (type)
|
||||||
return 0;
|
return 0;
|
||||||
while (TYPE_N_BASECLASSES (ttype) > 0)
|
while (TYPE_N_BASECLASSES (ttype) > 0)
|
||||||
ttype = TYPE_BASECLASS (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)
|
if (name != NULL && strcmp (name, "java.lang.Object") == 0)
|
||||||
return 1;
|
return 1;
|
||||||
name = TYPE_NFIELDS (ttype) > 0 ? TYPE_FIELD_NAME (ttype, 0) : (char*)0;
|
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 */
|
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
|
static value_ptr
|
||||||
evaluate_subexp_java (expect_type, exp, pos, noside)
|
evaluate_subexp_java (expect_type, exp, pos, noside)
|
||||||
struct type *expect_type;
|
struct type *expect_type;
|
||||||
|
@ -683,8 +768,10 @@ evaluate_subexp_java (expect_type, exp, pos, noside)
|
||||||
{
|
{
|
||||||
int pc = *pos;
|
int pc = *pos;
|
||||||
int i;
|
int i;
|
||||||
|
char *name;
|
||||||
enum exp_opcode op = exp->elts[*pos].opcode;
|
enum exp_opcode op = exp->elts[*pos].opcode;
|
||||||
value_ptr arg1;
|
value_ptr arg1, arg2;
|
||||||
|
struct type *type;
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case UNOP_IND:
|
case UNOP_IND:
|
||||||
|
@ -700,6 +787,70 @@ evaluate_subexp_java (expect_type, exp, pos, noside)
|
||||||
if (noside == EVAL_SKIP)
|
if (noside == EVAL_SKIP)
|
||||||
goto nosideret;
|
goto nosideret;
|
||||||
return value_ind (arg1);
|
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:
|
case OP_STRING:
|
||||||
(*pos)++;
|
(*pos)++;
|
||||||
i = longest_to_int (exp->elts[pc + 1].longconst);
|
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)
|
if (noside == EVAL_SKIP)
|
||||||
goto nosideret;
|
goto nosideret;
|
||||||
return java_value_string (&exp->elts[pc + 2].string, i);
|
return java_value_string (&exp->elts[pc + 2].string, i);
|
||||||
|
|
||||||
case STRUCTOP_STRUCT:
|
case STRUCTOP_STRUCT:
|
||||||
arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
|
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)
|
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT)
|
||||||
arg1 = value_addr (arg1);
|
arg1 = value_addr (arg1);
|
||||||
return arg1;
|
return arg1;
|
||||||
|
@ -791,7 +943,7 @@ const struct language_defn java_language_defn = {
|
||||||
java_parse,
|
java_parse,
|
||||||
java_error,
|
java_error,
|
||||||
evaluate_subexp_java,
|
evaluate_subexp_java,
|
||||||
c_printchar, /* Print a character constant */
|
java_printchar, /* Print a character constant */
|
||||||
c_printstr, /* Function to print string constant */
|
c_printstr, /* Function to print string constant */
|
||||||
java_create_fundamental_type, /* Create fundamental type in this language */
|
java_create_fundamental_type, /* Create fundamental type in this language */
|
||||||
java_print_type, /* Print a type using appropriate syntax */
|
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 */
|
{"%ld", "", "d", ""}, /* Decimal format info */
|
||||||
{"0x%lx", "0x", "x", ""}, /* Hex format info */
|
{"0x%lx", "0x", "x", ""}, /* Hex format info */
|
||||||
java_op_print_tab, /* expression operators for printing */
|
java_op_print_tab, /* expression operators for printing */
|
||||||
1, /* c-style arrays */
|
0, /* not c-style arrays */
|
||||||
0, /* String lower bound */
|
0, /* String lower bound */
|
||||||
&builtin_type_char, /* Type of string elements */
|
&builtin_type_char, /* Type of string elements */
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
_initialize_jave_language ()
|
_initialize_java_language ()
|
||||||
{
|
{
|
||||||
|
|
||||||
java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
|
java_int_type = init_type (TYPE_CODE_INT, 4, 0, "int", NULL);
|
||||||
|
|
|
@ -56,10 +56,95 @@ java_value_print (val, stream, format, pretty)
|
||||||
if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_TAG_NAME (type) != NULL
|
if (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_TAG_NAME (type) != NULL
|
||||||
&& TYPE_TAG_NAME (type)[0] == '[')
|
&& TYPE_TAG_NAME (type)[0] == '[')
|
||||||
{
|
{
|
||||||
value_ptr len = value_at (java_int_type, address + JAVA_OBJECT_SIZE, 0);
|
char buf4[4];
|
||||||
long length = value_as_long (len);
|
long length;
|
||||||
fprintf_filtered (stream, "{");
|
unsigned int things_printed = 0;
|
||||||
fprintf_filtered (stream, "length = %ld", length);
|
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, "}");
|
fprintf_filtered (stream, "}");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -68,6 +153,206 @@ java_value_print (val, stream, format, pretty)
|
||||||
stream, format, 1, 0, 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
|
int
|
||||||
java_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
java_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||||
pretty)
|
pretty)
|
||||||
|
@ -130,6 +415,20 @@ java_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
|
||||||
}
|
}
|
||||||
return i;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
return c_val_print (type, valaddr, address, stream, format,
|
return c_val_print (type, valaddr, address, stream, format,
|
||||||
|
|
|
@ -59,9 +59,6 @@ free_funcalls PARAMS ((void));
|
||||||
static void
|
static void
|
||||||
prefixify_expression PARAMS ((struct expression *));
|
prefixify_expression PARAMS ((struct expression *));
|
||||||
|
|
||||||
static int
|
|
||||||
length_of_subexp PARAMS ((struct expression *, int));
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prefixify_subexp PARAMS ((struct expression *, struct expression *, int, int));
|
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
|
/* Return the number of exp_elements in the subexpression of EXPR
|
||||||
whose last exp_element is at index ENDPOS - 1 in EXPR. */
|
whose last exp_element is at index ENDPOS - 1 in EXPR. */
|
||||||
|
|
||||||
static int
|
int
|
||||||
length_of_subexp (expr, endpos)
|
length_of_subexp (expr, endpos)
|
||||||
register struct expression *expr;
|
register struct expression *expr;
|
||||||
register int endpos;
|
register int endpos;
|
||||||
|
|
|
@ -133,6 +133,9 @@ pop_type PARAMS ((void));
|
||||||
extern int
|
extern int
|
||||||
pop_type_int PARAMS ((void));
|
pop_type_int PARAMS ((void));
|
||||||
|
|
||||||
|
extern int
|
||||||
|
length_of_subexp PARAMS ((struct expression *, int));
|
||||||
|
|
||||||
extern struct type *follow_types PARAMS ((struct type *));
|
extern struct type *follow_types PARAMS ((struct type *));
|
||||||
|
|
||||||
/* During parsing of a C expression, the pointer to the next character
|
/* During parsing of a C expression, the pointer to the next character
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue