This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH gcc/java type resoluton simplification
- To: egcs-patches at egcs dot cygnus dot com
- Subject: PATCH gcc/java type resoluton simplification
- From: Per Bothner <bothner at cygnus dot com>
- Date: Fri, 19 Feb 1999 14:58:02 -0800
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;
}