This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Java: ENABLE_TREE_CHECKING patch.
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH] Java: ENABLE_TREE_CHECKING patch.
- From: Alexandre Petit-Bianco <apbianco at cygnus dot com>
- Date: Wed, 21 Jun 2000 22:04:27 -0700
- Reply-to: apbianco at redhat dot com
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;
}