ENABLE_TREE_CHECKING

Alexandre Petit-Bianco apbianco@cygnus.com
Tue Jun 20 22:09:00 GMT 2000


Alexandre Petit-Bianco writes:
> I plan on posting/submitting/checking-in patches fairly soon.

OK. There are two patches. One for the Java front-end, one for the C++
front-end. I haven't thoroughly tested the compiler, but it rebuilds
the runtime and stands against my personal 1.1 non regression test
suite (approximately a subset of what's in the libgcj/testsuite
directory.)
I'll check the patch in once I've tested it against Plum Hall. Note
that this patch also includes fixes to let jc1 build SAX and XP, two
components of a free XML implementation.
Per, I need a ChangeLog entry for your patch
( http://gcc.gnu.org/ml/gcc-patches/2000-06/msg00551.html )
The first patch will be posted to the g++ patches mailing list. Apply
it to the egcs/cp directory if you want to rebuild your runtime.
./A
2000年06月20日 Alexandre Petit-Bianco <apbianco@cygnus.com>
	* class.c (push_lang_context): TYPE_NAME gets you to the Java
	types DECLs.
	* decl.c (check_goto): Non DECL labels treated as not yet defined
	ones.
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.320
diff -u -p -r1.320 class.c
--- class.c	2000年06月14日 16:10:14	1.320
+++ class.c	2000年06月21日 05:00:02
@@ -5682,14 +5682,14 @@ push_lang_context (name)
 	 (See record_builtin_java_type in decl.c.) However, that causes
 	 incorrect debug entries if these types are actually used.
 	 So we re-enable debug output after extern "Java". */
- DECL_IGNORED_P (java_byte_type_node) = 0;
- DECL_IGNORED_P (java_short_type_node) = 0;
- DECL_IGNORED_P (java_int_type_node) = 0;
- DECL_IGNORED_P (java_long_type_node) = 0;
- DECL_IGNORED_P (java_float_type_node) = 0;
- DECL_IGNORED_P (java_double_type_node) = 0;
- DECL_IGNORED_P (java_char_type_node) = 0;
- DECL_IGNORED_P (java_boolean_type_node) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_byte_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_short_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_int_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_long_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_float_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_double_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_char_type_node)) = 0;
+ DECL_IGNORED_P (TYPE_NAME (java_boolean_type_node)) = 0;
 }
 else if (name == lang_name_c)
 {
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.638
diff -u -p -r1.638 decl.c
--- decl.c	2000年06月19日 18:40:21	1.638
+++ decl.c	2000年06月21日 05:00:38
@@ -5025,7 +5025,7 @@ check_goto (decl)
 struct named_label_list *lab;
 
 /* If the label hasn't been defined yet, defer checking. */
- if (! DECL_INITIAL (decl))
+ if (! DECL_P (decl) || ! DECL_INITIAL (decl))
 {
 use_label (decl);
 return;
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月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月21日 05:05:52
@@ -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: 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月21日 05:05:58
@@ -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月21日 05:05:59
@@ -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月21日 05:06:02
@@ -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月21日 05:06:05
@@ -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月21日 05:06:12
@@ -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月21日 05:06:15
@@ -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月21日 05:06:48
@@ -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, 
@@ -134,7 +136,7 @@ static tree lookup_method_invoke PARAMS 
 static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
 static tree obtain_incomplete_type PARAMS ((tree));
 static tree java_complete_lhs PARAMS ((tree));
-static tree java_complete_tree PARAMS ((tree));
+tree java_complete_tree PARAMS ((tree));
 static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
 static int maybe_yank_clinit PARAMS ((tree));
 static void java_complete_expand_method PARAMS ((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
@@ -10526,7 +10582,7 @@ breakdown_qualified (left, right, source
 local variable decls if present.
 Same as java_complete_lhs, but does resolve static finals to values. */
 
-static tree
+tree
 java_complete_tree (node)
 tree node;
 {
@@ -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;
 }
 


More information about the Java mailing list

AltStyle によって変換されたページ (->オリジナル) /