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: ENABLE_TREE_CHECKING patch.


This patch let the Java compiler build the Java run-time again. It
fixes errors unraveled by ENABLE_TREE_CHECKING, now enabled by
default:

  http://gcc.gnu.org/ml/gcc-patches/2000-06/msg00551.html

There also is a cp/ patch for that matter:

  http://gcc.gnu.org/ml/gcc-patches/2000-06/threads.html#00682

I checking this in.

./A

2000-06-21  Alexandre Petit-Bianco  <apbianco@cygnus.com>

        * except.c (prepare_eh_table_type): Use `CATCH_ALL_TYPE'.

2000-06-20  Alexandre Petit-Bianco  <apbianco@cygnus.com>

        * check-init.c (ENABLE_JC1_CHECKING): Replaces ENABLE_CHECKING for
        Java specific checks.
        * expr.c (build_instanceof): CLASS_INTERFACE and CLASS_FINAL usage
        screened by DECL_P.
        * java-tree.def (CASE_EXPR): Marked 'e'.
        (DEFAULT_EXPR): Likewise.
        * jcf-parse.c (set_source_filename): CLASS_COMPLETE_P usage
        screened by DECL_P.
        * jcf-write.c (ENABLE_JC1_CHECKING): Replaces ENABLE_CHECKING for
        Java specific checks.
        (generate_bytecode_insns): Test try_block for BLOCK before using
        BLOCK_EXPR_BODY.
        * parse.y (build_wfl_wrap): Added `location' argument. Set
        EXPR_WFL_LINECOL accordingly.
        (dim_expr:): Wrap constants with WFLs.
        (method_declarator): Use TREE_TYPE not TYPE_NAME on GET_CPC.
        (resolve_package): Check for `stmt' not being a BLOCK before
        building a debuggable statement with it.
        (make_qualified_primary): Added extra parameter to build_wfl_wrap
        invocation.
        (resolve_field_access): Make sure `decl' is a DECL before treating
        it as such.
        (maybe_build_primttype_type_ref): Make sure `wfl''s node is an
        IDENTIFIER_NODE before treating it as such.
        (patch_new_array_init): Make sure `elt' is a TREE_LIST before
        treating it as such.
        (find_applicable_accessible_methods_list): CLASS_INTERFACE macro
        to be applied only on non array types.

2000-06-16  Per Bothner  <per@bothner.com>

        * java-tree.h (LABEL_RETURN_LABELS, LABEL_PENDING_CHAIN):  Don't
        define in terms of DECL_RESULT, as that fails when --enable-checking.
        
2000-06-06  Alexandre Petit-Bianco  <apbianco@cygnus.com>

        * parse.h (REGISTER_IMPORT): Use `chainon' to link new entries.
        * parse.y (find_in_imports): Returned type changed to void,
        leading comment fixed.
        (register_package): New function.
        (qualify_and_find): Likewise.
        (package_declaration:): Use `register_package'.
        (single_type_import_declaration:): Removed local variable
        `node'. Added missing `;' for consistency.
        (type_import_on_demand_declaration:): Use `chainon' to link new
        entries.
        (lookup_field_wrapper): Lookup local variables defined in outer
        contexts first.
        (java_complete_class): Don't reverse the list of imported on demand.
        (do_resolve_class): Reorganized. Removed local variable
        `original_name'. Call `qualify_and_find' with the current package
        name, invoke `find_in_imports_on_demand' right after. Call
        `qualify_and_find' with the packages we've seen so far. Fixed
        operations numbering in comments.
        (java_expand_class): Don't reverse `package_list'.
        (find_most_specific_methods_list): New local variables `abstract'
        and `candidates'. Use them to pick the right method.

Index: check-init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/check-init.c,v
retrieving revision 1.22
diff -u -p -r1.22 check-init.c
--- check-init.c	2000/05/09 19:55:52	1.22
+++ check-init.c	2000/06/22 04:44:29
@@ -463,7 +463,7 @@ check_init (exp, before)
 	words tmp = ALLOC_WORDS (2 * num_current_words);
 	words when_true = tmp;
 	words when_false = tmp + num_current_words;
-#ifdef ENABLE_CHECKING
+#ifdef ENABLE_JC1_CHECKING
 	if (TREE_CODE (alt->block) != LOOP_EXPR)
 	  fatal ("internal error in check-init:  EXIT_EXPR not in LOOP_EXPR");
 #endif
@@ -534,7 +534,7 @@ check_init (exp, before)
     case WITH_CLEANUP_EXPR:
       {
 	struct alternatives *alt = alternatives;	
-#ifdef ENABLE_CHECKING
+#ifdef ENABLE_JC1_CHECKING
 	if (TREE_CODE (alt->block) != CLEANUP_POINT_EXPR)
 	  fatal ("internal error in check-init:  WITH_CLEANUP_EXPR not in CLEANUP_POINT_EXPR");
 #endif
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/except.c,v
retrieving revision 1.22
diff -u -p -r1.22 except.c
--- except.c	2000/03/19 18:25:27	1.22
+++ except.c	2000/06/22 04:44:30
@@ -325,7 +325,7 @@ prepare_eh_table_type (type)
 
   push_obstacks (&permanent_obstack, &permanent_obstack);
   if (type == NULL_TREE)
-    exp = null_pointer_node;
+    exp = CATCH_ALL_TYPE;
   else if (is_compiled_class (type))
     exp = build_class_ref (type);
   else
Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/expr.c,v
retrieving revision 1.76
diff -u -p -r1.76 expr.c
--- expr.c	2000/05/31 23:55:54	1.76
+++ expr.c	2000/06/22 04:44:37
@@ -1087,7 +1087,8 @@ build_instanceof (value, type)
 		    value,
 		    boolean_true_node, boolean_false_node);
     }
-  else if (! CLASS_INTERFACE (valclass)
+  else if (DECL_P (klass) && DECL_P (valclass)
+	   && ! CLASS_INTERFACE (valclass)
 	   && ! CLASS_INTERFACE (klass)
 	   && ! inherits_from_p (type, valtype)
 	   && (CLASS_FINAL (klass)
@@ -1097,7 +1098,7 @@ build_instanceof (value, type)
 	 tree, so we immediately know the answer.  */
       expr = boolean_false_node;
     }
-  else if (CLASS_FINAL (klass))
+  else if (DECL_P (klass) && CLASS_FINAL (klass))
     {
       tree save = save_expr (value);
       expr = build (COND_EXPR, itype,
Index: java-tree.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.def,v
retrieving revision 1.14
diff -u -p -r1.14 java-tree.def
--- java-tree.def	2000/05/02 20:32:30	1.14
+++ java-tree.def	2000/06/22 04:44:37
@@ -42,10 +42,10 @@ DEFTREECODE (THIS_EXPR, "this", '1', 0)
 
 /* Case statement expression.
    Operand 1 is the case value.  */
-DEFTREECODE (CASE_EXPR, "case", 'x', 1)
+DEFTREECODE (CASE_EXPR, "case", 'e', 1)
 
 /* Default statement expression. */
-DEFTREECODE (DEFAULT_EXPR, "default", 'x', 0)
+DEFTREECODE (DEFAULT_EXPR, "default", 'e', 0)
 
 /* Try expression
    Operand 0 is the tried block,
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.72
diff -u -p -r1.72 java-tree.h
--- java-tree.h	2000/06/01 07:44:57	1.72
+++ java-tree.h	2000/06/22 04:44:41
@@ -465,11 +465,12 @@ struct lang_identifier
 #define RETURN_MAP_ADJUSTED(NODE) TREE_LANG_FLAG_2(NODE)
 
 /* In the label of a sub-routine, a chain of the return location labels. */
-#define LABEL_RETURN_LABELS(node) DECL_RESULT (LABEL_RETURN_LABEL(node))
+#define LABEL_RETURN_LABELS(node) \
+  (LABEL_DECL_CHECK (LABEL_RETURN_LABEL(node))->decl.result)
 
 /* In a LABEL_DECL, the next pending label.
    See pending_blocks in expr.c. */
-#define LABEL_PENDING_CHAIN(NODE) DECL_RESULT(NODE)
+#define LABEL_PENDING_CHAIN(NODE) (LABEL_DECL_CHECK (NODE)->decl.result)
 
 /* In a LABEL_DECL, the corresponding bytecode program counter. */
 #define LABEL_PC(NODE) ((NODE)->decl.u2.i)
Index: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-parse.c,v
retrieving revision 1.48
diff -u -p -r1.48 jcf-parse.c
--- jcf-parse.c	2000/06/01 18:26:16	1.48
+++ jcf-parse.c	2000/06/22 04:44:43
@@ -193,7 +193,7 @@ set_source_filename (jcf, index)
   while (c--)								  \
     {									  \
       tree class = get_class_constant (jcf, JCF_readu2 (jcf));	    	  \
-      if (!CLASS_COMPLETE_P (class))					  \
+      if (DECL_P (class) && !CLASS_COMPLETE_P (class))			  \
 	{								  \
 	  tree outer = TYPE_NAME (get_class_constant (jcf, 		  \
 						      JCF_readu2 (jcf))); \
Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-write.c,v
retrieving revision 1.58
diff -u -p -r1.58 jcf-write.c
--- jcf-write.c	2000/06/15 18:08:44	1.58
+++ jcf-write.c	2000/06/22 04:44:50
@@ -347,7 +347,7 @@ static void append_innerclasses_attribut
    We assume a local variable 'ptr' points into where we want to
    write next, and we assume enoygh space has been allocated. */
 
-#ifdef ENABLE_CHECKING
+#ifdef ENABLE_JC1_CHECKING
 static int CHECK_PUT PARAMS ((void *, struct jcf_partial *, int));
 
 static int
@@ -403,7 +403,7 @@ alloc_chunk (last, data, size, work)
   return chunk;
 }
 
-#ifdef ENABLE_CHECKING
+#ifdef ENABLE_JC1_CHECKING
 static int CHECK_OP PARAMS ((struct jcf_partial *));
 
 static int
@@ -2358,6 +2358,7 @@ generate_bytecode_insns (exp, target, st
 	  }
 
 	if (CAN_COMPLETE_NORMALLY (try_block)
+	    && TREE_CODE (try_block) == BLOCK
 	    && BLOCK_EXPR_BODY (try_block) != empty_stmt_node)
 	  emit_goto (finished_label, state);
 
Index: parse.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.h,v
retrieving revision 1.53
diff -u -p -r1.53 parse.h
--- parse.h	2000/06/01 07:44:58	1.53
+++ parse.h	2000/06/22 04:45:38
@@ -687,12 +687,11 @@ typedef struct _jdeplist {
   }
 
 /* Register an import */
-#define REGISTER_IMPORT(WHOLE, NAME)			\
-{							\
-  IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P ((NAME)) = 1;	\
-  node = build_tree_list ((WHOLE), (NAME));		\
-  TREE_CHAIN (node) = ctxp->import_list;		\
-  ctxp->import_list = node;				\
+#define REGISTER_IMPORT(WHOLE, NAME)					\
+{									\
+  IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P ((NAME)) = 1;			\
+  ctxp->import_list = chainon (ctxp->import_list, 			\
+			       build_tree_list ((WHOLE), (NAME)));	\
 }
 
 /* Macro to access the osb (opening square bracket) count */
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/parse.y,v
retrieving revision 1.178
diff -u -p -r1.178 parse.y
--- parse.y	2000/06/14 05:30:06	1.178
+++ parse.y	2000/06/22 04:46:11
@@ -99,8 +99,9 @@ static void complete_class_report_errors
 static int process_imports PARAMS ((void));
 static void read_import_dir PARAMS ((tree));
 static int find_in_imports_on_demand PARAMS ((tree));
-static int find_in_imports PARAMS ((tree));
+static void find_in_imports PARAMS ((tree));
 static int check_pkg_class_access PARAMS ((tree, tree));
+static void register_package PARAMS ((tree));
 static tree resolve_package PARAMS ((tree, tree *));
 static tree lookup_package_type PARAMS ((const char *, int));
 static tree lookup_package_type_and_set_next PARAMS ((const char *, int, tree *));
@@ -120,6 +121,7 @@ static tree patch_method_invocation PARA
 					    int *, tree *));
 static int breakdown_qualified PARAMS ((tree *, tree *, tree));
 static tree resolve_and_layout PARAMS ((tree, tree));
+static tree qualify_and_find PARAMS ((tree, tree, tree));
 static tree resolve_no_layout PARAMS ((tree, tree));
 static int invocation_mode PARAMS ((tree, int));
 static tree find_applicable_accessible_methods_list PARAMS ((int, tree, 
@@ -180,7 +182,7 @@ static tree build_newarray_node PARAMS (
 static tree patch_newarray PARAMS ((tree));
 static tree resolve_type_during_patch PARAMS ((tree));
 static tree build_this PARAMS ((int));
-static tree build_wfl_wrap PARAMS ((tree));
+static tree build_wfl_wrap PARAMS ((tree, int));
 static tree build_return PARAMS ((int, tree));
 static tree patch_return PARAMS ((tree));
 static tree maybe_access_field PARAMS ((tree, tree, tree));
@@ -682,7 +684,7 @@ package_declaration:
 	PACKAGE_TK name SC_TK
 		{ 
 		  ctxp->package = EXPR_WFL_NODE ($2);
-		  package_list = tree_cons (ctxp->package, NULL, package_list);
+		  register_package (ctxp->package);
 		}
 |	PACKAGE_TK error
 		{yyerror ("Missing name"); RECOVER;}
@@ -698,7 +700,7 @@ import_declaration:
 single_type_import_declaration:
 	IMPORT_TK name SC_TK
 		{
-		  tree name = EXPR_WFL_NODE ($2), node, last_name;
+		  tree name = EXPR_WFL_NODE ($2), last_name;
 		  int   i = IDENTIFIER_LENGTH (name)-1;
 		  const char *last = &IDENTIFIER_POINTER (name)[i];
 		  while (last != IDENTIFIER_POINTER (name))
@@ -717,7 +719,7 @@ single_type_import_declaration:
 			   IDENTIFIER_POINTER (name), 
 			   IDENTIFIER_POINTER (err));
 		      else
-			REGISTER_IMPORT ($2, last_name)
+			REGISTER_IMPORT ($2, last_name);
 		    }
 		  else
 		    REGISTER_IMPORT ($2, last_name);
@@ -735,10 +737,10 @@ type_import_on_demand_declaration:
 		  /* Don't import java.lang.* twice. */
 		  if (name != java_lang_id)
 		    {
-		      tree node = build_tree_list ($2, NULL_TREE);
 		      read_import_dir ($2);
-		      TREE_CHAIN (node) = ctxp->import_demand_list;
-		      ctxp->import_demand_list = node;
+		      ctxp->import_demand_list = 
+			chainon (ctxp->import_demand_list,
+				 build_tree_list ($2, NULL_TREE));
 		    }
 		}
 |	IMPORT_TK name DOT_TK error
@@ -2079,6 +2081,11 @@ dim_exprs:
 dim_expr:
 	OSB_TK expression CSB_TK
 		{ 
+		  if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
+		    {
+		      $2 = build_wfl_node ($2);
+		      TREE_TYPE ($2) = NULL_TREE;
+		    }
 		  EXPR_WFL_LINECOL ($2) = $1.location;
 		  $$ = $2;
 		}
@@ -3993,23 +4000,27 @@ lookup_field_wrapper (class, name)
      tree class, name;
 {
   tree type = class;
-  tree decl;
+  tree decl = NULL_TREE;
   java_parser_context_save_global ();
-  decl = lookup_field (&type, name);
 
   /* Last chance: if we're within the context of an inner class, we
      might be trying to access a local variable defined in an outer
      context. We try to look for it now. */
-  if (INNER_CLASS_TYPE_P (class) && (!decl || decl == error_mark_node))
+  if (INNER_CLASS_TYPE_P (class))
     {
       char *alias_buffer;
+      tree new_name;
       MANGLE_OUTER_LOCAL_VARIABLE_NAME (alias_buffer, name);
-      name = get_identifier (alias_buffer);
-      type = class;
-      decl = lookup_field (&type, name);
+      new_name = get_identifier (alias_buffer);
+      decl = lookup_field (&type, new_name);
       if (decl && decl != error_mark_node)
 	FIELD_LOCAL_ALIAS_USED (decl) = 1;
     }
+  if (!decl || decl == error_mark_node)
+    {
+      type = class;
+      decl = lookup_field (&type, name);
+    }
 
   java_parser_context_restore_global ();
   return decl == error_mark_node ? NULL : decl;
@@ -4673,7 +4684,7 @@ method_declarator (id, list)
 
       /* Then this$<n> */
       type = TREE_TYPE (DECL_CONTEXT (GET_CPC ()));
-      thisn = build_current_thisn (TYPE_NAME (GET_CPC ()));
+      thisn = build_current_thisn (TREE_TYPE (GET_CPC ()));
       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
 			list);
     }
@@ -5207,10 +5218,8 @@ java_complete_class ()
 
   push_obstacks (&permanent_obstack, &permanent_obstack);
 
-  /* Process imports and reverse the import on demand list */
+  /* Process imports */
   process_imports ();
-  if (ctxp->import_demand_list)
-    ctxp->import_demand_list = nreverse (ctxp->import_demand_list);
 
   /* Rever things so we have the right order */
   ctxp->class_list = nreverse (ctxp->class_list);
@@ -5415,10 +5424,10 @@ do_resolve_class (enclosing, class_type,
      tree enclosing, class_type, decl, cl;
 {
   tree new_class_decl;
-  tree original_name = NULL_TREE;
 
   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
-     its is changed by find_in_imports{_on_demand} */
+     it is changed by find_in_imports{_on_demand} and (but it doesn't
+     really matter) qualify_and_find */
 
   /* 0- Search in the current class as an inner class */
 
@@ -5452,12 +5461,11 @@ do_resolve_class (enclosing, class_type,
       enclosing = do_resolve_class (NULL, name, NULL, NULL);
     }
 
-  /* 1- Check for the type in single imports */
-  if (find_in_imports (class_type))
-    return NULL_TREE;
+  /* 1- Check for the type in single imports. This will change
+     TYPE_NAME() if something relevant is found */
+  find_in_imports (class_type);
 
-  /* 2- And check for the type in the current compilation unit. If it fails,
-     try with a name qualified with the package name we've seen so far */
+  /* 2- And check for the type in the current compilation unit */
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     {
       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -5465,35 +5473,38 @@ do_resolve_class (enclosing, class_type,
 	load_class (TYPE_NAME (class_type), 0);
       return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
     }
+
+  /* 3- Search according to the current package definition */
+  if (!QUALIFIED_P (TYPE_NAME (class_type)))
+    {
+      if ((new_class_decl = qualify_and_find (class_type, ctxp->package,
+					     TYPE_NAME (class_type))))
+	return new_class_decl;
+    }
+
+  /* 4- Check the import on demands. Don't allow bar.baz to be
+     imported from foo.* */
+  if (!QUALIFIED_P (TYPE_NAME (class_type)))
+    if (find_in_imports_on_demand (class_type))
+      return NULL_TREE;
+
+  /* If found in find_in_imports_on_demant, the type has already been
+     loaded. */
+  if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
+    return new_class_decl;
 
-  original_name = TYPE_NAME (class_type);
+  /* 5- Try with a name qualified with the package name we've seen so far */
   if (!QUALIFIED_P (TYPE_NAME (class_type)))
     {
       tree package;
       for (package = package_list; package; package = TREE_CHAIN (package))
-  	{
- 	  tree new_qualified;
- 	  
- 	  new_qualified = merge_qualified_name (TREE_PURPOSE (package),
- 						original_name);
- 	  TYPE_NAME (class_type) = new_qualified;
- 	  new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
- 	  if (!new_class_decl)
- 	    load_class (TYPE_NAME (class_type), 0);
- 	  new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
- 	  if (new_class_decl)
- 	    {
- 	      if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
- 		  !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
- 		load_class (TYPE_NAME (class_type), 0);
- 	      return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
- 	    }
-	}
+	if ((new_class_decl = qualify_and_find (class_type,
+					       TREE_PURPOSE (package), 
+					       TYPE_NAME (class_type))))
+	  return new_class_decl;
     }
-
-  TYPE_NAME (class_type) = original_name;
 
-  /* 3- Check an other compilation unit that bears the name of type */
+  /* 5- Check an other compilation unit that bears the name of type */
   load_class (TYPE_NAME (class_type), 0);
   if (check_pkg_class_access (TYPE_NAME (class_type), 
 			      (cl ? cl : lookup_cl (decl))))
@@ -5501,17 +5512,31 @@ do_resolve_class (enclosing, class_type,
 
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     return new_class_decl;
-
-  /* 4- Check the import on demands. Don't allow bar.baz to be
-     imported from foo.* */
-  if (!QUALIFIED_P (TYPE_NAME (class_type)))
-    if (find_in_imports_on_demand (class_type))
-      return NULL_TREE;
 
-  /* 5- Last call for a resolution */
+  /* 6- Last call for a resolution */
   return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
 }
 
+static tree
+qualify_and_find (class_type, package, name)
+     tree class_type, package, name;
+{
+  tree new_qualified = merge_qualified_name (package, name);
+  tree new_class_decl;
+
+  if (!IDENTIFIER_CLASS_VALUE (new_qualified))
+    load_class (new_qualified, 0);
+  if ((new_class_decl = IDENTIFIER_CLASS_VALUE (new_qualified)))
+    {
+      if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
+	  !CLASS_FROM_SOURCE_P (TREE_TYPE (new_class_decl)))
+	load_class (new_qualified, 0);
+      TYPE_NAME (class_type) = new_qualified;
+      return IDENTIFIER_CLASS_VALUE (new_qualified);
+    }
+  return NULL_TREE;
+}
+
 /* Resolve NAME and lay it out (if not done and if not the current
    parsed class). Return a decl node. This function is meant to be
    called when type resolution is necessary during the walk pass.  */
@@ -6385,10 +6410,10 @@ process_imports ()
   return 0;
 }
 
-/* Possibly find a class imported by a single-type import statement. Return
-   1 if an error occured, 0 otherwise. */
+/* Possibly find and mark a class imported by a single-type import
+   statement.  */
 
-static int
+static void
 find_in_imports (class_type)
      tree class_type;
 {
@@ -6400,7 +6425,6 @@ find_in_imports (class_type)
 	TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
 	QUALIFIED_P (TYPE_NAME (class_type)) = 1;
       }
-  return 0;
 }
 
 static int
@@ -6610,6 +6634,30 @@ find_in_imports_on_demand (class_type)
     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
 }
 
+/* Add package NAME to the list of package encountered so far. To
+   speed up class lookup in do_resolve_class, we make sure a
+   particular package is added only once.  */
+
+static void
+register_package (name)
+     tree name;
+{
+  static struct hash_table _pht, *pht = NULL;
+
+  if (!pht)
+    {
+      hash_table_init (&_pht, hash_newfunc, 
+		       java_hash_hash_tree_node, java_hash_compare_tree_node);
+      pht = &_pht;
+    }
+  
+  if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
+    {
+      package_list = chainon (package_list, build_tree_list (name, NULL));
+      hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
+    }
+}
+
 static tree
 resolve_package (pkg, next)
      tree pkg, *next;
@@ -7378,10 +7426,12 @@ maybe_generate_pre_expand_clinit (class_
   for (current = TYPE_CLINIT_STMT_LIST (class_type); current;
        current = TREE_CHAIN (current))
     {
+      tree stmt = current;
       /* We build the assignment expression that will initialize the
 	 field to its value. There are strict rules on static
 	 initializers (8.5). FIXME */
-      tree stmt = build_debugable_stmt (EXPR_WFL_LINECOL (current), current);
+      if (TREE_CODE (stmt) != BLOCK)
+	stmt = build_debugable_stmt (EXPR_WFL_LINECOL (stmt), stmt);
       java_method_add_stmt (mdecl, stmt);
     }
 
@@ -8342,12 +8392,6 @@ java_expand_classes ()
   java_layout_classes ();
   java_parse_abort_on_error ();
 
-  /* The list of packages declaration seen so far needs to be
-     reversed, so that package declared in a file being compiled gets
-     priority over packages declared as a side effect of parsing other
-     files.*/
-  package_list = nreverse (package_list);
-
   saved_ctxp = ctxp_for_generation;
   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
     {
@@ -8426,7 +8470,7 @@ make_qualified_primary (primary, right, 
   tree wfl;
 
   if (TREE_CODE (primary) != EXPR_WITH_FILE_LOCATION)
-    wfl = build_wfl_wrap (primary);
+    wfl = build_wfl_wrap (primary, location);
   else
     {
       wfl = primary;
@@ -8643,7 +8687,8 @@ resolve_field_access (qual_wfl, field_de
     return error_mark_node;
 
   /* Resolve the LENGTH field of an array here */
-  if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
+  if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
+      && TYPE_ARRAY_P (type_found) 
       && ! flag_emit_class_files && ! flag_emit_xref)
     {
       tree length = build_java_array_length_access (where_found);
@@ -10035,7 +10080,8 @@ find_applicable_accessible_methods_list 
     }
 
   /* Search interfaces */
-  if (CLASS_INTERFACE (TYPE_NAME (class)))
+  if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
+      && CLASS_INTERFACE (TYPE_NAME (class)))
     {
       static struct hash_table t, *searched_interfaces = NULL;
       static int search_not_done = 0;
@@ -10183,6 +10229,7 @@ find_most_specific_methods_list (list)
      tree list;
 {
   int max = 0;
+  int abstract, candidates;
   tree current, new_list = NULL_TREE;
   for (current = list; current; current = TREE_CHAIN (current))
     {
@@ -10209,24 +10256,33 @@ find_most_specific_methods_list (list)
     }
 
   /* Review the list and select the maximally specific methods */
-  for (current = list; current; current = TREE_CHAIN (current))
+  for (current = list, abstract = -1, candidates = -1;
+       current; current = TREE_CHAIN (current))
     if (DECL_SPECIFIC_COUNT (TREE_VALUE (current)) == max)
-      new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
+      {
+	new_list = tree_cons (NULL_TREE, TREE_VALUE (current), new_list);
+	abstract += (METHOD_ABSTRACT (TREE_VALUE (current)) ? 1 : 0);
+	candidates++;
+      }
 
   /* If we have several and they're all abstract, just pick the
      closest one. */
+  if (candidates > 0 && (candidates == abstract))
+    {
+      new_list = nreverse (new_list);
+      TREE_CHAIN (new_list) = NULL_TREE;
+    }
 
-  if (new_list && TREE_CHAIN (new_list))
+  /* We have several, we couldn't find a most specific, all but one are
+     abstract, we pick the only non abstract one. */
+  if (candidates > 0 && !max && (candidates == abstract+1))
     {
-      tree c;
-      for (c = new_list; c && METHOD_ABSTRACT (TREE_VALUE (c)); 
-	   c = TREE_CHAIN (c))
-        ;
-      if (!c)
-	{
-	  new_list = nreverse (new_list);
-	  TREE_CHAIN (new_list) = NULL_TREE;
-	}
+      for (current = new_list; current; current = TREE_CHAIN (current))
+	if (!METHOD_ABSTRACT (TREE_VALUE (current)))
+	  {
+	    TREE_CHAIN (current) = NULL_TREE;
+	    new_list = current;
+	  }
     }
 
   /* If we can't find one, lower expectations and try to gather multiple
@@ -11465,8 +11521,9 @@ maybe_absorb_scoping_blocks ()
 
 /* Wrap a non WFL node around a WFL.  */
 static tree
-build_wfl_wrap (node)
+build_wfl_wrap (node, location)
     tree node;
+    int location;
 {
   tree wfl, node_to_insert = node;
   
@@ -11478,7 +11535,7 @@ build_wfl_wrap (node)
   else
     wfl = build_expr_wfl (NULL_TREE, ctxp->filename, 0, 0);
 
-  EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (node);
+  EXPR_WFL_LINECOL (wfl) = location;
   EXPR_WFL_QUALIFICATION (wfl) = build_tree_list (node_to_insert, NULL_TREE);
   return wfl;
 }
@@ -11644,7 +11701,8 @@ maybe_build_primttype_type_ref (rhs, wfl
       tree n = TREE_OPERAND (rhs, 1);
       if (TREE_CODE (n) == VAR_DECL 
 	  && DECL_NAME (n) == TYPE_identifier_node
-	  && rhs_type == class_ptr_type)
+	  && rhs_type == class_ptr_type
+	  && TREE_CODE (EXPR_WFL_NODE (wfl)) == IDENTIFIER_NODE)
 	{
 	  const char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
 	  if (!strncmp (self_name, "java.lang.", 10))
@@ -13536,7 +13594,8 @@ patch_new_array_init (type, node)
 	  TREE_PURPOSE (current) = NULL_TREE;
 	  all_constant = 0;
 	}
-      if (elt && TREE_VALUE (elt) == error_mark_node)
+      if (elt && TREE_CODE (elt) == TREE_LIST 
+	  && TREE_VALUE (elt) == error_mark_node)
 	error_seen = 1;
     }
 

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