[PATCH] Java: fix to PR #177.

Alexandre Petit-Bianco apbianco@cygnus.com
Thu Jun 1 00:43:00 GMT 2000


This patch fixes the Java PR #177. I checking it in.

./A

2000-04-24  Alexandre Petit-Bianco  <apbianco@cygnus.com>

	* class.c (common_enclosing_context_p): New function.
	* java-tree.h (common_enclosing_context_p): Added prototype.
	* parse.h (INNER_ENCLOSING_SCOPE_CHECK): Relaxed test to allow
	classes sharing an outer context with the current instance.
	* parse.y (build_access_to_thisn): Fixed leading comment.
	(verify_constructor_super): New local `supper_inner'. Skip
	enclosing context argument in the case of inner class constructors.
	(patch_method_invocation): Insert proper context as second
	parameter to pure inner class constructor super invocations.

Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/class.c,v
retrieving revision 1.65
diff -u -p -r1.65 class.c
--- class.c	2000/04/06 01:01:11	1.65
+++ class.c	2000/04/27 20:00:13
@@ -486,6 +486,30 @@ enclosing_context_p (type1, type2)
   return 0;
 }
 
+/* Return 1 iff there exists a common enclosing context between TYPE1
+   and TYPE2.  */
+
+int common_enclosing_context_p (type1, type2)
+     tree type1, type2;
+{
+  if (!PURE_INNER_CLASS_TYPE_P (type1) && !PURE_INNER_CLASS_TYPE_P (type2))
+    return 0;
+  
+  for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1; 
+       type1 = (PURE_INNER_CLASS_TYPE_P (type1) ?
+		TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))) : NULL_TREE))
+    {
+      tree current;
+      for (current = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))); current;
+	   current = (PURE_INNER_CLASS_TYPE_P (current) ?
+		      TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current))) : 
+		      NULL_TREE))
+	if (type1 == current)
+	  return 1;
+    }
+  return 0;
+}
+
 static void
 add_interface_do (basetype_vec, interface_class, i)
      tree basetype_vec, interface_class;
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.64
diff -u -p -r1.64 java-tree.h
--- java-tree.h	2000/04/05 23:57:18	1.64
+++ java-tree.h	2000/04/27 20:00:13
@@ -672,6 +672,7 @@ extern void set_super_info PARAMS ((int,
 extern int get_access_flags_from_decl PARAMS ((tree));
 extern int interface_of_p PARAMS ((tree, tree));
 extern int inherits_from_p PARAMS ((tree, tree));
+extern int common_enclosing_context_p PARAMS ((tree, tree));
 extern int enclosing_context_p PARAMS ((tree, tree));
 extern void complete_start_java_method PARAMS ((tree));
 extern tree build_result_decl PARAMS ((tree));
Index: parse.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.h,v
retrieving revision 1.51
diff -u -p -r1.51 parse.h
--- parse.h	2000/04/24 16:17:03	1.51
+++ parse.h	2000/04/27 20:00:14
@@ -822,15 +822,17 @@ struct parser_ctxt {
 
 /* Make sure that innerclass T sits in an appropriate enclosing
    context.  */
-#define INNER_ENCLOSING_SCOPE_CHECK(T)					\
-  (INNER_CLASS_TYPE_P ((T)) && !ANONYMOUS_CLASS_P ((T))			\
-   && ((current_this							\
-	/* We have a this and it's not the right one */			\
-	&& (DECL_CONTEXT (TYPE_NAME ((T)))				\
-	    != TYPE_NAME (TREE_TYPE (TREE_TYPE (current_this))))	\
-	&& !inherits_from_p (TREE_TYPE (TREE_TYPE (current_this)),	\
-			     TREE_TYPE (DECL_CONTEXT (TYPE_NAME (T)))))	\
-       /* We don't have a this. */					\
+#define INNER_ENCLOSING_SCOPE_CHECK(T)					      \
+  (INNER_CLASS_TYPE_P ((T)) && !ANONYMOUS_CLASS_P ((T))			      \
+   && ((current_this							      \
+	/* We have a this and it's not the right one */			      \
+	&& (DECL_CONTEXT (TYPE_NAME ((T)))				      \
+	    != TYPE_NAME (TREE_TYPE (TREE_TYPE (current_this))))	      \
+	&& !inherits_from_p (TREE_TYPE (TREE_TYPE (current_this)),	      \
+			     TREE_TYPE (DECL_CONTEXT (TYPE_NAME (T))))	      \
+        && !common_enclosing_context_p (TREE_TYPE (TREE_TYPE (current_this)), \
+					(T)))				      \
+       /* We don't have a this. */					      \
        || !current_this))
 
 /* Push macro. First argument to PUSH_CPC is a DECL_TYPE, second
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.157
diff -u -p -r1.157 parse.y
--- parse.y	2000/04/25 22:14:53	1.157
+++ parse.y	2000/04/27 20:00:14
@@ -7871,7 +7873,7 @@ build_access_to_thisn (from, to, lc)
 
 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
    is returned if nothing needs to be generated. Otherwise, the method
-   generated, fully walked and a method decl is returned.  
+   generated and a method decl is returned.  
 
    NOTE: These generated methods should be declared in a class file
    attribute so that they can't be referred to directly.  */
@@ -8214,6 +8216,7 @@ verify_constructor_super (mdecl)
      tree mdecl;
 {
   tree class = CLASSTYPE_SUPER (current_class);
+  int super_inner = PURE_INNER_CLASS_TYPE_P (class);
   tree sdecl;
 
   if (!class)
@@ -8226,10 +8229,11 @@ verify_constructor_super (mdecl)
       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
 	if (DECL_CONSTRUCTOR_P (sdecl))
 	  {
-	    tree arg_type;
-	    for (arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
-		 arg_type != end_params_node && 
-		   mdecl_arg_type != end_params_node;
+	    tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
+	    if (super_inner)
+	      arg_type = TREE_CHAIN (arg_type);
+	    for (; (arg_type != end_params_node 
+		    && mdecl_arg_type != end_params_node);
 		 arg_type = TREE_CHAIN (arg_type), 
 		 mdecl_arg_type = TREE_CHAIN (mdecl_arg_type))
 	      if (TREE_VALUE (arg_type) != TREE_VALUE (mdecl_arg_type))
@@ -8244,9 +8248,10 @@ verify_constructor_super (mdecl)
     {
       for (sdecl = TYPE_METHODS (class); sdecl; sdecl = TREE_CHAIN (sdecl))
 	{
-	  if (DECL_CONSTRUCTOR_P (sdecl)
-	      && TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl))) 
-	         == end_params_node)
+	  tree arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
+	  if (super_inner)
+	    arg = TREE_CHAIN (arg);
+	  if (DECL_CONSTRUCTOR_P (sdecl) && arg == end_params_node)
 	    return 0;
 	}
     }
@@ -9514,6 +9519,30 @@ patch_method_invocation (patch, primary,
 	args = tree_cons (NULL_TREE, (primary ? primary : current_this), args);
       else
 	args = tree_cons (NULL_TREE, integer_zero_node, args);
+    }
+
+  /* This handles the situation where a constructor invocation needs
+     to have an enclosing context passed as a second parameter (the
+     constructor is one of an inner class. We extract it from the
+     current function.  */
+  if (is_super_init && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
+    {
+      tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
+      tree extra_arg;
+
+      if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
+	{
+	  extra_arg = DECL_FUNCTION_BODY (current_function_decl);
+	  extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
+	}
+      else
+	{
+	  tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
+	  extra_arg = 
+	    build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
+	  extra_arg = java_complete_tree (extra_arg);
+	}
+      args = tree_cons (NULL_TREE, extra_arg, args);
     }
 
   is_static_flag = METHOD_STATIC (list);


More information about the Gcc-patches mailing list