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 3


Jim Blandy wrote:
Jeff Johnston <jjohnstn@redhat.com> writes:

Here is the revised patch.

2004-08-24 Jeff Johnston <jjohnstn@redhat.com>

    * dwarf2read.c (typename_concat): Change prototype to accept dwarf2_cu
    struct pointer as argument.  Change function to use new argument to
    determine language.  If language is Java, use "." as separator,
    otherwise, use "::".
    (partial_die_parent_scope): Change comment to include java.  Check
    language to determine if Java "." or C++ "::" separator should be used.
    (add_partial_symbol): Enhance tests for C++ to also test for Java.
    (guess_structure_name): Ditto.
    (read_subroutine_type): Ditto.
    (new_symbol): Ditto.
    (read_structure_type): Add Java vtable support.
    (read_namespace): Add Java support.
    * jv-exp.y (FuncStart): New pattern.
    (MethodInvocation): Add support for simple function calls.  Change
    warning message for other forms of inferior call currently not
    supported.
    * valarith.c (value_subscript): Treat an array with upper-bound
    of -1 as unknown size.


For the dwarf2read.c part of this patch:

There are a lot of places where we're selecting the name component
separator based on the language; I'd like compound name construction
abstracted out into its own function.  Two possible approaches:

- typename_concat could take, in addition to the cu, a pointer to an
  obstack.  When the obstack pointer is null, typename_concat would
  use xmalloc as it does now; otherwise it'd use obconcat.

- If you don't like overloading the behavior of typename_concat that
  way, you could define a new function altogether that takes a prefix,
  a name, a cu, and an obstack, and returns the name with the prefix
  properly attached, allocated in the obstack.

But once there's a function that does this, I think all the 'if java
then "." else "::"' can be neatened up quite a bit.


In this change:


-	    /* The semantics of C++ state that "struct foo { ... }" also
+	    /* The semantics of C++ and Java state that "struct foo { ... }" also

'struct foo { ... }' isn't valid Java; go ahead and say what you mean:

    /* The semantics of C++ state that "struct foo { ... }" also
       defines a typedef for "foo".  A Java class declaration also
       defines a typedef for the class.  Synthesize a typedef symbol
       so that "ptype foo" works as expected.  */


The new comment for typename_concat should explain what its 'cu' argument is used for.

The vtable pointer recognition code is kind of weird.  The use of
'strlen (vptr_name) - 1' looks like a bug: don't we want to include
that last character in the comparison?  I've committed the patch
below; could you adapt your patch to apply on top of that?


Ok. How about the following revised patch which modifies typename_concat as suggested above plus incorporates your other comments?


2004-09-09 Jeff Johnston <jjohnstn@redhat.com>

      * dwarf2read.c (typename_concat): Change prototype to accept dwarf2_cu
      struct pointer and obstack pointer as arguments.  Change function to
      pick separator based on language and whether prefix/suffix is NULL or
      empty.  Also support concatenating using the obstack argument.
      (partial_die_parent_scope): Change comment to include java.  Check
      language to determine if Java "." or C++ "::" separator should be used.
      (add_partial_symbol): Enhance tests for C++ to also test for Java.
      (guess_structure_name): Ditto.
     (read_subroutine_type): Ditto.
      (new_symbol): Ditto.
      (read_structure_type): Add Java vtable support.
      (read_namespace): Add Java support.
      * jv-exp.y (FuncStart): New pattern.
      (MethodInvocation): Add support for simple function calls.  Change
      warning message for other forms of inferior call currently not
      supported.
      * valarith.c (value_subscript): Treat an array with upper-bound
      of -1 as unknown size.

Ok to commit?

-- Jeff J.



Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.160
diff -u -p -r1.160 dwarf2read.c
--- dwarf2read.c	1 Sep 2004 04:19:21 -0000	1.160
+++ dwarf2read.c	9 Sep 2004 23:36:39 -0000
@@ -791,7 +791,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 (struct obstack *, const char *prefix, const char *suffix,
+			      struct dwarf2_cu *);
 
 static void read_typedef (struct die_info *, struct dwarf2_cu *);
 
@@ -1511,7 +1512,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.
@@ -1566,8 +1568,8 @@ partial_die_parent_scope (struct partial
       if (grandparent_scope == NULL)
 	parent->scope = parent->name;
       else
-	parent->scope = obconcat (&cu->comp_unit_obstack, grandparent_scope,
-				  "::", parent->name);
+	parent->scope = typename_concat (&cu->comp_unit_obstack, grandparent_scope,
+					 parent->name, cu);
     }
   else if (parent->tag == DW_TAG_enumeration_type)
     /* Enumerators should not get the name of the enumeration as a prefix.  */
@@ -1599,7 +1601,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
@@ -1717,14 +1723,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,
@@ -1734,7 +1742,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);
@@ -1814,7 +1823,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)
     {
@@ -2474,7 +2484,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);
 
@@ -3272,10 +3283,13 @@ static int
 is_vtable_name (const char *name, struct dwarf2_cu *cu)
 {
   static const char vptr[] = "_vptr";
+  static const char vtable[] = "vtable";
 
-  /* C++ and some implementations of Java use this name.  */
-  if (strncmp (name, vptr, sizeof (vptr) - 1) == 0
-      && is_cplus_marker (name[sizeof (vptr) - 1]))
+  /* Look for the C++ and Java forms of the vtable.  */
+  if ((cu->language == language_java
+       && strncmp (name, vtable, sizeof (vtable) - 1) == 0)
+       || (strncmp (name, vptr, sizeof (vptr) - 1) == 0
+       && is_cplus_marker (name[sizeof (vptr) - 1])))
     return 1;
 
   return 0;
@@ -3316,7 +3330,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,
@@ -3518,11 +3533,9 @@ read_enumeration_type (struct die_info *
 
       if (processing_has_namespace_info)
 	{
-	  TYPE_TAG_NAME (type) = obconcat (&objfile->objfile_obstack,
-					   processing_current_prefix,
-					   processing_current_prefix[0] == '\0'
-					   ? "" : "::",
-					   name);
+	  TYPE_TAG_NAME (type) = typename_concat (&objfile->objfile_obstack,
+						  processing_current_prefix,
+						  name, cu);
 	}
       else
 	{
@@ -3546,7 +3559,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 *
@@ -3593,8 +3606,9 @@ determine_class_name (struct die_info *d
   if (new_prefix == NULL)
     {
       const char *name = dwarf2_name (die, cu);
-      new_prefix = typename_concat (processing_current_prefix,
-				    name ? name : "<<anonymous>>");
+      new_prefix = typename_concat (NULL, processing_current_prefix,
+				    name ? name : "<<anonymous>>", 
+				    cu);
     }
 
   if (back_to != NULL)
@@ -3877,7 +3891,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;
@@ -4166,10 +4183,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)
@@ -4820,7 +4838,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);
@@ -6431,7 +6450,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);
 	      
@@ -6448,7 +6468,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
@@ -6459,15 +6479,18 @@ 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
-	       defines a typedef for "foo". Synthesize a typedef symbol so
-	       that "ptype foo" works as expected.  */
-	    if (cu->language == language_cplus)
+	       defines a typedef for "foo".  A Java class declaration also
+	       defines a typedef for the class.  Synthesize a typedef symbol
+	       so that "ptype foo" works as expected.  */
+	    if (cu->language == language_cplus
+		|| cu->language == language_java)
 	      {
 		struct symbol *typedef_sym = (struct symbol *)
 		  obstack_alloc (&objfile->objfile_obstack,
@@ -6487,10 +6510,9 @@ new_symbol (struct die_info *die, struct
 	  if (processing_has_namespace_info
 	      && processing_current_prefix[0] != '\0')
 	    {
-	      SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
-						    processing_current_prefix,
-						    "::",
-						    name);
+	      SYMBOL_LINKAGE_NAME (sym) = typename_concat (&objfile->objfile_obstack,
+							   processing_current_prefix,
+							   name, cu);
 	    }
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
@@ -6506,10 +6528,9 @@ new_symbol (struct die_info *die, struct
 	  if (processing_has_namespace_info
 	      && processing_current_prefix[0] != '\0')
 	    {
-	      SYMBOL_LINKAGE_NAME (sym) = obconcat (&objfile->objfile_obstack,
-						    processing_current_prefix,
-						    "::",
-						    name);
+	      SYMBOL_LINKAGE_NAME (sym) = typename_concat (&objfile->objfile_obstack,
+							   processing_current_prefix,
+							   name, cu);
 	    }
 	  attr = dwarf2_attr (die, DW_AT_const_value, cu);
 	  if (attr)
@@ -6523,7 +6544,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);
@@ -6832,7 +6854,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;
@@ -6856,9 +6879,10 @@ determine_prefix (struct die_info *die, 
 	    {
 	      int dummy;
 	      char *parent_prefix = determine_prefix (parent, cu);
-	      char *retval = typename_concat (parent_prefix,
+	      char *retval = typename_concat (NULL, parent_prefix,
 					      namespace_name (parent, &dummy,
-							      cu));
+							      cu),
+					      cu);
 	      xfree (parent_prefix);
 	      return retval;
 	    }
@@ -6891,25 +6915,47 @@ 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
-   string, just return a copy of SUFFIX.  */
+/* Return a newly-allocated string formed by concatenating PREFIX and
+   SUFFIX with appropriate separator.  If PREFIX or SUFFIX is NULL or empty, then
+   simply copy the SUFFIX or PREFIX, respectively.  If OBS is non-null,
+   perform an obconcat, otherwise allocate storage for the result.  The CU argument
+   is used to determine the language and hence, the appropriate separator.  */
+
+#define MAX_SEP_LEN 2  /* sizeof ("::")  */
 
 static char *
-typename_concat (const char *prefix, const char *suffix)
+typename_concat (struct obstack *obs, const char *prefix, const char *suffix, 
+		 struct dwarf2_cu *cu)
 {
-  if (prefix == NULL || prefix[0] == '\0')
-    return xstrdup (suffix);
-  else
-    {
-      char *retval = xmalloc (strlen (prefix) + 2 + strlen (suffix) + 1);
+  char *sep;
 
-      strcpy (retval, prefix);
-      strcat (retval, "::");
-      strcat (retval, suffix);
+  if (suffix == NULL || suffix[0] == '\0' || prefix == NULL || prefix[0] == '\0')
+    sep = "";
+  else if (cu->language == language_java)
+    sep = ".";
+  else
+    sep = "::";
 
+  if (obs == NULL)
+    {
+      char *retval = xmalloc (strlen (prefix) + MAX_SEP_LEN + strlen (suffix) + 1);
+      retval[0] = '\0';
+      
+      if (prefix)
+	{
+	  strcpy (retval, prefix);
+	  strcat (retval, sep);
+	}
+      if (suffix)
+	strcat (retval, suffix);
+      
       return retval;
     }
+  else
+    {
+      /* We have an obstack.  */
+      return obconcat (obs, prefix, sep, suffix);
+    }
 }
 
 static struct type *
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	9 Sep 2004 23:36:39 -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.135
diff -u -p -r1.135 symtab.c
--- symtab.c	10 Aug 2004 21:16:13 -0000	1.135
+++ symtab.c	9 Sep 2004 23:36:39 -0000
@@ -1000,7 +1000,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)
     {
@@ -1012,6 +1012,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.23
diff -u -p -r1.23 valarith.c
--- valarith.c	27 Jun 2004 07:57:15 -0000	1.23
+++ valarith.c	9 Sep 2004 23:36:39 -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]