This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA]: Java Inferior Call Take 2
- From: Jeff Johnston <jjohnstn at redhat dot com>
- To: Daniel Jacobowitz <drow at false dot org>
- Cc: Andrew Haley <aph at redhat dot com>, gdb-patches at sources dot redhat dot com
- Date: Tue, 06 Jul 2004 17:47:09 -0400
- Subject: Re: [RFA]: Java Inferior Call Take 2
- References: <40A9264C.4060404@redhat.com> <20040617030603.GC23443@nevyn.them.org> <40D20494.2020608@redhat.com> <20040619235857.GA18759@nevyn.them.org> <16598.64375.217285.743094@cuddles.cambridge.redhat.com> <16601.25623.949217.642524@cuddles.cambridge.redhat.com> <20040623134742.GA24612@nevyn.them.org> <40D9FC3B.3030700@redhat.com> <20040623230138.GA6426@nevyn.them.org>
Daniel Jacobowitz wrote:
On Wed, Jun 23, 2004 at 05:55:07PM -0400, Jeff Johnston wrote:
Daniel Jacobowitz wrote:
On Wed, Jun 23, 2004 at 12:05:59PM +0100, Andrew Haley wrote:
This patch is now in mainline. Is there anything else you need?
Yes. Two sets of questions left, one for Jeff and one [plus a little
bit] for you...
Jeff, one test still fails: calling addprint. I think this is mostly a
GDB problem rather than GCC. Before starting the program I see this:
Let me take a look at it. It is not failing in my all-patches-applied
build. Perhaps in splitting the patches up, I screwed up and missed
something.
Thanks.
Ok, I figured out what piece I left out and have remade the patch. I can't
remember where we are on this regarding the workaround for gcc debug-info, but
at least you will be able to run the test with the full functionality now.
Please let me know what is needed next as I want to move this forward.
-- Jeff J.
- Should we suppress jvclass and <clinit> the way we do for C++
artificial methods?
Perhaps remove <clinit>, but jvclass() is the constructor. There could be
multiple constructors and as an end-user, I would want to see the various
prototypes. I can't speak for what C++ does.
In C++, the debug information marks whether a constructor was written
by the user (i.e. the type really contains a constructor) or by the
compiler (i.e. implicit). I imagine Java's debug information has the
same thing. For minimum confusion, we choose not to print the
artificial methods in C++ types; I think we should do the same for
Java.
(This shouldn't affect breakpointing it for users who know the
constructor exists.)
- Why did printing of the type change? There's only one definition
of jvclass in the debug info, and it's marked Java.
There are checks in the code based on current language. The current
language does not start as java. If you manually change it via set
language java, you will see the same results before and after.
Bleeeeeeech. Thanks for explaining; definitely not your problem, but
definitely a bug. If we're printing a type we ought to be using the
type's language.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.151
diff -u -p -r1.151 dwarf2read.c
--- dwarf2read.c 7 May 2004 14:29:33 -0000 1.151
+++ dwarf2read.c 6 Jul 2004 21:42:45 -0000
@@ -788,7 +788,8 @@ static void read_type_die (struct die_in
static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
-static char *typename_concat (const char *prefix, const char *suffix);
+static char *typename_concat (const char *prefix, const char *suffix,
+ struct dwarf2_cu *);
static void read_typedef (struct die_info *, struct dwarf2_cu *);
@@ -1502,7 +1503,8 @@ scan_partial_symbols (struct partial_die
/* Functions used to compute the fully scoped name of a partial DIE.
Normally, this is simple. For C++, the parent DIE's fully scoped
- name is concatenated with "::" and the partial DIE's name.
+ name is concatenated with "::" and the partial DIE's name. For
+ Java, the same thing occurs except that "." is used instead of "::".
Enumerators are an exception; they use the scope of their parent
enumeration type, i.e. the name of the enumeration type is not
prepended to the enumerator.
@@ -1558,7 +1560,7 @@ partial_die_parent_scope (struct partial
parent->scope = parent->name;
else
parent->scope = obconcat (&cu->comp_unit_obstack, grandparent_scope,
- "::", parent->name);
+ cu->language == language_java ? "." : "::", parent->name);
}
else if (parent->tag == DW_TAG_enumeration_type)
/* Enumerators should not get the name of the enumeration as a prefix. */
@@ -1590,7 +1592,11 @@ partial_die_full_name (struct partial_di
if (parent_scope == NULL)
return NULL;
else
- return concat (parent_scope, "::", pdi->name, NULL);
+ {
+ if (cu->language == language_java)
+ return concat (parent_scope, ".", pdi->name, NULL);
+ return concat (parent_scope, "::", pdi->name, NULL);
+ }
}
static void
@@ -1708,14 +1714,16 @@ add_partial_symbol (struct partial_die_i
return;
add_psymbol_to_list (actual_name, strlen (actual_name),
STRUCT_DOMAIN, LOC_TYPEDEF,
- cu->language == language_cplus
+ (cu->language == language_cplus
+ || cu->language == language_java)
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
- /* For C++, these implicitly act as typedefs as well. */
+ /* For C++ and Java, these implicitly act as typedefs as well. */
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_TYPEDEF,
&objfile->global_psymbols,
@@ -1725,7 +1733,8 @@ add_partial_symbol (struct partial_die_i
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
VAR_DOMAIN, LOC_CONST,
- cu->language == language_cplus
+ (cu->language == language_cplus
+ || cu->language == language_java)
? &objfile->global_psymbols
: &objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, objfile);
@@ -1805,7 +1814,8 @@ static void
guess_structure_name (struct partial_die_info *struct_pdi,
struct dwarf2_cu *cu)
{
- if (cu->language == language_cplus
+ if ((cu->language == language_cplus
+ || cu->language == language_java)
&& cu->has_namespace_info == 0
&& struct_pdi->has_children)
{
@@ -2460,7 +2470,8 @@ read_func_scope (struct die_info *die, s
if (name == NULL || !dwarf2_get_pc_bounds (die, &lowpc, &highpc, cu))
return;
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
struct die_info *spec_die = die_specification (die, cu);
@@ -3101,7 +3112,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;
@@ -3292,7 +3325,8 @@ read_structure_type (struct die_info *di
attr = dwarf2_attr (die, DW_AT_name, cu);
if (attr && DW_STRING (attr))
{
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
char *new_prefix = determine_class_name (die, cu);
TYPE_TAG_NAME (type) = obsavestring (new_prefix,
@@ -3398,6 +3432,9 @@ read_structure_type (struct die_info *di
{
static const char vptr_name[] =
{'_', 'v', 'p', 't', 'r', '\0'};
+ static const char vtable_name[] =
+ {'v', 't', 'a', 'b', 'l', 'e', '\0'};
+
int i;
/* Our own class provides vtbl ptr. */
@@ -3407,10 +3444,18 @@ read_structure_type (struct die_info *di
{
char *fieldname = TYPE_FIELD_NAME (t, i);
- if ((strncmp (fieldname, vptr_name,
- strlen (vptr_name) - 1)
- == 0)
- && is_cplus_marker (fieldname[strlen (vptr_name)]))
+ if (cu->language == language_java
+ && (strncmp (fieldname, vtable_name,
+ strlen (vtable_name) - 1)
+ == 0))
+ {
+ TYPE_VPTR_FIELDNO (type) = i;
+ break;
+ }
+ else if ((strncmp (fieldname, vptr_name,
+ strlen (vptr_name) - 1)
+ == 0)
+ && is_cplus_marker (fieldname[strlen (vptr_name)]))
{
TYPE_VPTR_FIELDNO (type) = i;
break;
@@ -3502,7 +3547,9 @@ read_enumeration_type (struct die_info *
TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
processing_current_prefix[0] == '\0'
- ? "" : "::",
+ ? "" :
+ cu->language == language_java
+ ? "." : "::",
name);
}
else
@@ -3527,7 +3574,7 @@ read_enumeration_type (struct die_info *
}
/* Determine the name of the type represented by DIE, which should be
- a named C++ compound type. Return the name in question; the caller
+ a named C++ or Java compound type. Return the name in question; the caller
is responsible for xfree()'ing it. */
static char *
@@ -3573,7 +3620,8 @@ determine_class_name (struct die_info *d
{
const char *name = dwarf2_name (die, cu);
new_prefix = typename_concat (processing_current_prefix,
- name ? name : "<<anonymous>>");
+ name ? name : "<<anonymous>>",
+ cu);
}
if (back_to != NULL)
@@ -3810,7 +3858,10 @@ read_namespace (struct die_info *die, st
char *temp_name = alloca (strlen (previous_prefix)
+ 2 + strlen(name) + 1);
strcpy (temp_name, previous_prefix);
- strcat (temp_name, "::");
+ if (cu->language == language_java)
+ strcat (temp_name, ".");
+ else
+ strcat (temp_name, "::");
strcat (temp_name, name);
processing_current_prefix = temp_name;
@@ -4099,10 +4150,11 @@ read_subroutine_type (struct die_info *d
type = die_type (die, cu);
ftype = lookup_function_type (type);
- /* All functions in C++ have prototypes. */
+ /* All functions in C++ and Java have prototypes. */
attr = dwarf2_attr (die, DW_AT_prototyped, cu);
if ((attr && (DW_UNSND (attr) != 0))
- || cu->language == language_cplus)
+ || cu->language == language_cplus
+ || cu->language == language_java)
TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
if (die->child != NULL)
@@ -4753,7 +4805,8 @@ load_partial_dies (bfd *abfd, char *info
else if (building_psymtab)
add_psymbol_to_list (part_die->name, strlen (part_die->name),
VAR_DOMAIN, LOC_CONST,
- cu->language == language_cplus
+ (cu->language == language_cplus
+ || cu->language == language_java)
? &cu->objfile->global_psymbols
: &cu->objfile->static_psymbols,
0, (CORE_ADDR) 0, cu->language, cu->objfile);
@@ -6357,7 +6410,8 @@ new_symbol (struct die_info *die, struct
read_structure_type, and the correct name is saved in
the type. */
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
struct type *type = SYMBOL_TYPE (sym);
@@ -6374,7 +6428,7 @@ new_symbol (struct die_info *die, struct
}
{
- /* NOTE: carlton/2003-11-10: C++ class symbols shouldn't
+ /* NOTE: carlton/2003-11-10: C++ and Java class symbols shouldn't
really ever be static objects: otherwise, if you try
to, say, break of a class's method and you're in a file
which doesn't mention that class, it won't work unless
@@ -6385,15 +6439,17 @@ new_symbol (struct die_info *die, struct
struct pending **list_to_add;
list_to_add = (cu->list_in_scope == &file_symbols
- && cu->language == language_cplus
+ && (cu->language == language_cplus
+ || cu->language == language_java)
? &global_symbols : cu->list_in_scope);
add_symbol_to_list (sym, list_to_add);
- /* The semantics of C++ state that "struct foo { ... }" also
+ /* The semantics of C++ and Java state that "struct foo { ... }" also
defines a typedef for "foo". Synthesize a typedef symbol so
that "ptype foo" works as expected. */
- if (cu->language == language_cplus)
+ if (cu->language == language_cplus
+ || cu->language == language_java)
{
struct symbol *typedef_sym = (struct symbol *)
obstack_alloc (&objfile->objfile_obstack,
@@ -6415,7 +6471,8 @@ new_symbol (struct die_info *die, struct
{
SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
- "::",
+ cu->language == language_java
+ ? "." : "::",
name);
}
SYMBOL_CLASS (sym) = LOC_TYPEDEF;
@@ -6434,7 +6491,8 @@ new_symbol (struct die_info *die, struct
{
SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
processing_current_prefix,
- "::",
+ cu->language == language_java
+ ? "." : "::",
name);
}
attr = dwarf2_attr (die, DW_AT_const_value, cu);
@@ -6449,7 +6507,8 @@ new_symbol (struct die_info *die, struct
struct pending **list_to_add;
list_to_add = (cu->list_in_scope == &file_symbols
- && cu->language == language_cplus
+ && (cu->language == language_cplus
+ || cu->language == language_java)
? &global_symbols : cu->list_in_scope);
add_symbol_to_list (sym, list_to_add);
@@ -6758,7 +6817,8 @@ determine_prefix (struct die_info *die,
{
struct die_info *parent;
- if (cu->language != language_cplus)
+ if (cu->language != language_cplus
+ && cu->language != language_java)
return NULL;
parent = die->parent;
@@ -6784,7 +6844,8 @@ determine_prefix (struct die_info *die,
char *parent_prefix = determine_prefix (parent, cu);
char *retval = typename_concat (parent_prefix,
namespace_name (parent, &dummy,
- cu));
+ cu),
+ cu);
xfree (parent_prefix);
return retval;
}
@@ -6818,11 +6879,11 @@ determine_prefix (struct die_info *die,
}
/* Return a newly-allocated string formed by concatenating PREFIX,
- "::", and SUFFIX, except that if PREFIX is NULL or the empty
+ "::" or ".", and SUFFIX, except that if PREFIX is NULL or the empty
string, just return a copy of SUFFIX. */
static char *
-typename_concat (const char *prefix, const char *suffix)
+typename_concat (const char *prefix, const char *suffix, struct dwarf2_cu *cu)
{
if (prefix == NULL || prefix[0] == '\0')
return xstrdup (suffix);
@@ -6831,7 +6892,10 @@ typename_concat (const char *prefix, con
char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
strcpy (retval, prefix);
- strcat (retval, "::");
+ if (cu->language == language_java)
+ strcat (retval, ".");
+ else
+ strcat (retval, "::");
strcat (retval, suffix);
return retval;
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 6 Jul 2004 21:42:45 -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.129
diff -u -p -r1.129 symtab.c
--- symtab.c 8 Apr 2004 21:18:13 -0000 1.129
+++ symtab.c 6 Jul 2004 21:42:45 -0000
@@ -932,7 +932,7 @@ 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)
{
@@ -944,6 +944,17 @@ lookup_symbol (const char *name, const s
needtofreename = 1;
}
}
+ else if (current_language->la_language == language_java)
+ {
+ demangled_name = cplus_demangle (name,
+ DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
+ if (demangled_name)
+ {
+ mangled_name = name;
+ modified_name = demangled_name;
+ needtofreename = 1;
+ }
+ }
if (case_sensitivity == case_sensitive_off)
{
Index: valarith.c
===================================================================
RCS file: /cvs/src/src/gdb/valarith.c,v
retrieving revision 1.22
diff -u -p -r1.22 valarith.c
--- valarith.c 1 Apr 2004 12:08:30 -0000 1.22
+++ valarith.c 6 Jul 2004 21:42:49 -0000
@@ -202,7 +202,10 @@ value_subscript (struct value *array, st
LONGEST index = value_as_long (idx);
if (index >= lowerbound && index <= upperbound)
return value_subscripted_rvalue (array, idx, lowerbound);
- warning ("array or string index out of range");
+ /* Emit warning unless we have an array of unknown size.
+ An array of unknown size has lowerbound 0 and upperbound -1. */
+ if (upperbound > -1)
+ warning ("array or string index out of range");
/* fall doing C stuff */
c_style = 1;
}