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 gcc/java type resoluton simplification


This is a simplification of the Java type resolution algorithm.
This also seems to fix a bug, where the compiler could sometimes
(not quite sure when) get confused in the presence of circular
dependencies.

I've checked it into egcs.

	--Per Bothner
Cygnus Solutions     bothner@cygnus.com     http://www.cygnus.com/~bothner

Fri Feb 19 13:00:56 1999  Per Bothner  <bothner@cygnus.com>

	* parse.y (obtain_incomplete_type):  Don't wrap unknown types
	in TREE_LIST - just chain the POINTER_TYPEs together.
	(resolve_class):  If type already resolved, return decl.
	After resolving, update TREE_TYPE(class_type), and name (if array).
	* parse.h (do_resolve_class), parse.y:  Make non-static.	
	* class.c (maybe_layout_super_class):  Take this_class argument.
	Do do_resolve_class if necessary.
	(layout_class, layout_class_methods): Adjust calls appropriately.
	* parse.h (JDEP_TO_RESOLVE, JDEP_RESOLVED_DECL, JDEP_RESOLVED,
	JDEP_RESOLVED_P):  Redefined for new TREE_LIST-less convention.
	* typeck.c (build_java_array_type):  Don't call layout_class.

Index: class.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/class.c,v
retrieving revision 1.61
diff -u -p -r1.61 class.c
--- class.c	1999/02/19 01:10:28	1.61
+++ class.c	1999/02/19 22:47:53
@@ -1402,8 +1402,9 @@ push_super_field (this_class, super_clas
 /* Handle the different manners we may have to lay out a super class.  */
 
 static tree
-maybe_layout_super_class (super_class)
+maybe_layout_super_class (super_class, this_class)
      tree super_class;
+     tree this_class;
 {
   if (TREE_CODE (super_class) == RECORD_TYPE)
     {
@@ -1415,14 +1416,17 @@ maybe_layout_super_class (super_class)
     }
   /* We might have to layout the class before its dependency on
      the super class gets resolved by java_complete_class  */
-  else if (TREE_CODE (super_class) == TREE_LIST)
+  else if (TREE_CODE (super_class) == POINTER_TYPE)
     {
-      tree name = TYPE_NAME (TREE_PURPOSE (super_class));
-      load_class (name, 1);
-      super_class = IDENTIFIER_CLASS_VALUE (name);
-      if (!super_class)
-	return NULL_TREE;	/* FIXME, NULL_TREE not checked by caller. */
-      super_class = TREE_TYPE (super_class);
+      if (TREE_TYPE (super_class) != NULL_TREE)
+	super_class = TREE_TYPE (super_class);
+      else
+	{
+	  super_class = do_resolve_class (super_class, NULL_TREE, this_class);
+	  if (!super_class)
+	    return NULL_TREE;	/* FIXME, NULL_TREE not checked by caller. */
+	  super_class = TREE_TYPE (super_class);
+	}
     }
   if (!TYPE_SIZE (super_class))
     safe_layout_class (super_class);
@@ -1439,7 +1443,7 @@ layout_class (this_class)
 
   if (super_class)
     {
-      super_class = maybe_layout_super_class (super_class);
+      super_class = maybe_layout_super_class (super_class, this_class);
       if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK)
 	{
 	  TYPE_SIZE (this_class) = error_mark_node;
@@ -1478,7 +1482,7 @@ layout_class_methods (this_class)
 
   if (super_class)
     {
-      super_class = maybe_layout_super_class (super_class);
+      super_class = maybe_layout_super_class (super_class, this_class);
       if (!TYPE_NVIRTUALS (super_class))
 	layout_class_methods (super_class);
       dtable_count = TYPE_NVIRTUALS (super_class);
Index: parse.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/parse.h,v
retrieving revision 1.38
diff -u -p -r1.38 parse.h
--- parse.h	1999/02/19 20:36:11	1.38
+++ parse.h	1999/02/19 22:47:53
@@ -381,15 +381,11 @@ typedef struct _jdep {
 #define JDEP_APPLY_PATCH(J,P) (*(J)->patch = (P))
 #define JDEP_GET_PATCH(J)     ((J)->patch)
 #define JDEP_CHAIN(J)         ((J)->next)
-#define JDEP_TO_RESOLVE(J)    (TREE_PURPOSE ((J)->solv))
-#define JDEP_RESOLVED_DECL(J) ((J)->solv ? TREE_PURPOSE ((J)->solv):NULL_TREE)
-#define JDEP_RESOLVED(J, D)			\
-  {						\
-    TREE_PURPOSE ((J)->solv) = D;		\
-    TREE_VALUE ((J)->solv) = (J)->solv;		\
-  }
-#define JDEP_RESOLVED_P(J)    (!(J)->solv || 				\
-			       TREE_VALUE ((J)->solv) == (J)->solv)
+#define JDEP_TO_RESOLVE(J)    ((J)->solv)
+#define JDEP_RESOLVED_DECL(J) ((J)->solv)
+#define JDEP_RESOLVED(J, D)   ((J)->solv = D)
+#define JDEP_RESOLVED_P(J)    \
+	(!(J)->solv || TREE_CODE ((J)->solv) != POINTER_TYPE)
 
 typedef struct _jdeplist {
   jdep *first;
@@ -667,6 +663,7 @@ tree java_method_add_stmt PROTO ((tree, 
 char *java_get_line_col PROTO ((char *, int, int));
 void java_expand_switch PROTO ((tree));
 int java_report_errors PROTO (());
+extern tree do_resolve_class PROTO ((tree, tree, tree));
 #endif
 
 /* Always in use, no matter what you compile */
Index: parse.y
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/parse.y,v
retrieving revision 1.51
diff -u -p -r1.51 parse.y
--- parse.y	1999/02/19 21:28:56	1.51
+++ parse.y	1999/02/19 22:47:53
@@ -99,7 +99,6 @@ static int check_pkg_class_access PROTO 
 static tree resolve_package PROTO ((tree, tree *));
 static tree lookup_package_type PROTO ((char *, int));
 static tree resolve_class PROTO ((tree, tree, tree));
-static tree do_resolve_class PROTO ((tree, tree, tree));
 static void declare_local_variables PROTO ((int, tree, tree));
 static void source_start_java_method PROTO ((tree));
 static void source_end_java_method PROTO ((void));
@@ -3806,16 +3805,14 @@ obtain_incomplete_type (type_name)
     fatal ("invalid type name - obtain_incomplete_type");
 
   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
-    if (TYPE_NAME (TREE_PURPOSE (ptr)) == name)
+    if (TYPE_NAME (ptr) == name)
       break;
 
   if (!ptr)
     {
-      tree core;
       push_obstacks (&permanent_obstack, &permanent_obstack);
-      BUILD_PTR_FROM_NAME (core, name);
-      layout_type (core);
-      ptr = build_tree_list (core, NULL_TREE);
+      BUILD_PTR_FROM_NAME (ptr, name);
+      layout_type (ptr);
       pop_obstacks ();
       TREE_CHAIN (ptr) = ctxp->incomplete_class;
       ctxp->incomplete_class = ptr;
@@ -4077,8 +4074,22 @@ resolve_class (class_type, decl, cl)
 {
   char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
   char *base = name;
-  tree resolved_type, resolved_type_decl;
+  tree resolved_type = TREE_TYPE (class_type);
+  tree resolved_type_decl;
   
+  if (resolved_type != NULL_TREE)
+    {
+      tree resolved_type_decl = TYPE_NAME (resolved_type);
+      if (resolved_type_decl == NULL_TREE
+	  || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
+	{
+	  resolved_type_decl = build_decl (TYPE_DECL,
+					   TYPE_NAME (class_type),
+					   resolved_type);
+	}
+      return resolved_type_decl;
+    }
+
   /* 1- Check to see if we have an array. If true, find what we really
      want to resolve  */
   while (name[0] == '[')
@@ -4109,14 +4120,16 @@ resolve_class (class_type, decl, cl)
       /* Figure how those two things are important for error report. FIXME */
       DECL_SOURCE_LINE (resolved_type_decl) = 0;
       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
+      TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
     }
+  TREE_TYPE (class_type) = resolved_type;
   return resolved_type_decl;
 }
 
 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
    are used to report error messages.  */
 
-static tree
+tree
 do_resolve_class (class_type, decl, cl)
      tree class_type;
      tree decl;
Index: typeck.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/typeck.c,v
retrieving revision 1.41
diff -u -p -r1.41 typeck.c
--- typeck.c	1999/02/18 21:52:06	1.41
+++ typeck.c	1999/02/19 22:47:53
@@ -404,7 +404,12 @@ build_java_array_type (element_type, len
     TYPE_ALIGN (t) = TYPE_ALIGN (element_type);
   pop_obstacks ();
 
-  layout_class (t);
+  /* We could layout_class, but that loads java.lang.Object prematurely.
+   * This is called by the parser, and it is a bad idea to do load_class
+   * in the middle of parsing, because of possible circularity problems. */
+  push_super_field (t, object_type_node);
+  layout_type (t);
+
   return t;
 }
 


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