This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

[PATCH] Java: miscellaneous fixes


I just checked in a patch in order to fix several bugs in the source
code front end of the Java compiler:

  - Method invocation qualified by a package name are now processed
    correctly. Bug reported by Bryce McKinlay,
    http://sourceware.cygnus.com/ml/java-discuss/1999-q2/msg00489.html

  - A bug found when trying to use package names in qualified expressions
    that are not method invocations (like in
    mauve/gnu/testlet/java/text/Collator/Constants.java)

  - A minor xref infrastructure bug, occurring when WFL are expanded as
    CALL_EXPR.

This patch also replaces, when compiling to class files, void methods
empty bodies by a RETURN_EXPR. As a side effect, the bytecode compiler
now emits a `return' instruction in such a case. This fixes a bug
found attempting to compile mauve/gnu/testlet/java/lang/Class/ClassTest.java
to bytecode and then from bytecode to native.

./A

Fri Jun 25 13:35:19 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (resolve_package): Fixed bogus return statement.
	(patch_method_invocation): Resolve method invocation beginning with
 	a package name qualifier.

Thu Jun 24 13:12:15 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (java_complete_lhs): When doing cross referencing, don't
 	try to keep file location on a WFL expanded as a CALL_EXPR.

Wed Jun 23 14:37:15 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (finish_method_declaration): Insert a RETURN_EXPR when
 	compiling to class file a void method with an empty method body.
  	As a side effect, the bytecode backend will generate the
 	appropriate `return' instruction.
	
Tue Jun 22 20:43:49 1999  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* parse.y (lookup_package_type_and_set_next): New function prototype.
	(resolve_package): Search current and imported packages.
	(lookup_package_type_and_set_next): New function.

Index: parse.y
===================================================================
RCS file: /cvs/egcs/egcs/gcc/java/parse.y,v
retrieving revision 1.85.4.2
diff -u -p -r1.85.4.2 parse.y
--- parse.y	1999/06/18 18:05:33	1.85.4.2
+++ parse.y	1999/06/25 23:29:57
@@ -100,6 +100,7 @@ static int find_in_imports PROTO ((tree)
 static int check_pkg_class_access PROTO ((tree, tree));
 static tree resolve_package PROTO ((tree, tree *));
 static tree lookup_package_type PROTO ((char *, int));
+static tree lookup_package_type_and_set_next PROTO ((char *, int, tree *));
 static tree resolve_class PROTO ((tree, tree, tree));
 static void declare_local_variables PROTO ((int, tree, tree));
 static void source_start_java_method PROTO ((tree));
@@ -3542,6 +3543,12 @@ finish_method_declaration (method_body)
       method_body = NULL_TREE;
     }
 
+  if (flag_emit_class_files && method_body 
+      && TREE_CODE (method_body) == NOP_EXPR 
+      && TREE_TYPE (current_function_decl) 
+      && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
+    method_body = build1 (RETURN_EXPR, void_type_node, NULL);
+    
   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
   maybe_absorb_scoping_blocks ();
   /* Exit function's body */
@@ -5237,6 +5244,7 @@ static tree
 resolve_package (pkg, next)
      tree pkg, *next;
 {
+  tree current;
   tree type_name = NULL_TREE;
   char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
 
@@ -5256,9 +5264,63 @@ resolve_package (pkg, next)
       *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
       type_name = lookup_package_type (name, 9);
     }
-  else
-    return NULL_TREE;		/* FIXME, search all imported packages. */
 
+  /* If we found something here, return */
+  if (type_name)
+    return type_name; 
+
+  *next = EXPR_WFL_QUALIFICATION (pkg);
+
+  /* Try the current package. */
+  if (ctxp->package && !strncmp (name, IDENTIFIER_POINTER (ctxp->package),  
+				 IDENTIFIER_LENGTH (ctxp->package)))
+    {
+      type_name = 
+	lookup_package_type_and_set_next (name, 
+					  IDENTIFIER_LENGTH (ctxp->package), 
+					  next );
+      if (type_name)
+	return type_name;
+    }
+
+  /* Search in imported package */
+  for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
+    {
+      tree current_pkg_name = EXPR_WFL_NODE (TREE_PURPOSE (current));
+      int len = IDENTIFIER_LENGTH (current_pkg_name);
+      if (!strncmp (name, IDENTIFIER_POINTER (current_pkg_name), len))
+	{
+	  tree left, dummy;
+	  
+	  breakdown_qualified (&left, &dummy, current_pkg_name);
+	  len = IDENTIFIER_LENGTH (left);
+	  type_name = lookup_package_type_and_set_next (name, len, next);
+	  if (type_name)
+	    break;
+	}
+    }
+
+  return type_name;
+}
+
+static tree
+lookup_package_type_and_set_next (name, len, next)
+     char *name;
+     int len;
+     tree *next;
+{
+  char *ptr;
+  tree type_name = lookup_package_type (name, len);
+
+  if (!type_name)
+    return NULL;
+  
+  ptr = IDENTIFIER_POINTER (type_name);
+  while (ptr && (ptr = strchr (ptr, '.'))) 
+    {
+      *next = TREE_CHAIN (*next);
+      ptr++;
+    }
   return type_name;
 }
 
@@ -6872,18 +6934,36 @@ patch_method_invocation (patch, primary,
 	 as a MethodName. We need to qualify what's before */
       qualify_ambiguous_name (wfl);
 
-      /* Package resolution are erroneous */
+      /* Package resolution */
       if (RESOLVE_PACKAGE_NAME_P (wfl))
 	{
-	  tree remainder;
-	  breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
-	  parse_error_context (wfl, "Can't search method `%s' in package "
-			       "`%s'",IDENTIFIER_POINTER (identifier),
-			       IDENTIFIER_POINTER (remainder));
-	  PATCH_METHOD_RETURN_ERROR ();
+	  tree next, decl, name = resolve_package (wfl, &next);
+	  
+	  if (!name)
+	    {
+	      tree remainder;
+	      breakdown_qualified (&remainder, NULL, EXPR_WFL_NODE (wfl));
+	      parse_error_context (wfl, "Can't search method `%s' in package "
+				   "`%s'",IDENTIFIER_POINTER (identifier),
+				   IDENTIFIER_POINTER (remainder));
+	      PATCH_METHOD_RETURN_ERROR ();
+	    }
+	  RESOLVE_PACKAGE_NAME_P (wfl) = 0;
+	  if ((decl = resolve_no_layout (name, QUAL_WFL (next))))
+	    {
+	      QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl)) = decl;
+	      RESOLVE_EXPRESSION_NAME_P (wfl) = 0;
+	      RESOLVE_TYPE_NAME_P (wfl) = 1;
+	    }
+	  else
+	    {
+	      RESOLVE_EXPRESSION_NAME_P (wfl) = 1;
+	      RESOLVE_TYPE_NAME_P (wfl) = 0;
+	    }
 	}
+
       /* We're resolving a call from a type */
-      else if (RESOLVE_TYPE_NAME_P (wfl))
+      if (RESOLVE_TYPE_NAME_P (wfl))
 	{
 	  tree decl = QUAL_RESOLUTION (EXPR_WFL_QUALIFICATION (wfl));
 	  tree name = DECL_NAME (decl);
@@ -7630,7 +7710,6 @@ qualify_ambiguous_name (id)
 	/* Do one more interation to set things up */
 	super_found = again = 1;
       }
-
   } while (again);
   
   /* If name appears within the scope of a location variable
@@ -8108,7 +8187,7 @@ java_complete_lhs (node)
 	    return node;
 	  /* Keep line number information somewhere were it doesn't
 	     disrupt the completion process. */
-	  if (flag_emit_xref)
+	  if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
 	    {
 	      EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
 	      TREE_OPERAND (node, 1) = wfl;


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