Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.141 diff -u -p -r1.141 dwarf2read.c --- dwarf2read.c 16 Mar 2004 22:43:15 -0000 1.141 +++ dwarf2read.c 23 Mar 2004 18:31:07 -0000 @@ -2986,7 +2986,29 @@ dwarf2_add_member_fn (struct field_info /* Get name of member function. */ attr = dwarf2_attr (die, DW_AT_name, cu); if (attr && DW_STRING (attr)) - fieldname = DW_STRING (attr); + { + /* Note: C++ and Java currently differ in how the member function + name is stored in the debug info. For Java, the member name is + fully qualified with prototype while C++ just has the member + name. To get the Java member name, we strip off any dot qualifiers + and remove the trailing prototype. */ + char *dot_index; + char *lparen; + fieldname = DW_STRING (attr); + if (cu->language == language_java) + { + dot_index = strchr (fieldname, '.'); + while (dot_index) + { + fieldname = dot_index + 1; + dot_index = strchr (fieldname, '.'); + } + lparen = strchr (fieldname + 1, '('); + if (lparen) + fieldname = obsavestring (fieldname, lparen - fieldname, + &objfile->objfile_obstack); + } + } else return; Index: gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.52 diff -u -p -r1.52 gdbtypes.h --- gdbtypes.h 7 Feb 2004 16:57:55 -0000 1.52 +++ gdbtypes.h 23 Mar 2004 18:31:07 -0000 @@ -905,6 +905,7 @@ extern void allocate_cplus_struct_type ( #define TYPE_FN_FIELD_INLINED(thisfn, n) ((thisfn)[n].is_inlined) #define TYPE_FN_FIELD_FCONTEXT(thisfn, n) ((thisfn)[n].fcontext) #define TYPE_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset-2) +#define TYPE_JAVA_FN_FIELD_VOFFSET(thisfn, n) ((thisfn)[n].voffset) #define TYPE_FN_FIELD_VIRTUAL_P(thisfn, n) ((thisfn)[n].voffset > 1) #define TYPE_FN_FIELD_STATIC_P(thisfn, n) ((thisfn)[n].voffset == VOFFSET_STATIC) Index: gnu-v3-abi.c =================================================================== RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v retrieving revision 1.21 diff -u -p -r1.21 gnu-v3-abi.c --- gnu-v3-abi.c 15 Mar 2004 20:38:08 -0000 1.21 +++ gnu-v3-abi.c 23 Mar 2004 18:31:07 -0000 @@ -27,6 +27,7 @@ #include "demangle.h" #include "gdb_assert.h" #include "gdb_string.h" +#include "language.h" static struct cp_abi_ops gnu_v3_abi_ops; @@ -95,7 +96,7 @@ enum { /* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable', described above, laid out appropriately for ARCH. - We use this function as the gdbarch per-architecture data + We use this function as a gdbarch per-architecture data initialization function. We assume that the gdbarch framework calls the per-architecture data initialization functions after it sets current_gdbarch to the new architecture. */ @@ -170,6 +171,26 @@ build_gdb_vtable_type (struct gdbarch *a return t; } +/* For Java, the vtable is different than C++. It is simply an + array of function pointers. */ +static struct gdbarch_data *java_vtable_type_gdbarch_data; + +/* Return a GDB type representing a Java vtable. + We use this function in the gdbarch per-architecture data + initialization function. We assume that the gdbarch framework + calls the per-architecture data initialization functions after it + sets current_gdbarch to the new architecture. */ +static void * +build_gdb_java_vtable_type (struct gdbarch *arch) +{ + struct type *t; + struct type *ptr_to_void_fn_type + = lookup_pointer_type (lookup_function_type (builtin_type_void)); + + t = create_array_type (0, ptr_to_void_fn_type, + create_range_type (0, builtin_type_int, 0, -1)); + return t; +} /* Return the offset from the start of the imaginary `struct gdb_gnu_v3_abi_vtable' object to the vtable's "address point" @@ -294,49 +315,81 @@ gnuv3_virtual_fn_field (struct value **v if (TYPE_CODE (value_type) != TYPE_CODE_CLASS) error ("Only classes can have virtual functions."); - /* Find the base class that defines this virtual function. */ - vfn_base = TYPE_FN_FIELD_FCONTEXT (f, j); - if (! vfn_base) - /* In programs compiled with G++ version 1, the debug info doesn't - say which base class defined the virtual function. We'll guess - it's the same base class that has our vtable; this is wrong for - multiple inheritance, but it's better than nothing. */ - vfn_base = TYPE_VPTR_BASETYPE (type); - - /* This type may have been defined before its virtual function table - was. If so, fill in the virtual function table entry for the - type now. */ - if (TYPE_VPTR_FIELDNO (vfn_base) < 0) - fill_in_vptr_fieldno (vfn_base); - if (TYPE_VPTR_FIELDNO (vfn_base) < 0) - error ("Could not find virtual table pointer for class \"%s\".", - TYPE_TAG_NAME (vfn_base) ? TYPE_TAG_NAME (vfn_base) : ""); - - /* Now that we know which base class is defining our virtual - function, cast our value to that baseclass. This takes care of - any necessary `this' adjustments. */ - if (vfn_base != value_type) - value = value_cast (vfn_base, value); - - /* Now value is an object of the appropriate base type. Fetch its - virtual table. */ - /* It might be possible to do this cast at the same time as the above. - Does multiple inheritance affect this? - Can this even trigger, or is TYPE_VPTR_BASETYPE idempotent? - */ - if (TYPE_VPTR_BASETYPE (vfn_base) != vfn_base) - value = value_cast (TYPE_VPTR_BASETYPE (vfn_base), value); - vtable_address - = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (vfn_base))); - - vtable = value_at_lazy (vtable_type, - vtable_address - vtable_address_point_offset (), - VALUE_BFD_SECTION (value)); - - /* Fetch the appropriate function pointer from the vtable. */ - vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions), - value_from_longest (builtin_type_int, - TYPE_FN_FIELD_VOFFSET (f, j))); + /* C++ and java have different vtable mechanisms. Check the language + first. */ + if (current_language->la_language == language_java) + { + /* For Java, the vtable address is the first word of the class object. + It is simply an array of function pointers. */ + struct value *vtable_ptr; + struct type *ptr_to_void_fn_type + = lookup_pointer_type (lookup_function_type (builtin_type_void)); + struct type *ptr_to_void_type + = lookup_pointer_type (builtin_type_void); + struct type *java_vtable_type + = gdbarch_data (current_gdbarch, java_vtable_type_gdbarch_data); + + vtable_ptr = value_at_lazy (ptr_to_void_type, VALUE_ADDRESS (value), + VALUE_BFD_SECTION (value)); + vtable_address = value_as_address (vtable_ptr); + vtable = value_at_lazy (java_vtable_type, + vtable_address, + VALUE_BFD_SECTION (value)); + /* Fetch the appropriate function pointer from the vtable. + Note that the voffset should not be adjusted. Thus, we cannot + use the TYPE_FN_FIELD_OFFSET macro. */ + vfn = value_subscript_1 (vtable, + value_from_longest (builtin_type_int, + TYPE_JAVA_FN_FIELD_VOFFSET (f, j)), + 1); + } + else /* C++ */ + { + /* Find the base class that defines this virtual function. */ + vfn_base = TYPE_FN_FIELD_FCONTEXT (f, j); + if (! vfn_base) + /* In programs compiled with G++ version 1, the debug info doesn't + say which base class defined the virtual function. We'll guess + it's the same base class that has our vtable; this is wrong for + multiple inheritance, but it's better than nothing. */ + vfn_base = TYPE_VPTR_BASETYPE (type); + + /* This type may have been defined before its virtual function table + was. If so, fill in the virtual function table entry for the + type now. */ + if (TYPE_VPTR_FIELDNO (vfn_base) < 0) + fill_in_vptr_fieldno (vfn_base); + if (TYPE_VPTR_FIELDNO (vfn_base) < 0) + error ("Could not find virtual table pointer for class \"%s\".", + TYPE_TAG_NAME (vfn_base) ? TYPE_TAG_NAME (vfn_base) : ""); + + /* Now that we know which base class is defining our virtual + function, cast our value to that baseclass. This takes care of + any necessary `this' adjustments. */ + if (vfn_base != value_type) + value = value_cast (vfn_base, value); + + /* Now value is an object of the appropriate base type. Fetch its + virtual table. */ + /* It might be possible to do this cast at the same time as the above. + Does multiple inheritance affect this? + Can this even trigger, or is TYPE_VPTR_BASETYPE idempotent? + */ + if (TYPE_VPTR_BASETYPE (vfn_base) != vfn_base) + value = value_cast (TYPE_VPTR_BASETYPE (vfn_base), value); + vtable_address + = value_as_address (value_field (value, TYPE_VPTR_FIELDNO (vfn_base))); + + vtable = value_at_lazy (vtable_type, + vtable_address - vtable_address_point_offset (), + VALUE_BFD_SECTION (value)); + + /* Fetch the appropriate function pointer from the vtable. */ + vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions), + value_from_longest (builtin_type_int, + TYPE_FN_FIELD_VOFFSET (f, j))); + + } /* Cast the function pointer to the appropriate type. */ vfn = value_cast (lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)), @@ -423,6 +476,8 @@ static void init_gnuv3_ops (void) { vtable_type_gdbarch_data = gdbarch_data_register_post_init (build_gdb_vtable_type); + + java_vtable_type_gdbarch_data = gdbarch_data_register_post_init (build_gdb_java_vtable_type); gnu_v3_abi_ops.shortname = "gnu-v3"; gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI"; Index: jv-exp.y =================================================================== RCS file: /cvs/src/src/gdb/jv-exp.y,v retrieving revision 1.18 diff -u -p -r1.18 jv-exp.y --- jv-exp.y 23 Nov 2003 20:41:17 -0000 1.18 +++ jv-exp.y 23 Mar 2004 18:31:07 -0000 @@ -446,13 +446,22 @@ FieldAccess: /*| SUPER '.' SimpleName { FIXME } */ ; +FuncStart: + Name '(' + { push_expression_name ($1); } +; + MethodInvocation: - Name '(' ArgumentList_opt ')' - { error (_("Method invocation not implemented")); } + FuncStart + { start_arglist(); } + ArgumentList_opt ')' + { write_exp_elt_opcode (OP_FUNCALL); + write_exp_elt_longcst ((LONGEST) end_arglist ()); + write_exp_elt_opcode (OP_FUNCALL); } | Primary '.' SimpleName '(' ArgumentList_opt ')' - { error (_("Method invocation not implemented")); } + { error (_("Form of method invocation not implemented")); } | SUPER '.' SimpleName '(' ArgumentList_opt ')' - { error (_("Method invocation not implemented")); } + { error (_("Form of method invocation not implemented")); } ; ArrayAccess: Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.128 diff -u -p -r1.128 symtab.c --- symtab.c 19 Feb 2004 19:01:26 -0000 1.128 +++ symtab.c 23 Mar 2004 18:31:08 -0000 @@ -41,6 +41,7 @@ #include "source.h" #include "filenames.h" /* for FILENAME_CMP */ #include "objc-lang.h" +#include "jv-lang.h" #include "hashtab.h" @@ -932,11 +933,13 @@ lookup_symbol (const char *name, const s modified_name = name; - /* If we are using C++ language, demangle the name before doing a lookup, so + /* If we are using C++ or Java, demangle the name before doing a lookup, so we can always binary search. */ - if (current_language->la_language == language_cplus) + if (current_language->la_language == language_cplus || + current_language->la_language == language_java) { - demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); + demangled_name = language_demangle (current_language, name, + DMGL_ANSI | DMGL_PARAMS); if (demangled_name) { mangled_name = name; Index: valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.21 diff -u -p -r1.21 valarith.c --- valarith.c 14 Sep 2003 16:32:14 -0000 1.21 +++ valarith.c 23 Mar 2004 18:31:08 -0000 @@ -171,17 +171,24 @@ an integer nor a pointer of the same typ return value_binop (arg1, arg2, BINOP_SUB); } +/* Return the value of ARRAY[IDX]. */ + +struct value * +value_subscript (struct value *array, struct value *idx) +{ + return value_subscript_1 (array, idx, current_language->c_style_arrays); +} + /* Return the value of ARRAY[IDX]. + If C_STYLE is true, do not perform range checking. See comments in value_coerce_array() for rationale for reason for doing lower bounds adjustment here rather than there. FIXME: Perhaps we should validate that the index is valid and if - verbosity is set, warn about invalid indices (but still use them). */ - + verbosity is set, warn about invalid indices (but still use them). */ struct value * -value_subscript (struct value *array, struct value *idx) +value_subscript_1 (struct value *array, struct value *idx, int c_style) { struct value *bound; - int c_style = current_language->c_style_arrays; struct type *tarray; COERCE_REF (array); Index: value.h =================================================================== RCS file: /cvs/src/src/gdb/value.h,v retrieving revision 1.54 diff -u -p -r1.54 value.h --- value.h 23 Oct 2003 22:36:14 -0000 1.54 +++ value.h 23 Mar 2004 18:31:08 -0000 @@ -416,6 +416,9 @@ extern struct value *value_repeat (struc extern struct value *value_subscript (struct value *array, struct value *idx); +extern struct value *value_subscript_1 (struct value *array, + struct value *idx, int c_style); + extern struct value *register_value_being_returned (struct type *valtype, struct regcache *retbuf);