This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA]: Java Inferior Call Take 2


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;
 	}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]