OSDN Git Service

Merge from pch-branch.
[pf3gnuchains/gcc-fork.git] / gcc / java / parse.y
index 11318be..c67a42e 100644 (file)
@@ -1,22 +1,23 @@
 /* Source code parsing and tree node generation for the GNU compiler
    for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
+along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.
 
@@ -35,7 +36,7 @@ Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
 The following modifications were brought to the original grammar:
 
 method_body: added the rule '| block SC_TK'
-static_initializer: added the rule 'static block SC_TK'. 
+static_initializer: added the rule 'static block SC_TK'.
 
 Note: All the extra rules described above should go away when the
       empty_statement rule will work.
@@ -48,9 +49,12 @@ definitions and other extensions.  */
 %{
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include <dirent.h>
 #include "tree.h"
 #include "rtl.h"
+#include "real.h"
 #include "obstack.h"
 #include "toplev.h"
 #include "flags.h"
@@ -65,289 +69,277 @@ definitions and other extensions.  */
 #include "function.h"
 #include "except.h"
 #include "ggc.h"
-
-#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
-#endif
+#include "debug.h"
+#include "tree-inline.h"
 
 /* Local function prototypes */
-static char *java_accstring_lookup PARAMS ((int));
-static void  classitf_redefinition_error PARAMS ((const char *,tree, tree, tree));
-static void  variable_redefinition_error PARAMS ((tree, tree, tree, int));
-static tree  create_class PARAMS ((int, tree, tree, tree));
-static tree  create_interface PARAMS ((int, tree, tree));
-static void  end_class_declaration PARAMS ((int));
-static tree  find_field PARAMS ((tree, tree));
-static tree lookup_field_wrapper PARAMS ((tree, tree));
-static int   duplicate_declaration_error_p PARAMS ((tree, tree, tree));
-static void  register_fields PARAMS ((int, tree, tree));
-static tree parser_qualified_classname PARAMS ((tree));
-static int  parser_check_super PARAMS ((tree, tree, tree));
-static int  parser_check_super_interface PARAMS ((tree, tree, tree));
-static void check_modifiers_consistency PARAMS ((int));
-static tree lookup_cl PARAMS ((tree));
-static tree lookup_java_method2 PARAMS ((tree, tree, int));
-static tree method_header PARAMS ((int, tree, tree, tree));
-static void fix_method_argument_names PARAMS ((tree ,tree));
-static tree method_declarator PARAMS ((tree, tree));
-static void parse_warning_context PARAMS ((tree cl, const char *msg, ...))
+static char *java_accstring_lookup (int);
+static void  classitf_redefinition_error (const char *,tree, tree, tree);
+static void  variable_redefinition_error (tree, tree, tree, int);
+static tree  create_class (int, tree, tree, tree);
+static tree  create_interface (int, tree, tree);
+static void  end_class_declaration (int);
+static tree  find_field (tree, tree);
+static tree lookup_field_wrapper (tree, tree);
+static int   duplicate_declaration_error_p (tree, tree, tree);
+static void  register_fields (int, tree, tree);
+static tree parser_qualified_classname (tree);
+static int  parser_check_super (tree, tree, tree);
+static int  parser_check_super_interface (tree, tree, tree);
+static void check_modifiers_consistency (int);
+static tree lookup_cl (tree);
+static tree lookup_java_method2 (tree, tree, int);
+static tree method_header (int, tree, tree, tree);
+static void fix_method_argument_names (tree ,tree);
+static tree method_declarator (tree, tree);
+static void parse_warning_context (tree cl, const char *msg, ...)
   ATTRIBUTE_PRINTF_2;
-static void issue_warning_error_from_context PARAMS ((tree, const char *msg, va_list))
+static void issue_warning_error_from_context (tree, const char *msg, va_list)
   ATTRIBUTE_PRINTF (2, 0);
-static void parse_ctor_invocation_error PARAMS ((void));
-static tree parse_jdk1_1_error PARAMS ((const char *));
-static void complete_class_report_errors PARAMS ((jdep *));
-static int process_imports PARAMS ((void));
-static void read_import_dir PARAMS ((tree));
-static int find_in_imports_on_demand PARAMS ((tree, tree));
-static void find_in_imports PARAMS ((tree, tree));
-static void check_inner_class_access PARAMS ((tree, tree, tree));
-static int check_pkg_class_access PARAMS ((tree, tree, bool));
-static void register_package PARAMS ((tree));
-static tree resolve_package PARAMS ((tree, tree *));
-static tree lookup_package_type PARAMS ((const char *, int));
-static tree resolve_class PARAMS ((tree, tree, tree, tree));
-static void declare_local_variables PARAMS ((int, tree, tree));
-static void source_start_java_method PARAMS ((tree));
-static void source_end_java_method PARAMS ((void));
-static tree find_name_in_single_imports PARAMS ((tree));
-static void check_abstract_method_header PARAMS ((tree));
-static tree lookup_java_interface_method2 PARAMS ((tree, tree));
-static tree resolve_expression_name PARAMS ((tree, tree *));
-static tree maybe_create_class_interface_decl PARAMS ((tree, tree, tree, tree));
-static int check_class_interface_creation PARAMS ((int, int, tree, 
-                                                 tree, tree, tree));
-static tree patch_method_invocation PARAMS ((tree, tree, tree, int,
-                                           int *, tree *));
-static int breakdown_qualified PARAMS ((tree *, tree *, tree));
-static int in_same_package PARAMS ((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, 
-                                                           tree, tree));
-static void search_applicable_methods_list PARAMS ((int, tree, tree, tree, 
-                                                  tree *, tree *));
-static tree find_most_specific_methods_list PARAMS ((tree));
-static int argument_types_convertible PARAMS ((tree, tree));
-static tree patch_invoke PARAMS ((tree, tree, tree));
-static int maybe_use_access_method PARAMS ((int, tree *, tree *));
-static tree lookup_method_invoke PARAMS ((int, tree, tree, tree, tree));
-static tree register_incomplete_type PARAMS ((int, tree, tree, tree));
-static tree check_inner_circular_reference PARAMS ((tree, tree));
-static tree check_circular_reference PARAMS ((tree));
-static tree obtain_incomplete_type PARAMS ((tree));
-static tree java_complete_lhs PARAMS ((tree));
-static tree java_complete_tree PARAMS ((tree));
-static tree maybe_generate_pre_expand_clinit PARAMS ((tree));
-static int analyze_clinit_body PARAMS ((tree));
-static int maybe_yank_clinit PARAMS ((tree));
-static void start_complete_expand_method PARAMS ((tree));
-static void java_complete_expand_method PARAMS ((tree));
-static void java_expand_method_bodies PARAMS ((tree));
-static int  unresolved_type_p PARAMS ((tree, tree *));
-static void create_jdep_list PARAMS ((struct parser_ctxt *));
-static tree build_expr_block PARAMS ((tree, tree));
-static tree enter_block PARAMS ((void));
-static tree exit_block PARAMS ((void));
-static tree lookup_name_in_blocks PARAMS ((tree));
-static void maybe_absorb_scoping_blocks PARAMS ((void));
-static tree build_method_invocation PARAMS ((tree, tree));
-static tree build_new_invocation PARAMS ((tree, tree));
-static tree build_assignment PARAMS ((int, int, tree, tree));
-static tree build_binop PARAMS ((enum tree_code, int, tree, tree));
-static tree patch_assignment PARAMS ((tree, tree));
-static tree patch_binop PARAMS ((tree, tree, tree));
-static tree build_unaryop PARAMS ((int, int, tree));
-static tree build_incdec PARAMS ((int, int, tree, int));
-static tree patch_unaryop PARAMS ((tree, tree));
-static tree build_cast PARAMS ((int, tree, tree));
-static tree build_null_of_type PARAMS ((tree));
-static tree patch_cast PARAMS ((tree, tree));
-static int valid_ref_assignconv_cast_p PARAMS ((tree, tree, int));
-static int valid_builtin_assignconv_identity_widening_p PARAMS ((tree, tree));
-static int valid_cast_to_p PARAMS ((tree, tree));
-static int valid_method_invocation_conversion_p PARAMS ((tree, tree));
-static tree try_builtin_assignconv PARAMS ((tree, tree, tree));
-static tree try_reference_assignconv PARAMS ((tree, tree));
-static tree build_unresolved_array_type PARAMS ((tree));
-static int build_type_name_from_array_name PARAMS ((tree, tree *));
-static tree build_array_from_name PARAMS ((tree, tree, tree, tree *));
-static tree build_array_ref PARAMS ((int, tree, tree));
-static tree patch_array_ref PARAMS ((tree));
-static tree make_qualified_name PARAMS ((tree, tree, int));
-static tree merge_qualified_name PARAMS ((tree, tree));
-static tree make_qualified_primary PARAMS ((tree, tree, int));
-static int resolve_qualified_expression_name PARAMS ((tree, tree *, 
-                                                    tree *, tree *));
-static void qualify_ambiguous_name PARAMS ((tree));
-static tree resolve_field_access PARAMS ((tree, tree *, tree *));
-static tree build_newarray_node PARAMS ((tree, tree, int));
-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, int));
-static tree build_return PARAMS ((int, tree));
-static tree patch_return PARAMS ((tree));
-static tree maybe_access_field PARAMS ((tree, tree, tree));
-static int complete_function_arguments PARAMS ((tree));
-static int check_for_static_method_reference PARAMS ((tree, tree, tree, 
-                                                     tree, tree));
-static int not_accessible_p PARAMS ((tree, tree, tree, int));
-static void check_deprecation PARAMS ((tree, tree));
-static int class_in_current_package PARAMS ((tree));
-static tree build_if_else_statement PARAMS ((int, tree, tree, tree));
-static tree patch_if_else_statement PARAMS ((tree));
-static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
-static tree add_stmt_to_block PARAMS ((tree, tree, tree));
-static tree patch_exit_expr PARAMS ((tree));
-static tree build_labeled_block PARAMS ((int, tree));
-static tree finish_labeled_statement PARAMS ((tree, tree));
-static tree build_bc_statement PARAMS ((int, int, tree));
-static tree patch_bc_statement PARAMS ((tree));
-static tree patch_loop_statement PARAMS ((tree));
-static tree build_new_loop PARAMS ((tree));
-static tree build_loop_body PARAMS ((int, tree, int));
-static tree finish_loop_body PARAMS ((int, tree, tree, int));
-static tree build_debugable_stmt PARAMS ((int, tree));
-static tree finish_for_loop PARAMS ((int, tree, tree, tree));
-static tree patch_switch_statement PARAMS ((tree));
-static tree string_constant_concatenation PARAMS ((tree, tree));
-static tree build_string_concatenation PARAMS ((tree, tree));
-static tree patch_string_cst PARAMS ((tree));
-static tree patch_string PARAMS ((tree));
-static tree encapsulate_with_try_catch PARAMS ((int, tree, tree, tree));
-static tree build_try_statement PARAMS ((int, tree, tree));
-static tree build_try_finally_statement PARAMS ((int, tree, tree));
-static tree patch_try_statement PARAMS ((tree));
-static tree patch_synchronized_statement PARAMS ((tree, tree));
-static tree patch_throw_statement PARAMS ((tree, tree));
-static void check_thrown_exceptions PARAMS ((int, tree));
-static int check_thrown_exceptions_do PARAMS ((tree));
-static void purge_unchecked_exceptions PARAMS ((tree));
-static bool ctors_unchecked_throws_clause_p PARAMS ((tree));
-static void check_throws_clauses PARAMS ((tree, tree, tree));
-static void finish_method_declaration PARAMS ((tree));
-static tree build_super_invocation PARAMS ((tree));
-static int verify_constructor_circularity PARAMS ((tree, tree));
-static char *constructor_circularity_msg PARAMS ((tree, tree));
-static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
-                                                         int, int));
-static const char *get_printable_method_name PARAMS ((tree));
-static tree patch_conditional_expr PARAMS ((tree, tree, tree));
-static tree generate_finit PARAMS ((tree));
-static tree generate_instinit PARAMS ((tree));
-static tree build_instinit_invocation PARAMS ((tree));
-static void fix_constructors PARAMS ((tree));
-static tree build_alias_initializer_parameter_list PARAMS ((int, tree,
-                                                           tree, int *));
-static void craft_constructor PARAMS ((tree, tree));
-static int verify_constructor_super PARAMS ((tree));
-static tree create_artificial_method PARAMS ((tree, int, tree, tree, tree));
-static void start_artificial_method_body PARAMS ((tree));
-static void end_artificial_method_body PARAMS ((tree));
-static int check_method_redefinition PARAMS ((tree, tree));
-static int check_method_types_complete PARAMS ((tree));
-static void java_check_regular_methods PARAMS ((tree));
-static void java_check_abstract_methods PARAMS ((tree));
-static void unreachable_stmt_error PARAMS ((tree));
-static tree find_expr_with_wfl PARAMS ((tree));
-static void missing_return_error PARAMS ((tree));
-static tree build_new_array_init PARAMS ((int, tree));
-static tree patch_new_array_init PARAMS ((tree, tree));
-static tree maybe_build_array_element_wfl PARAMS ((tree));
-static int array_constructor_check_entry PARAMS ((tree, tree));
-static const char *purify_type_name PARAMS ((const char *));
-static tree fold_constant_for_init PARAMS ((tree, tree));
-static tree strip_out_static_field_access_decl PARAMS ((tree));
-static jdeplist *reverse_jdep_list PARAMS ((struct parser_ctxt *));
-static void static_ref_err PARAMS ((tree, tree, tree));
-static void parser_add_interface PARAMS ((tree, tree, tree));
-static void add_superinterfaces PARAMS ((tree, tree));
-static tree jdep_resolve_class PARAMS ((jdep *));
-static int note_possible_classname PARAMS ((const char *, int));
-static void java_complete_expand_classes PARAMS ((void));
-static void java_complete_expand_class PARAMS ((tree));
-static void java_complete_expand_methods PARAMS ((tree));
-static tree cut_identifier_in_qualified PARAMS ((tree));
-static tree java_stabilize_reference PARAMS ((tree));
-static tree do_unary_numeric_promotion PARAMS ((tree));
-static char * operator_string PARAMS ((tree));
-static tree do_merge_string_cste PARAMS ((tree, const char *, int, int));
-static tree merge_string_cste PARAMS ((tree, tree, int));
-static tree java_refold PARAMS ((tree));
-static int java_decl_equiv PARAMS ((tree, tree));
-static int binop_compound_p PARAMS ((enum tree_code));
-static tree search_loop PARAMS ((tree));
-static int labeled_block_contains_loop_p PARAMS ((tree, tree));
-static int check_abstract_method_definitions PARAMS ((int, tree, tree));
-static void java_check_abstract_method_definitions PARAMS ((tree));
-static void java_debug_context_do PARAMS ((int));
-static void java_parser_context_push_initialized_field PARAMS ((void));
-static void java_parser_context_pop_initialized_field PARAMS ((void));
-static tree reorder_static_initialized PARAMS ((tree));
-static void java_parser_context_suspend PARAMS ((void));
-static void java_parser_context_resume PARAMS ((void));
-static int pop_current_osb PARAMS ((struct parser_ctxt *));
+static void parse_ctor_invocation_error (void);
+static tree parse_jdk1_1_error (const char *);
+static void complete_class_report_errors (jdep *);
+static int process_imports (void);
+static void read_import_dir (tree);
+static int find_in_imports_on_demand (tree, tree);
+static void find_in_imports (tree, tree);
+static void check_inner_class_access (tree, tree, tree);
+static int check_pkg_class_access (tree, tree, bool);
+static void register_package (tree);
+static tree resolve_package (tree, tree *, tree *);
+static tree resolve_class (tree, tree, tree, tree);
+static void declare_local_variables (int, tree, tree);
+static void dump_java_tree (enum tree_dump_index, tree);
+static void source_start_java_method (tree);
+static void source_end_java_method (void);
+static tree find_name_in_single_imports (tree);
+static void check_abstract_method_header (tree);
+static tree lookup_java_interface_method2 (tree, tree);
+static tree resolve_expression_name (tree, tree *);
+static tree maybe_create_class_interface_decl (tree, tree, tree, tree);
+static int check_class_interface_creation (int, int, tree, tree, tree, tree);
+static tree patch_method_invocation (tree, tree, tree, int, int *, tree *);
+static int breakdown_qualified (tree *, tree *, tree);
+static int in_same_package (tree, tree);
+static tree resolve_and_layout (tree, tree);
+static tree qualify_and_find (tree, tree, tree);
+static tree resolve_no_layout (tree, tree);
+static int invocation_mode (tree, int);
+static tree find_applicable_accessible_methods_list (int, tree, tree, tree);
+static void search_applicable_methods_list (int, tree, tree, tree, tree *, tree *);
+static tree find_most_specific_methods_list (tree);
+static int argument_types_convertible (tree, tree);
+static tree patch_invoke (tree, tree, tree);
+static int maybe_use_access_method (int, tree *, tree *);
+static tree lookup_method_invoke (int, tree, tree, tree, tree);
+static tree register_incomplete_type (int, tree, tree, tree);
+static tree check_inner_circular_reference (tree, tree);
+static tree check_circular_reference (tree);
+static tree obtain_incomplete_type (tree);
+static tree java_complete_lhs (tree);
+static tree java_complete_tree (tree);
+static tree maybe_generate_pre_expand_clinit (tree);
+static int analyze_clinit_body (tree, tree);
+static int maybe_yank_clinit (tree);
+static void start_complete_expand_method (tree);
+static void java_complete_expand_method (tree);
+static void java_expand_method_bodies (tree);
+static int  unresolved_type_p (tree, tree *);
+static void create_jdep_list (struct parser_ctxt *);
+static tree build_expr_block (tree, tree);
+static tree enter_block (void);
+static tree exit_block (void);
+static tree lookup_name_in_blocks (tree);
+static void maybe_absorb_scoping_blocks (void);
+static tree build_method_invocation (tree, tree);
+static tree build_new_invocation (tree, tree);
+static tree build_assignment (int, int, tree, tree);
+static tree build_binop (enum tree_code, int, tree, tree);
+static tree patch_assignment (tree, tree);
+static tree patch_binop (tree, tree, tree);
+static tree build_unaryop (int, int, tree);
+static tree build_incdec (int, int, tree, int);
+static tree patch_unaryop (tree, tree);
+static tree build_cast (int, tree, tree);
+static tree build_null_of_type (tree);
+static tree patch_cast (tree, tree);
+static int valid_ref_assignconv_cast_p (tree, tree, int);
+static int valid_builtin_assignconv_identity_widening_p (tree, tree);
+static int valid_cast_to_p (tree, tree);
+static int valid_method_invocation_conversion_p (tree, tree);
+static tree try_builtin_assignconv (tree, tree, tree);
+static tree try_reference_assignconv (tree, tree);
+static tree build_unresolved_array_type (tree);
+static int build_type_name_from_array_name (tree, tree *);
+static tree build_array_from_name (tree, tree, tree, tree *);
+static tree build_array_ref (int, tree, tree);
+static tree patch_array_ref (tree);
+static tree make_qualified_name (tree, tree, int);
+static tree merge_qualified_name (tree, tree);
+static tree make_qualified_primary (tree, tree, int);
+static int resolve_qualified_expression_name (tree, tree *, tree *, tree *);
+static void qualify_ambiguous_name (tree);
+static tree resolve_field_access (tree, tree *, tree *);
+static tree build_newarray_node (tree, tree, int);
+static tree patch_newarray (tree);
+static tree resolve_type_during_patch (tree);
+static tree build_this (int);
+static tree build_wfl_wrap (tree, int);
+static tree build_return (int, tree);
+static tree patch_return (tree);
+static tree maybe_access_field (tree, tree, tree);
+static int complete_function_arguments (tree);
+static int check_for_static_method_reference (tree, tree, tree, tree, tree);
+static int not_accessible_p (tree, tree, tree, int);
+static void check_deprecation (tree, tree);
+static int class_in_current_package (tree);
+static tree build_if_else_statement (int, tree, tree, tree);
+static tree patch_if_else_statement (tree);
+static tree add_stmt_to_compound (tree, tree, tree);
+static tree add_stmt_to_block (tree, tree, tree);
+static tree patch_exit_expr (tree);
+static tree build_labeled_block (int, tree);
+static tree finish_labeled_statement (tree, tree);
+static tree build_bc_statement (int, int, tree);
+static tree patch_bc_statement (tree);
+static tree patch_loop_statement (tree);
+static tree build_new_loop (tree);
+static tree build_loop_body (int, tree, int);
+static tree finish_loop_body (int, tree, tree, int);
+static tree build_debugable_stmt (int, tree);
+static tree finish_for_loop (int, tree, tree, tree);
+static tree patch_switch_statement (tree);
+static tree string_constant_concatenation (tree, tree);
+static tree build_string_concatenation (tree, tree);
+static tree patch_string_cst (tree);
+static tree patch_string (tree);
+static tree encapsulate_with_try_catch (int, tree, tree, tree);
+static tree build_assertion (int, tree, tree);
+static tree build_try_statement (int, tree, tree);
+static tree build_try_finally_statement (int, tree, tree);
+static tree patch_try_statement (tree);
+static tree patch_synchronized_statement (tree, tree);
+static tree patch_throw_statement (tree, tree);
+static void check_thrown_exceptions (int, tree);
+static int check_thrown_exceptions_do (tree);
+static void purge_unchecked_exceptions (tree);
+static bool ctors_unchecked_throws_clause_p (tree);
+static void check_throws_clauses (tree, tree, tree);
+static void finish_method_declaration (tree);
+static tree build_super_invocation (tree);
+static int verify_constructor_circularity (tree, tree);
+static char *constructor_circularity_msg (tree, tree);
+static tree build_this_super_qualified_invocation (int, tree, tree, int, int);
+static const char *get_printable_method_name (tree);
+static tree patch_conditional_expr (tree, tree, tree);
+static tree generate_finit (tree);
+static tree generate_instinit (tree);
+static tree build_instinit_invocation (tree);
+static void fix_constructors (tree);
+static tree build_alias_initializer_parameter_list (int, tree, tree, int *);
+static tree craft_constructor (tree, tree);
+static int verify_constructor_super (tree);
+static tree create_artificial_method (tree, int, tree, tree, tree);
+static void start_artificial_method_body (tree);
+static void end_artificial_method_body (tree);
+static int check_method_redefinition (tree, tree);
+static int check_method_types_complete (tree);
+static void java_check_regular_methods (tree);
+static void java_check_abstract_methods (tree);
+static void unreachable_stmt_error (tree);
+static tree find_expr_with_wfl (tree);
+static void missing_return_error (tree);
+static tree build_new_array_init (int, tree);
+static tree patch_new_array_init (tree, tree);
+static tree maybe_build_array_element_wfl (tree);
+static int array_constructor_check_entry (tree, tree);
+static const char *purify_type_name (const char *);
+static tree fold_constant_for_init (tree, tree);
+static tree strip_out_static_field_access_decl (tree);
+static jdeplist *reverse_jdep_list (struct parser_ctxt *);
+static void static_ref_err (tree, tree, tree);
+static void parser_add_interface (tree, tree, tree);
+static void add_superinterfaces (tree, tree);
+static tree jdep_resolve_class (jdep *);
+static int note_possible_classname (const char *, int);
+static void java_complete_expand_classes (void);
+static void java_complete_expand_class (tree);
+static void java_complete_expand_methods (tree);
+static tree cut_identifier_in_qualified (tree);
+static tree java_stabilize_reference (tree);
+static tree do_unary_numeric_promotion (tree);
+static char * operator_string (tree);
+static tree do_merge_string_cste (tree, const char *, int, int);
+static tree merge_string_cste (tree, tree, int);
+static tree java_refold (tree);
+static int java_decl_equiv (tree, tree);
+static int binop_compound_p (enum tree_code);
+static tree search_loop (tree);
+static int labeled_block_contains_loop_p (tree, tree);
+static int check_abstract_method_definitions (int, tree, tree);
+static void java_check_abstract_method_definitions (tree);
+static void java_debug_context_do (int);
+static void java_parser_context_push_initialized_field (void);
+static void java_parser_context_pop_initialized_field (void);
+static tree reorder_static_initialized (tree);
+static void java_parser_context_suspend (void);
+static void java_parser_context_resume (void);
+static int pop_current_osb (struct parser_ctxt *);
 
 /* JDK 1.1 work. FIXME */
 
-static tree maybe_make_nested_class_name PARAMS ((tree));
-static void make_nested_class_name PARAMS ((tree));
-static void set_nested_class_simple_name_value PARAMS ((tree, int));
-static void link_nested_class_to_enclosing PARAMS ((void));
-static tree resolve_inner_class PARAMS ((struct hash_table *, tree, tree *,
-                                        tree *, tree));
-static tree find_as_inner_class PARAMS ((tree, tree, tree));
-static tree find_as_inner_class_do PARAMS ((tree, tree));
-static int check_inner_class_redefinition PARAMS ((tree, tree));
-
-static tree build_thisn_assign PARAMS ((void));
-static tree build_current_thisn PARAMS ((tree));
-static tree build_access_to_thisn PARAMS ((tree, tree, int));
-static tree maybe_build_thisn_access_method PARAMS ((tree));
-
-static tree build_outer_field_access PARAMS ((tree, tree));
-static tree build_outer_field_access_methods PARAMS ((tree));
-static tree build_outer_field_access_expr PARAMS ((int, tree, tree, 
-                                                 tree, tree));
-static tree build_outer_method_access_method PARAMS ((tree));
-static tree build_new_access_id PARAMS ((void));
-static tree build_outer_field_access_method PARAMS ((tree, tree, tree,
-                                                   tree, tree));
-
-static int outer_field_access_p PARAMS ((tree, tree));
-static int outer_field_expanded_access_p PARAMS ((tree, tree *, 
-                                                tree *, tree *));
-static tree outer_field_access_fix PARAMS ((tree, tree, tree));
-static tree build_incomplete_class_ref PARAMS ((int, tree));
-static tree patch_incomplete_class_ref PARAMS ((tree));
-static tree create_anonymous_class PARAMS ((int, tree));
-static void patch_anonymous_class PARAMS ((tree, tree, tree));
-static void add_inner_class_fields PARAMS ((tree, tree));
-
-static tree build_dot_class_method PARAMS ((tree));
-static tree build_dot_class_method_invocation PARAMS ((tree));
-static void create_new_parser_context PARAMS ((int));
-static void mark_parser_ctxt PARAMS ((void *));
-static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
-
-static bool attach_init_test_initialization_flags PARAMS ((struct hash_entry *,
-                                                         PTR));
-static bool adjust_init_test_initialization PARAMS ((struct hash_entry *,
-                                                    PTR));
-static bool emit_test_initialization PARAMS ((struct hash_entry *, PTR));
+static tree maybe_make_nested_class_name (tree);
+static int make_nested_class_name (tree);
+static void set_nested_class_simple_name_value (tree, int);
+static void link_nested_class_to_enclosing (void);
+static tree resolve_inner_class (htab_t, tree, tree *, tree *, tree);
+static tree find_as_inner_class (tree, tree, tree);
+static tree find_as_inner_class_do (tree, tree);
+static int check_inner_class_redefinition (tree, tree);
+
+static tree build_thisn_assign (void);
+static tree build_current_thisn (tree);
+static tree build_access_to_thisn (tree, tree, int);
+static tree maybe_build_thisn_access_method (tree);
+
+static tree build_outer_field_access (tree, tree);
+static tree build_outer_field_access_methods (tree);
+static tree build_outer_field_access_expr (int, tree, tree,
+                                                 tree, tree);
+static tree build_outer_method_access_method (tree);
+static tree build_new_access_id (void);
+static tree build_outer_field_access_method (tree, tree, tree,
+                                                   tree, tree);
+
+static int outer_field_access_p (tree, tree);
+static int outer_field_expanded_access_p (tree, tree *,
+                                                tree *, tree *);
+static tree outer_field_access_fix (tree, tree, tree);
+static tree build_incomplete_class_ref (int, tree);
+static tree patch_incomplete_class_ref (tree);
+static tree create_anonymous_class (int, tree);
+static void patch_anonymous_class (tree, tree, tree);
+static void add_inner_class_fields (tree, tree);
+
+static tree build_dot_class_method (tree);
+static tree build_dot_class_method_invocation (tree);
+static void create_new_parser_context (int);
+static tree maybe_build_class_init_for_field (tree, tree);
+
+static int attach_init_test_initialization_flags (PTR *, PTR);
+static int emit_test_initialization (PTR *, PTR);
+
+static char *string_convert_int_cst (tree);
 
 /* Number of error found so far. */
-int java_error_count; 
+int java_error_count;
 /* Number of warning found so far. */
 int java_warning_count;
 /* Tell when not to fold, when doing xrefs */
 int do_not_fold;
 /* Cyclic inheritance report, as it can be set by layout_class */
 const char *cyclic_inheritance_report;
+
 /* The current parser context */
 struct parser_ctxt *ctxp;
 
@@ -359,10 +351,10 @@ struct parser_ctxt *ctxp_for_generation = NULL;
    covers both integral/floating point division. The code is changed
    once the type of both operator is worked out.  */
 
-static enum tree_code binop_lookup[19] = 
-  { 
+static const enum tree_code binop_lookup[19] =
+  {
     PLUS_EXPR, MINUS_EXPR, MULT_EXPR, RDIV_EXPR, TRUNC_MOD_EXPR,
-    LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR, 
+    LSHIFT_EXPR, RSHIFT_EXPR, URSHIFT_EXPR,
     BIT_AND_EXPR, BIT_XOR_EXPR, BIT_IOR_EXPR,
     TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR,
     EQ_EXPR, NE_EXPR, GT_EXPR, GE_EXPR, LT_EXPR, LE_EXPR,
@@ -375,54 +367,52 @@ static enum tree_code binop_lookup[19] =
 #define BINOP_COMPOUND_CANDIDATES 11
 
 /* The "$L" identifier we use to create labels.  */
-static tree label_id = NULL_TREE;
+static GTY(()) tree label_id;
 
 /* The "StringBuffer" identifier used for the String `+' operator. */
-static tree wfl_string_buffer = NULL_TREE; 
+static GTY(()) tree wfl_string_buffer;
 
 /* The "append" identifier used for String `+' operator.  */
-static tree wfl_append = NULL_TREE;
+static GTY(()) tree wfl_append;
 
 /* The "toString" identifier used for String `+' operator. */
-static tree wfl_to_string = NULL_TREE;
+static GTY(()) tree wfl_to_string;
 
 /* The "java.lang" import qualified name.  */
-static tree java_lang_id = NULL_TREE;
+static GTY(()) tree java_lang_id;
 
 /* The generated `inst$' identifier used for generated enclosing
    instance/field access functions.  */
-static tree inst_id = NULL_TREE;
-
-/* The "java.lang.Cloneable" qualified name.  */
-static tree java_lang_cloneable = NULL_TREE;
-
-/* The "java.io.Serializable" qualified name.  */
-static tree java_io_serializable = NULL_TREE; 
+static GTY(()) tree inst_id;
 
 /* Context and flag for static blocks */
-static tree current_static_block = NULL_TREE;
+static GTY(()) tree current_static_block;
 
 /* The generated `write_parm_value$' identifier.  */
-static tree wpv_id;
+static GTY(()) tree wpv_id;
 
 /* The list of all packages we've seen so far */
-static tree package_list = NULL_TREE;
+static GTY(()) tree package_list;
+
 /* Hold THIS for the scope of the current method decl.  */
-static tree current_this;
+static GTY(()) tree current_this;
 
 /* Hold a list of catch clauses list. The first element of this list is
    the list of the catch clauses of the currently analysed try block. */
-static tree currently_caught_type_list;
+static GTY(()) tree currently_caught_type_list;
 
 /* This holds a linked list of all the case labels for the current
    switch statement.  It is only used when checking to see if there
    are duplicate labels.  FIXME: probably this should just be attached
    to the switch itself; then it could be referenced via
    `ctxp->current_loop'.  */
-static tree case_label_list; 
+static GTY(()) tree case_label_list;
 
-static tree src_parse_roots[1] = { NULL_TREE };
+/* Anonymous class counter. Will be reset to 1 every time a non
+   anonymous class gets created. */
+static int anonymous_class_counter = 1;
+
+static GTY(()) tree src_parse_roots[1];
 
 /* All classes seen from source code */
 #define gclass_list src_parse_roots[0]
@@ -435,8 +425,8 @@ static tree src_parse_roots[1] = { NULL_TREE };
 #define check_modifiers(__message, __value, __mask) do {       \
   if ((__value) & ~(__mask))                                   \
     {                                                          \
-      int i, remainder = (__value) & ~(__mask);                        \
-      for (i = 0; i <= 10; i++)                                        \
+      size_t i, remainder = (__value) & ~(__mask);             \
+      for (i = 0; i < ARRAY_SIZE (ctxp->modifier_ctx); i++)    \
         if ((1 << i) & remainder)                              \
          parse_error_context (ctxp->modifier_ctx [i], (__message), \
                               java_accstring_lookup (1 << i)); \
@@ -467,13 +457,13 @@ static tree src_parse_roots[1] = { NULL_TREE };
 %token   PLUS_TK         MINUS_TK        MULT_TK         DIV_TK    REM_TK
 %token   LS_TK           SRS_TK          ZRS_TK
 %token   AND_TK          XOR_TK          OR_TK
-%token   BOOL_AND_TK BOOL_OR_TK 
+%token   BOOL_AND_TK BOOL_OR_TK
 %token   EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
 
 /* This maps to the same binop_lookup entry than the token above */
 
 %token   PLUS_ASSIGN_TK  MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
-%token   REM_ASSIGN_TK   
+%token   REM_ASSIGN_TK
 %token   LS_ASSIGN_TK    SRS_ASSIGN_TK   ZRS_ASSIGN_TK
 %token   AND_ASSIGN_TK   XOR_ASSIGN_TK   OR_ASSIGN_TK
 
@@ -483,8 +473,8 @@ static tree src_parse_roots[1] = { NULL_TREE };
 %token   PUBLIC_TK       PRIVATE_TK         PROTECTED_TK
 %token   STATIC_TK       FINAL_TK           SYNCHRONIZED_TK
 %token   VOLATILE_TK     TRANSIENT_TK       NATIVE_TK
-%token   PAD_TK          ABSTRACT_TK        MODIFIER_TK
-%token   STRICT_TK
+%token   PAD_TK          ABSTRACT_TK        STRICT_TK
+%token   MODIFIER_TK
 
 /* Keep those two in order, too */
 %token   DECR_TK INCR_TK
@@ -493,7 +483,7 @@ static tree src_parse_roots[1] = { NULL_TREE };
 
 %token   DEFAULT_TK      IF_TK              THROW_TK
 %token   BOOLEAN_TK      DO_TK              IMPLEMENTS_TK
-%token   THROWS_TK       BREAK_TK           IMPORT_TK       
+%token   THROWS_TK       BREAK_TK           IMPORT_TK
 %token   ELSE_TK         INSTANCEOF_TK      RETURN_TK
 %token   VOID_TK         CATCH_TK           INTERFACE_TK
 %token   CASE_TK         EXTENDS_TK         FINALLY_TK
@@ -501,6 +491,7 @@ static tree src_parse_roots[1] = { NULL_TREE };
 %token   SWITCH_TK       CONST_TK           TRY_TK
 %token   FOR_TK          NEW_TK             CONTINUE_TK
 %token   GOTO_TK         PACKAGE_TK         THIS_TK
+%token   ASSERT_TK
 
 %token   BYTE_TK         SHORT_TK           INT_TK            LONG_TK
 %token   CHAR_TK         INTEGRAL_TK
@@ -524,12 +515,11 @@ static tree src_parse_roots[1] = { NULL_TREE };
 %type   <node>         type_declaration compilation_unit
                        field_declaration method_declaration extends_interfaces
                         interfaces interface_type_list
-                        class_member_declaration
-                        import_declarations package_declaration 
+                        import_declarations package_declaration
                         type_declarations interface_body
                        interface_member_declaration constant_declaration
                        interface_member_declarations interface_type
-                       abstract_method_declaration interface_type_list
+                       abstract_method_declaration
 %type   <node>         class_body_declaration class_member_declaration
                        static_initializer constructor_declaration block
 %type   <node>         class_body_declarations constructor_header
@@ -554,41 +544,42 @@ static tree src_parse_roots[1] = { NULL_TREE };
                        array_creation_expression array_type
                        class_instance_creation_expression field_access
                        method_invocation array_access something_dot_new
-                       argument_list postfix_expression while_expression 
+                       argument_list postfix_expression while_expression
                        post_increment_expression post_decrement_expression
                        unary_expression_not_plus_minus unary_expression
                        pre_increment_expression pre_decrement_expression
-                       unary_expression_not_plus_minus cast_expression
+                       cast_expression
                        multiplicative_expression additive_expression
-                       shift_expression relational_expression 
-                       equality_expression and_expression 
+                       shift_expression relational_expression
+                       equality_expression and_expression
                        exclusive_or_expression inclusive_or_expression
                        conditional_and_expression conditional_or_expression
                        conditional_expression assignment_expression
                        left_hand_side assignment for_header for_begin
                        constant_expression do_statement_begin empty_statement
                        switch_statement synchronized_statement throw_statement
-                       try_statement switch_expression switch_block
+                       try_statement assert_statement
+                       switch_expression switch_block
                        catches catch_clause catch_clause_parameter finally
                        anonymous_class_creation trap_overflow_corner_case
 %type    <node>         return_statement break_statement continue_statement
 
-%type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK  
+%type    <operator>     ASSIGN_TK      MULT_ASSIGN_TK  DIV_ASSIGN_TK
 %type    <operator>     REM_ASSIGN_TK  PLUS_ASSIGN_TK  MINUS_ASSIGN_TK
 %type    <operator>     LS_ASSIGN_TK   SRS_ASSIGN_TK   ZRS_ASSIGN_TK
 %type    <operator>     AND_ASSIGN_TK  XOR_ASSIGN_TK   OR_ASSIGN_TK
 %type    <operator>     ASSIGN_ANY_TK  assignment_operator
-%token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK 
+%token   <operator>     EQ_TK GTE_TK ZRS_TK SRS_TK GT_TK LTE_TK LS_TK
 %token   <operator>     BOOL_AND_TK AND_TK BOOL_OR_TK OR_TK INCR_TK PLUS_TK
 %token   <operator>     DECR_TK MINUS_TK MULT_TK DIV_TK XOR_TK REM_TK NEQ_TK
 %token   <operator>     NEG_TK REL_QM_TK REL_CL_TK NOT_TK LT_TK OCB_TK CCB_TK
 %token   <operator>     OP_TK OSB_TK DOT_TK THROW_TK INSTANCEOF_TK
-%type    <operator>    THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK 
+%type    <operator>    THIS_TK SUPER_TK RETURN_TK BREAK_TK CONTINUE_TK
 %type   <operator>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
-%type   <operator>     NEW_TK
+%type   <operator>     NEW_TK ASSERT_TK
+
+%type   <node>         method_body
 
-%type   <node>         method_body 
-       
 %type    <node>                literal INT_LIT_TK FP_LIT_TK BOOL_LIT_TK CHAR_LIT_TK
                        STRING_LIT_TK NULL_TK VOID_TK
 
@@ -597,7 +588,7 @@ static tree src_parse_roots[1] = { NULL_TREE };
 %type    <node>         formal_parameter_list formal_parameter
                         method_declarator method_header
 
-%type   <node>         primitive_type reference_type type 
+%type   <node>         primitive_type reference_type type
                        BOOLEAN_TK INTEGRAL_TK FP_TK
 
 /* Added or modified JDK 1.1 rule types  */
@@ -605,32 +596,7 @@ static tree src_parse_roots[1] = { NULL_TREE };
 
 %%
 /* 19.2 Production from 2.3: The Syntactic Grammar  */
-goal:
-                {
-                 /* Register static variables with the garbage
-                    collector.  */
-                 ggc_add_tree_root (&label_id, 1);
-                 ggc_add_tree_root (&wfl_string_buffer, 1);
-                 ggc_add_tree_root (&wfl_append, 1);
-                 ggc_add_tree_root (&wfl_to_string, 1);
-                 ggc_add_tree_root (&java_lang_id, 1);
-                 ggc_add_tree_root (&inst_id, 1);
-                 ggc_add_tree_root (&java_lang_cloneable, 1);
-                 ggc_add_tree_root (&java_io_serializable, 1);
-                 ggc_add_tree_root (&current_static_block, 1);
-                 ggc_add_tree_root (&wpv_id, 1);
-                 ggc_add_tree_root (&package_list, 1);
-                 ggc_add_tree_root (&current_this, 1);
-                 ggc_add_tree_root (&currently_caught_type_list, 1);
-                 ggc_add_tree_root (&case_label_list, 1);
-                 ggc_add_root (&ctxp, 1, 
-                               sizeof (struct parser_ctxt *),
-                               mark_parser_ctxt);
-                 ggc_add_root (&ctxp_for_generation, 1, 
-                               sizeof (struct parser_ctxt *),
-                               mark_parser_ctxt);
-               }
-       compilation_unit
+goal:  compilation_unit
                {}
 ;
 
@@ -675,7 +641,7 @@ interface_type:
 
 array_type:
        primitive_type dims
-               { 
+               {
                  int osb = pop_current_osb (ctxp);
                  tree t = build_java_array_type (($1), -1);
                  while (--osb)
@@ -683,7 +649,7 @@ array_type:
                  $$ = t;
                }
 |      name dims
-               { 
+               {
                  int osb = pop_current_osb (ctxp);
                  tree t = $1;
                  while (osb--)
@@ -741,7 +707,7 @@ type_declarations:
 
 package_declaration:
        PACKAGE_TK name SC_TK
-               { 
+               {
                  ctxp->package = EXPR_WFL_NODE ($2);
                  register_package (ctxp->package);
                }
@@ -775,7 +741,7 @@ single_type_import_declaration:
                      if (err && err != name)
                        parse_error_context
                          ($2, "Ambiguous class: `%s' and `%s'",
-                          IDENTIFIER_POINTER (name), 
+                          IDENTIFIER_POINTER (name),
                           IDENTIFIER_POINTER (err));
                      else
                        REGISTER_IMPORT ($2, last_name);
@@ -803,7 +769,7 @@ type_import_on_demand_declaration:
                  if (! it)
                    {
                      read_import_dir ($2);
-                     ctxp->import_demand_list = 
+                     ctxp->import_demand_list =
                        chainon (ctxp->import_demand_list,
                                 build_tree_list ($2, NULL_TREE));
                    }
@@ -839,7 +805,7 @@ modifiers:
                {
                  int acc = (1 << $2);
                  if ($$ & acc)
-                   parse_error_context 
+                   parse_error_context
                      (ctxp->modifier_ctx [$2], "Modifier `%s' declared twice",
                       java_accstring_lookup (acc));
                  else
@@ -854,20 +820,22 @@ class_declaration:
        modifiers CLASS_TK identifier super interfaces
                { create_class ($1, $3, $4, $5); }
        class_body
-|      CLASS_TK identifier super interfaces 
+               {;}
+|      CLASS_TK identifier super interfaces
                { create_class (0, $2, $3, $4); }
        class_body
+               {;}
 |      modifiers CLASS_TK error
-               {yyerror ("Missing class name"); RECOVER;}
+               { yyerror ("Missing class name"); RECOVER; }
 |      CLASS_TK error
-               {yyerror ("Missing class name"); RECOVER;}
+               { yyerror ("Missing class name"); RECOVER; }
 |       CLASS_TK identifier error
                {
-                 if (!ctxp->class_err) yyerror ("'{' expected"); 
+                 if (!ctxp->class_err) yyerror ("'{' expected");
                  DRECOVER(class1);
                }
 |       modifiers CLASS_TK identifier error
-               {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
+               { if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER; }
 ;
 
 super:
@@ -887,18 +855,18 @@ interfaces:
 |      IMPLEMENTS_TK error
                {
                  ctxp->class_err=1;
-                 yyerror ("Missing interface name"); 
+                 yyerror ("Missing interface name");
                }
 ;
 
 interface_type_list:
        interface_type
-               { 
+               {
                  ctxp->interface_number = 1;
                  $$ = build_tree_list ($1, NULL_TREE);
                }
 |      interface_type_list C_TK interface_type
-               { 
+               {
                  ctxp->interface_number++;
                  $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
                }
@@ -908,18 +876,18 @@ interface_type_list:
 
 class_body:
        OCB_TK CCB_TK
-               { 
+               {
                  /* Store the location of the `}' when doing xrefs */
                  if (flag_emit_xref)
-                   DECL_END_SOURCE_LINE (GET_CPC ()) = 
+                   DECL_END_SOURCE_LINE (GET_CPC ()) =
                      EXPR_WFL_ADD_COL ($2.location, 1);
                  $$ = GET_CPC ();
                }
 |      OCB_TK class_body_declarations CCB_TK
-               { 
+               {
                  /* Store the location of the `}' when doing xrefs */
                  if (flag_emit_xref)
-                   DECL_END_SOURCE_LINE (GET_CPC ()) = 
+                   DECL_END_SOURCE_LINE (GET_CPC ()) =
                      EXPR_WFL_ADD_COL ($3.location, 1);
                  $$ = GET_CPC ();
                }
@@ -960,7 +928,7 @@ field_declaration:
                { register_fields (0, $1, $2); }
 |      modifiers type variable_declarators SC_TK
                {
-                 check_modifiers 
+                 check_modifiers
                    ("Illegal modifier `%s' for field declaration",
                     $1, FIELD_MODIFIERS);
                  check_modifiers_consistency ($1);
@@ -981,10 +949,10 @@ variable_declarator:
        variable_declarator_id
                { $$ = build_tree_list ($1, NULL_TREE); }
 |      variable_declarator_id ASSIGN_TK variable_initializer
-               { 
+               {
                  if (java_error_count)
                    $3 = NULL_TREE;
-                 $$ = build_tree_list 
+                 $$ = build_tree_list
                    ($1, build_assignment ($2.token, $2.location, $1, $3));
                }
 |      variable_declarator_id ASSIGN_TK error
@@ -1008,13 +976,8 @@ variable_declarator_id:
 |      identifier error
                {yyerror ("Invalid declaration"); DRECOVER(vdi);}
 |      variable_declarator_id OSB_TK error
-               { 
-                 tree node = java_lval.node;
-                 if (node && (TREE_CODE (node) == INTEGER_CST
-                              || TREE_CODE (node) == EXPR_WITH_FILE_LOCATION))
-                   yyerror ("Can't specify array dimension in a declaration");
-                 else
-                   yyerror ("']' expected");
+               {
+                 yyerror ("']' expected");
                  DRECOVER(vdi);
                }
 |      variable_declarator_id CSB_TK error
@@ -1028,7 +991,7 @@ variable_initializer:
 
 /* 19.8.3 Productions from 8.4: Method Declarations  */
 method_declaration:
-       method_header 
+       method_header
                {
                  current_function_decl = $1;
                  if (current_function_decl
@@ -1043,7 +1006,7 @@ method_declaration:
                {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
 ;
 
-method_header: 
+method_header:
        type method_declarator throws
                { $$ = method_header (0, $1, $2, $3); }
 |      VOID_TK method_declarator throws
@@ -1058,11 +1021,20 @@ method_header:
                  RECOVER;
                }
 |      modifiers type error
-               {RECOVER;}
+               {
+                 yyerror ("Identifier expected");
+                 RECOVER;
+               }
 |      VOID_TK error
-               {yyerror ("Identifier expected"); RECOVER;}
+               {
+                 yyerror ("Identifier expected");
+                 RECOVER;
+               }
 |      modifiers VOID_TK error
-               {yyerror ("Identifier expected"); RECOVER;}
+               {
+                 yyerror ("Identifier expected");
+                 RECOVER;
+               }
 |      modifiers error
                {
                  yyerror ("Invalid method declaration, return type required");
@@ -1072,7 +1044,7 @@ method_header:
 
 method_declarator:
        identifier OP_TK CP_TK
-               { 
+               {
                  ctxp->formal_parameter_number = 0;
                  $$ = method_declarator ($1, NULL_TREE);
                }
@@ -1081,10 +1053,10 @@ method_declarator:
 |      method_declarator OSB_TK CSB_TK
                {
                  EXPR_WFL_LINECOL (wfl_operator) = $2.location;
-                 TREE_PURPOSE ($1) = 
+                 TREE_PURPOSE ($1) =
                    build_unresolved_array_type (TREE_PURPOSE ($1));
-                 parse_warning_context 
-                   (wfl_operator, 
+                 parse_warning_context
+                   (wfl_operator,
                     "Discouraged form of returned type specification");
                }
 |      identifier OP_TK error
@@ -1113,7 +1085,7 @@ formal_parameter:
                  $$ = build_tree_list ($2, $1);
                }
 |      final type variable_declarator_id /* Added, JDK1.1 final parms */
-               { 
+               {
                  $$ = build_tree_list ($3, $2);
                  ARG_FINAL_P ($$) = 1;
                }
@@ -1178,7 +1150,7 @@ static:                           /* Test lval.sub_token here */
                  /* Can't have a static initializer in an innerclass */
                  if ($1 | ACC_STATIC &&
                      GET_CPC_LIST () && !TOPLEVEL_CLASS_DECL_P (GET_CPC ()))
-                   parse_error_context 
+                   parse_error_context
                      (MODIFIER_WFL (STATIC_TK),
                       "Can't define static initializer in class `%s'. Static initializer can only be defined in top-level classes",
                       IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())));
@@ -1206,8 +1178,8 @@ constructor_header:
 
 constructor_declarator:
        simple_name OP_TK CP_TK
-               { 
-                 ctxp->formal_parameter_number = 0;  
+               {
+                 ctxp->formal_parameter_number = 0;
                  $$ = method_declarator ($1, NULL_TREE);
                }
 |      simple_name OP_TK formal_parameter_list CP_TK
@@ -1219,7 +1191,7 @@ constructor_body:
           body so we can safely perform all the required code
           addition (super invocation and field initialization) */
        block_begin constructor_block_end
-               { 
+               {
                  BLOCK_EXPR_BODY ($2) = empty_stmt_node;
                  $$ = $2;
                }
@@ -1238,14 +1210,14 @@ constructor_block_end:
 /* Error recovery for that rule moved down expression_statement: rule.  */
 explicit_constructor_invocation:
        this_or_super OP_TK CP_TK SC_TK
-               { 
-                 $$ = build_method_invocation ($1, NULL_TREE); 
+               {
+                 $$ = build_method_invocation ($1, NULL_TREE);
                  $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
                  $$ = java_method_add_stmt (current_function_decl, $$);
                }
 |      this_or_super OP_TK argument_list CP_TK SC_TK
-               { 
-                 $$ = build_method_invocation ($1, $3); 
+               {
+                 $$ = build_method_invocation ($1, $3);
                  $$ = build_debugable_stmt (EXPR_WFL_LINECOL ($1), $$);
                  $$ = java_method_add_stmt (current_function_decl, $$);
                }
@@ -1278,29 +1250,33 @@ interface_declaration:
        INTERFACE_TK identifier
                { create_interface (0, $2, NULL_TREE); }
        interface_body
+               { ; }
 |      modifiers INTERFACE_TK identifier
                { create_interface ($1, $3, NULL_TREE); }
        interface_body
+               { ; }
 |      INTERFACE_TK identifier extends_interfaces
                { create_interface (0, $2, $3); }
        interface_body
+               { ; }
 |      modifiers INTERFACE_TK identifier extends_interfaces
                { create_interface ($1, $3, $4); }
        interface_body
+               { ; }
 |      INTERFACE_TK identifier error
-               {yyerror ("'{' expected"); RECOVER;}
+               { yyerror ("'{' expected"); RECOVER; }
 |      modifiers INTERFACE_TK identifier error
-               {yyerror ("'{' expected"); RECOVER;}
+               { yyerror ("'{' expected"); RECOVER; }
 ;
 
 extends_interfaces:
        EXTENDS_TK interface_type
-               { 
+               {
                  ctxp->interface_number = 1;
                  $$ = build_tree_list ($2, NULL_TREE);
                }
 |      extends_interfaces C_TK interface_type
-               { 
+               {
                  ctxp->interface_number++;
                  $$ = chainon ($1, build_tree_list ($3, NULL_TREE));
                }
@@ -1337,7 +1313,7 @@ constant_declaration:
 
 abstract_method_declaration:
        method_header SC_TK
-               { 
+               {
                  check_abstract_method_header ($1);
                  current_function_decl = NULL_TREE; /* FIXME ? */
                }
@@ -1359,8 +1335,8 @@ array_initializer:
 
 variable_initializers:
        variable_initializer
-               { 
-                 $$ = tree_cons (maybe_build_array_element_wfl ($1), 
+               {
+                 $$ = tree_cons (maybe_build_array_element_wfl ($1),
                                  $1, NULL_TREE);
                }
 |      variable_initializers C_TK variable_initializer
@@ -1374,12 +1350,12 @@ variable_initializers:
 /* 19.11 Production from 14: Blocks and Statements  */
 block:
        OCB_TK CCB_TK
-               { 
+               {
                  /* Store the location of the `}' when doing xrefs */
                  if (current_function_decl && flag_emit_xref)
-                   DECL_END_SOURCE_LINE (current_function_decl) = 
+                   DECL_END_SOURCE_LINE (current_function_decl) =
                      EXPR_WFL_ADD_COL ($2.location, 1);
-                 $$ = empty_stmt_node; 
+                 $$ = empty_stmt_node;
                }
 |      block_begin block_statements block_end
                { $$ = $3; }
@@ -1392,12 +1368,12 @@ block_begin:
 
 block_end:
        CCB_TK
-               { 
+               {
                  maybe_absorb_scoping_blocks ();
                  /* Store the location of the `}' when doing xrefs */
                  if (current_function_decl && flag_emit_xref)
-                   DECL_END_SOURCE_LINE (current_function_decl) = 
-                     EXPR_WFL_ADD_COL ($1.location, 1);                  
+                   DECL_END_SOURCE_LINE (current_function_decl) =
+                     EXPR_WFL_ADD_COL ($1.location, 1);
                  $$ = exit_block ();
                  if (!BLOCK_SUBBLOCKS ($$))
                    BLOCK_SUBBLOCKS ($$) = empty_stmt_node;
@@ -1414,7 +1390,7 @@ block_statement:
 |      statement
                { java_method_add_stmt (current_function_decl, $1); }
 |      class_declaration       /* Added, JDK1.1 local classes */
-               { 
+               {
                  LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
                  end_class_declaration (1);
                }
@@ -1462,18 +1438,19 @@ statement_without_trailing_substatement:
 |      synchronized_statement
 |      throw_statement
 |      try_statement
+|      assert_statement
 ;
 
 empty_statement:
        SC_TK
-               { 
-                 if (flag_extraneous_semicolon 
-                     && ! current_static_block 
-                     && (! current_function_decl || 
+               {
+                 if (flag_extraneous_semicolon
+                     && ! current_static_block
+                     && (! current_function_decl ||
                          /* Verify we're not in a inner class declaration */
                          (GET_CPC () != TYPE_NAME
                           (DECL_CONTEXT (current_function_decl)))))
-                          
+
                    {
                      EXPR_WFL_SET_LINECOL (wfl_operator, lineno, -1);
                      parse_warning_context (wfl_operator, "An empty declaration is a deprecated feature that should not be used");
@@ -1485,7 +1462,7 @@ empty_statement:
 label_decl:
        identifier REL_CL_TK
                {
-                 $$ = build_labeled_block (EXPR_WFL_LINECOL ($1), 
+                 $$ = build_labeled_block (EXPR_WFL_LINECOL ($1),
                                            EXPR_WFL_NODE ($1));
                  pushlevel (2);
                  push_labeled_block ($$);
@@ -1517,7 +1494,7 @@ expression_statement:
                      info to be eventually generate here. */
                  $$ = JAVA_MAYBE_GENERATE_DEBUG_INFO ($$);
                }
-|      error SC_TK 
+|      error SC_TK
                {
                  YYNOT_TWICE yyerror ("Invalid expression statement");
                  DRECOVER (expr_stmt);
@@ -1558,7 +1535,7 @@ expression_statement:
                {yyerror ("';' expected"); RECOVER;}
 ;
 
-statement_expression: 
+statement_expression:
        assignment
 |      pre_increment_expression
 |      pre_decrement_expression
@@ -1570,8 +1547,8 @@ statement_expression:
 
 if_then_statement:
        IF_TK OP_TK expression CP_TK statement
-               { 
-                 $$ = build_if_else_statement ($2.location, $3, 
+               {
+                 $$ = build_if_else_statement ($2.location, $3,
                                                $5, NULL_TREE);
                }
 |      IF_TK error
@@ -1598,9 +1575,9 @@ switch_statement:
                  enter_block ();
                }
        switch_block
-               { 
+               {
                  /* Make into "proper list" of COMPOUND_EXPRs.
-                    I.e. make the last statment also have its own
+                    I.e. make the last statement also have its own
                     COMPOUND_EXPR. */
                  maybe_absorb_scoping_blocks ();
                  TREE_OPERAND ($1, 1) = exit_block ();
@@ -1610,7 +1587,7 @@ switch_statement:
 
 switch_expression:
        SWITCH_TK OP_TK expression CP_TK
-               { 
+               {
                  $$ = build (SWITCH_EXPR, NULL_TREE, $3, NULL_TREE);
                  EXPR_WFL_LINECOL ($$) = $2.location;
                }
@@ -1636,7 +1613,7 @@ switch_block:
                { $$ = NULL_TREE; }
 ;
 
-switch_block_statement_groups: 
+switch_block_statement_groups:
        switch_block_statement_group
 |      switch_block_statement_groups switch_block_statement_group
 ;
@@ -1652,13 +1629,13 @@ switch_labels:
 
 switch_label:
        CASE_TK constant_expression REL_CL_TK
-               { 
+               {
                  tree lab = build1 (CASE_EXPR, NULL_TREE, $2);
                  EXPR_WFL_LINECOL (lab) = $1.location;
                  java_method_add_stmt (current_function_decl, lab);
                }
 |      DEFAULT_TK REL_CL_TK
-               { 
+               {
                  tree lab = build (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
                  EXPR_WFL_LINECOL (lab) = $1.location;
                  java_method_add_stmt (current_function_decl, lab);
@@ -1673,7 +1650,7 @@ switch_label:
 
 while_expression:
        WHILE_TK OP_TK expression CP_TK
-               { 
+               {
                  tree body = build_loop_body ($2.location, $3, 0);
                  $$ = build_new_loop (body);
                }
@@ -1697,14 +1674,14 @@ while_statement_nsi:
 
 do_statement_begin:
        DO_TK
-               { 
+               {
                  tree body = build_loop_body (0, NULL_TREE, 1);
                  $$ = build_new_loop (body);
                }
        /* Need error handing here. FIXME */
 ;
 
-do_statement: 
+do_statement:
        do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
                { $$ = finish_loop_body ($4.location, $5, $2, 1); }
 ;
@@ -1717,10 +1694,10 @@ for_statement:
                  $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);
                }
 |      for_begin SC_TK SC_TK for_update CP_TK statement
-               { 
+               {
                  $$ = finish_for_loop (0, NULL_TREE, $4, $6);
                  /* We have not condition, so we get rid of the EXIT_EXPR */
-                 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
+                 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
                    empty_stmt_node;
                }
 |      for_begin SC_TK error
@@ -1735,20 +1712,20 @@ for_statement_nsi:
        for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
                { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
 |      for_begin SC_TK SC_TK for_update CP_TK statement_nsi
-               { 
+               {
                  $$ = finish_for_loop (0, NULL_TREE, $4, $6);
                  /* We have not condition, so we get rid of the EXIT_EXPR */
-                 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) = 
+                 LOOP_EXPR_BODY_CONDITION_EXPR (LOOP_EXPR_BODY ($$), 0) =
                    empty_stmt_node;
                }
 ;
 
 for_header:
        FOR_TK OP_TK
-               { 
+               {
                  /* This scope defined for local variable that may be
                      defined within the scope of the for loop */
-                 enter_block (); 
+                 enter_block ();
                }
 |      FOR_TK error
                {yyerror ("'(' expected"); DRECOVER(for_1);}
@@ -1758,7 +1735,7 @@ for_header:
 
 for_begin:
        for_header for_init
-               { 
+               {
                  /* We now declare the loop body. The loop is
                      declared as a for loop. */
                  tree body = build_loop_body (0, NULL_TREE, 0);
@@ -1772,13 +1749,13 @@ for_begin:
 for_init:                      /* Can be empty */
                { $$ = empty_stmt_node; }
 |      statement_expression_list
-               { 
+               {
                  /* Init statement recorded within the previously
                      defined block scope */
                  $$ = java_method_add_stmt (current_function_decl, $1);
                }
 |      local_variable_declaration
-               { 
+               {
                  /* Local variable are recorded within the previously
                     defined block scope */
                  $$ = NULL_TREE;
@@ -1837,7 +1814,7 @@ return_statement:
 
 throw_statement:
        THROW_TK expression SC_TK
-               { 
+               {
                  $$ = build1 (THROW_EXPR, NULL_TREE, $2);
                  EXPR_WFL_LINECOL ($$) = $1.location;
                }
@@ -1847,11 +1824,26 @@ throw_statement:
                {yyerror ("';' expected"); RECOVER;}
 ;
 
+assert_statement:
+       ASSERT_TK expression REL_CL_TK expression SC_TK
+               {
+                 $$ = build_assertion ($1.location, $2, $4);
+               }
+|      ASSERT_TK expression SC_TK
+               {
+                 $$ = build_assertion ($1.location, $2, NULL_TREE);
+               }
+|      ASSERT_TK error
+               {yyerror ("Missing term"); RECOVER;}
+|      ASSERT_TK expression error
+               {yyerror ("';' expected"); RECOVER;}
+;
+
 synchronized_statement:
        synchronized OP_TK expression CP_TK block
-               { 
+               {
                  $$ = build (SYNCHRONIZED_EXPR, NULL_TREE, $3, $5);
-                 EXPR_WFL_LINECOL ($$) = 
+                 EXPR_WFL_LINECOL ($$) =
                    EXPR_WFL_LINECOL (MODIFIER_WFL (SYNCHRONIZED_TK));
                }
 |      synchronized OP_TK expression CP_TK error
@@ -1871,7 +1863,7 @@ synchronized:
              "Illegal modifier `%s'. Only `synchronized' was expected here",
                                   $1, ACC_SYNCHRONIZED);
                  if ($1 != ACC_SYNCHRONIZED)
-                   MODIFIER_WFL (SYNCHRONIZED_TK) = 
+                   MODIFIER_WFL (SYNCHRONIZED_TK) =
                      build_wfl_node (NULL_TREE);
                }
 ;
@@ -1882,7 +1874,7 @@ try_statement:
 |      TRY_TK block finally
                { $$ = build_try_finally_statement ($1.location, $2, $3); }
 |      TRY_TK block catches finally
-               { $$ = build_try_finally_statement 
+               { $$ = build_try_finally_statement
                    ($1.location, build_try_statement ($1.location,
                                                       $2, $3), $4);
                }
@@ -1893,7 +1885,7 @@ try_statement:
 catches:
        catch_clause
 |      catches catch_clause
-               { 
+               {
                  TREE_CHAIN ($2) = $1;
                  $$ = $2;
                }
@@ -1901,22 +1893,23 @@ catches:
 
 catch_clause:
        catch_clause_parameter block
-               { 
+               {
                  java_method_add_stmt (current_function_decl, $2);
                  exit_block ();
                  $$ = $1;
                }
+;
 
 catch_clause_parameter:
        CATCH_TK OP_TK formal_parameter CP_TK
-               { 
+               {
                  /* We add a block to define a scope for
                     formal_parameter (CCBP). The formal parameter is
                     declared initialized by the appropriate function
                     call */
                  tree ccpb = enter_block ();
                  tree init = build_assignment
-                   (ASSIGN_TK, $2.location, TREE_PURPOSE ($3), 
+                   (ASSIGN_TK, $2.location, TREE_PURPOSE ($3),
                     build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
                  declare_local_variables (0, TREE_VALUE ($3),
                                           build_tree_list (TREE_PURPOSE ($3),
@@ -1926,9 +1919,9 @@ catch_clause_parameter:
                }
 |      CATCH_TK error
                {yyerror ("'(' expected"); RECOVER; $$ = NULL_TREE;}
-|      CATCH_TK OP_TK error 
+|      CATCH_TK OP_TK error
                {
-                 yyerror ("Missing term or ')' expected"); 
+                 yyerror ("Missing term or ')' expected");
                  RECOVER; $$ = NULL_TREE;
                }
 |      CATCH_TK OP_TK error CP_TK /* That's for () */
@@ -1963,11 +1956,11 @@ primary_no_new_array:
            refering to a 'ClassName' (class_name) rule that doesn't
            exist. Used name: instead.  */
 |      name DOT_TK THIS_TK
-               { 
+               {
                  tree wfl = build_wfl_node (this_identifier_node);
                  $$ = make_qualified_primary ($1, wfl, EXPR_WFL_LINECOL ($1));
                }
-|      OP_TK expression error 
+|      OP_TK expression error
                {yyerror ("')' expected"); RECOVER;}
 |      name DOT_TK error
                {yyerror ("'class' or 'this' expected" ); RECOVER;}
@@ -1985,7 +1978,7 @@ type_literals:
 |      primitive_type DOT_TK CLASS_TK
                 { $$ = build_incomplete_class_ref ($2.location, $1); }
 |      VOID_TK DOT_TK CLASS_TK
-                { 
+                {
                    $$ = build_incomplete_class_ref ($2.location,
                                                    void_type_node);
                 }
@@ -2001,20 +1994,20 @@ class_instance_creation_expression:
           primary instead of primary solely which couldn't work in
           all situations.  */
 |      something_dot_new identifier OP_TK CP_TK
-               { 
+               {
                  tree ctor = build_new_invocation ($2, NULL_TREE);
-                 $$ = make_qualified_primary ($1, ctor, 
+                 $$ = make_qualified_primary ($1, ctor,
                                               EXPR_WFL_LINECOL ($1));
                }
 |      something_dot_new identifier OP_TK CP_TK class_body
 |      something_dot_new identifier OP_TK argument_list CP_TK
-               { 
+               {
                  tree ctor = build_new_invocation ($2, $4);
-                 $$ = make_qualified_primary ($1, ctor, 
+                 $$ = make_qualified_primary ($1, ctor,
                                               EXPR_WFL_LINECOL ($1));
                }
 |      something_dot_new identifier OP_TK argument_list CP_TK class_body
-|      NEW_TK error SC_TK 
+|      NEW_TK error SC_TK
                {yyerror ("'(' expected"); DRECOVER(new_1);}
 |      NEW_TK class_type error
                {yyerror ("'(' expected"); RECOVER;}
@@ -2034,10 +2027,10 @@ class_instance_creation_expression:
    in the documentation but doesn't exist. */
 
 anonymous_class_creation:
-       NEW_TK class_type OP_TK argument_list CP_TK 
+       NEW_TK class_type OP_TK argument_list CP_TK
                { create_anonymous_class ($1.location, $2); }
         class_body
-               { 
+               {
                  tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
                  EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
 
@@ -2059,7 +2052,7 @@ anonymous_class_creation:
                     must be generated following the hints provided by
                     the `new' expression. Whether a super constructor
                     of that nature exists or not is to be verified
-                    later on in verify_constructor_super. 
+                    later on in verify_constructor_super.
 
                     It's during the expansion of a `new' statement
                     refering to an anonymous class that a ctor will
@@ -2067,10 +2060,10 @@ anonymous_class_creation:
                     right arguments. */
 
                }
-|      NEW_TK class_type OP_TK CP_TK 
+|      NEW_TK class_type OP_TK CP_TK
                { create_anonymous_class ($1.location, $2); }
-        class_body         
-               { 
+        class_body
+               {
                  tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
                  EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL ($2);
 
@@ -2093,9 +2086,9 @@ something_dot_new:                /* Added, not part of the specs. */
 
 argument_list:
        expression
-               { 
+               {
                  $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
-                 ctxp->formal_parameter_number = 1; 
+                 ctxp->formal_parameter_number = 1;
                }
 |      argument_list C_TK expression
                {
@@ -2129,12 +2122,12 @@ array_creation_expression:
                              $2, get_identifier (sig), $4);
                }
 |      NEW_TK primitive_type dims array_initializer
-               { 
+               {
                  int osb = pop_current_osb (ctxp);
                  tree type = $2;
                  while (osb--)
                    type = build_java_array_type (type, -1);
-                 $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE, 
+                 $$ = build (NEW_ANONYMOUS_ARRAY_EXPR, NULL_TREE,
                              build_pointer_type (type), NULL_TREE, $4);
                }
 |      NEW_TK error CSB_TK
@@ -2152,7 +2145,7 @@ dim_exprs:
 
 dim_expr:
        OSB_TK expression CSB_TK
-               { 
+               {
                  if (JNUMERIC_TYPE_P (TREE_TYPE ($2)))
                    {
                      $2 = build_wfl_node ($2);
@@ -2171,9 +2164,9 @@ dim_expr:
                }
 ;
 
-dims:                          
+dims:
        OSB_TK CSB_TK
-               { 
+               {
                  int allocate = 0;
                  /* If not initialized, allocate memory for the osb
                      numbers stack */
@@ -2185,7 +2178,7 @@ dims:
                  /* If capacity overflown, reallocate a bigger chunk */
                  else if (ctxp->osb_depth+1 == ctxp->osb_limit)
                    allocate = ctxp->osb_limit << 1;
-                 
+
                  if (allocate)
                    {
                      allocate *= sizeof (int);
@@ -2207,7 +2200,7 @@ dims:
 field_access:
        primary DOT_TK identifier
                { $$ = make_qualified_primary ($1, $3, $2.location); }
-               /*  FIXME - REWRITE TO: 
+               /*  FIXME - REWRITE TO:
                { $$ = build_binop (COMPONENT_REF, $2.location, $1, $3); } */
 |      SUPER_TK DOT_TK identifier
                {
@@ -2225,9 +2218,9 @@ method_invocation:
 |      name OP_TK argument_list CP_TK
                { $$ = build_method_invocation ($1, $3); }
 |      primary DOT_TK identifier OP_TK CP_TK
-               { 
+               {
                  if (TREE_CODE ($1) == THIS_EXPR)
-                   $$ = build_this_super_qualified_invocation 
+                   $$ = build_this_super_qualified_invocation
                      (1, $3, NULL_TREE, 0, $2.location);
                  else
                    {
@@ -2236,9 +2229,9 @@ method_invocation:
                    }
                }
 |      primary DOT_TK identifier OP_TK argument_list CP_TK
-               { 
+               {
                  if (TREE_CODE ($1) == THIS_EXPR)
-                   $$ = build_this_super_qualified_invocation 
+                   $$ = build_this_super_qualified_invocation
                      (1, $3, $5, 0, $2.location);
                  else
                    {
@@ -2247,13 +2240,13 @@ method_invocation:
                    }
                }
 |      SUPER_TK DOT_TK identifier OP_TK CP_TK
-               { 
-                 $$ = build_this_super_qualified_invocation 
+               {
+                 $$ = build_this_super_qualified_invocation
                    (0, $3, NULL_TREE, $1.location, $2.location);
                }
 |      SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
                {
-                 $$ = build_this_super_qualified_invocation 
+                 $$ = build_this_super_qualified_invocation
                    (0, $3, $5, $1.location, $2.location);
                }
         /* Screws up thing. I let it here until I'm convinced it can
@@ -2361,22 +2354,22 @@ unary_expression_not_plus_minus:
 
 cast_expression:               /* Error handling here is potentially weak */
        OP_TK primitive_type dims CP_TK unary_expression
-               { 
+               {
                  tree type = $2;
                  int osb = pop_current_osb (ctxp);
                  while (osb--)
                    type = build_java_array_type (type, -1);
-                 $$ = build_cast ($1.location, type, $5); 
+                 $$ = build_cast ($1.location, type, $5);
                }
 |      OP_TK primitive_type CP_TK unary_expression
                { $$ = build_cast ($1.location, $2, $4); }
 |      OP_TK expression CP_TK unary_expression_not_plus_minus
                { $$ = build_cast ($1.location, $2, $4); }
 |      OP_TK name dims CP_TK unary_expression_not_plus_minus
-               { 
+               {
                  const char *ptr;
-                 int osb = pop_current_osb (ctxp); 
-                 obstack_grow (&temporary_obstack, 
+                 int osb = pop_current_osb (ctxp);
+                 obstack_grow (&temporary_obstack,
                                IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
                                IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
                  while (osb--)
@@ -2404,19 +2397,19 @@ cast_expression:                /* Error handling here is potentially weak */
 multiplicative_expression:
        unary_expression
 |      multiplicative_expression MULT_TK unary_expression
-               { 
-                 $$ = build_binop (BINOP_LOOKUP ($2.token), 
+               {
+                 $$ = build_binop (BINOP_LOOKUP ($2.token),
                                    $2.location, $1, $3);
                }
 |      multiplicative_expression DIV_TK unary_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      multiplicative_expression REM_TK unary_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      multiplicative_expression MULT_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2431,12 +2424,12 @@ additive_expression:
 |      additive_expression PLUS_TK multiplicative_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      additive_expression MINUS_TK multiplicative_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      additive_expression PLUS_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2449,17 +2442,17 @@ shift_expression:
 |      shift_expression LS_TK additive_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      shift_expression SRS_TK additive_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      shift_expression ZRS_TK additive_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      shift_expression LS_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2474,22 +2467,22 @@ relational_expression:
 |      relational_expression LT_TK shift_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      relational_expression GT_TK shift_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      relational_expression LTE_TK shift_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      relational_expression GTE_TK shift_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      relational_expression INSTANCEOF_TK reference_type
                { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
@@ -2510,12 +2503,12 @@ equality_expression:
 |      equality_expression EQ_TK relational_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      equality_expression NEQ_TK relational_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      equality_expression EQ_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2528,7 +2521,7 @@ and_expression:
 |      and_expression AND_TK equality_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      and_expression AND_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2539,7 +2532,7 @@ exclusive_or_expression:
 |      exclusive_or_expression XOR_TK and_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      exclusive_or_expression XOR_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2550,7 +2543,7 @@ inclusive_or_expression:
 |      inclusive_or_expression OR_TK exclusive_or_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      inclusive_or_expression OR_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2561,7 +2554,7 @@ conditional_and_expression:
 |      conditional_and_expression BOOL_AND_TK inclusive_or_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      conditional_and_expression BOOL_AND_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2572,7 +2565,7 @@ conditional_or_expression:
 |      conditional_or_expression BOOL_OR_TK conditional_and_expression
                {
                  $$ = build_binop (BINOP_LOOKUP ($2.token), $2.location,
-                                   $1, $3); 
+                                   $1, $3);
                }
 |      conditional_or_expression BOOL_OR_TK error
                {yyerror ("Missing term"); RECOVER;}
@@ -2644,10 +2637,10 @@ pop_current_osb (ctxp)
 
   if (ctxp->osb_depth < 0)
     abort ();
-  
+
   to_return = CURRENT_OSB (ctxp);
   ctxp->osb_depth--;
-  
+
   return to_return;
 }
 
@@ -2657,7 +2650,7 @@ pop_current_osb (ctxp)
    Add mode documentation here. FIXME */
 
 /* Helper function. Create a new parser context. With
-   COPY_FROM_PREVIOUS set to a non zero value, content of the previous
+   COPY_FROM_PREVIOUS set to a nonzero value, content of the previous
    context is copied, otherwise, the new context is zeroed. The newly
    created context becomes the current one.  */
 
@@ -2667,7 +2660,7 @@ create_new_parser_context (copy_from_previous)
 {
   struct parser_ctxt *new;
 
-  new =  (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
+  new =  (struct parser_ctxt *) ggc_alloc (sizeof (struct parser_ctxt));
   if (copy_from_previous)
     {
       memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
@@ -2675,7 +2668,7 @@ create_new_parser_context (copy_from_previous)
     }
   else
     memset ((PTR) new, 0, sizeof (struct parser_ctxt));
-      
+
   new->next = ctxp;
   ctxp = new;
 }
@@ -2686,9 +2679,9 @@ void
 java_push_parser_context ()
 {
   create_new_parser_context (0);
-}  
+}
 
-void 
+void
 java_pop_parser_context (generate)
      int generate;
 {
@@ -2719,7 +2712,7 @@ java_pop_parser_context (generate)
   if ((ctxp = next))           /* Assignment is really meant here */
     for (current = ctxp->import_list; current; current = TREE_CHAIN (current))
       IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (TREE_VALUE (current)) = 1;
-  
+
   /* If we pushed a context to parse a class intended to be generated,
      we keep it so we can remember the class. What we could actually
      do is to just update a list of class names.  */
@@ -2728,8 +2721,6 @@ java_pop_parser_context (generate)
       toFree->next = ctxp_for_generation;
       ctxp_for_generation = toFree;
     }
-  else
-    free (toFree);
 }
 
 /* Create a parser context for the use of saving some global
@@ -2826,12 +2817,8 @@ java_parser_context_resume ()
   ctxp = restored;
 
   /* Re-installed the data for the parsing to carry on */
-  memcpy (&ctxp->marker_begining, &old->marker_begining, 
+  memcpy (&ctxp->marker_begining, &old->marker_begining,
          (size_t)(&ctxp->marker_end - &ctxp->marker_begining));
-
-  /* Buffer context can now be discarded */
-  free (saver);
-  free (old);
 }
 
 /* Add a new anchor node to which all statement(s) initializing static
@@ -2877,7 +2864,7 @@ java_parser_context_pop_initialized_field ()
   if (CPC_STATIC_INITIALIZER_LIST (ctxp))
     {
       stmts = CPC_STATIC_INITIALIZER_STMT (ctxp);
-      CPC_STATIC_INITIALIZER_LIST (ctxp) = 
+      CPC_STATIC_INITIALIZER_LIST (ctxp) =
        TREE_CHAIN (CPC_STATIC_INITIALIZER_LIST (ctxp));
       /* Keep initialization in order to enforce 8.5 */
       if (stmts && !java_error_count)
@@ -2888,7 +2875,7 @@ java_parser_context_pop_initialized_field ()
   if (CPC_INSTANCE_INITIALIZER_LIST (ctxp))
     {
       stmts = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
-      CPC_INSTANCE_INITIALIZER_LIST (ctxp) = 
+      CPC_INSTANCE_INITIALIZER_LIST (ctxp) =
        TREE_CHAIN (CPC_INSTANCE_INITIALIZER_LIST (ctxp));
       if (stmts && !java_error_count)
        TYPE_II_STMT_LIST (class_type) = nreverse (stmts);
@@ -2904,10 +2891,10 @@ reorder_static_initialized (list)
      keep them in lexical order. */
   tree marker, previous = NULL_TREE;
   for (marker = list; marker; previous = marker, marker = TREE_CHAIN (marker))
-    if (TREE_CODE (marker) == TREE_LIST 
+    if (TREE_CODE (marker) == TREE_LIST
        && !TREE_VALUE (marker) && !TREE_PURPOSE (marker))
       break;
-  
+
   /* No static initialized, the list is fine as is */
   if (!previous)
     list = TREE_CHAIN (marker);
@@ -2947,7 +2934,7 @@ java_debug_context_do (tab)
       fprintf (stderr, "lineno: %d\n", copy->lineno);
       TAB_CONTEXT (tab);
       fprintf (stderr, "package: %s\n",
-              (copy->package ? 
+              (copy->package ?
                IDENTIFIER_POINTER (copy->package) : "<none>"));
       TAB_CONTEXT (tab);
       fprintf (stderr, "context for saving: %d\n", copy->saved_data_ctx);
@@ -2980,7 +2967,7 @@ static void
 parse_ctor_invocation_error ()
 {
   if (DECL_CONSTRUCTOR_P (current_function_decl))
-    yyerror ("Constructor invocation must be first thing in a constructor"); 
+    yyerror ("Constructor invocation must be first thing in a constructor");
   else
     yyerror ("Only constructors can invoke constructors");
 }
@@ -3008,7 +2995,7 @@ yyerror (msg)
 
   int save_lineno;
   char *remainder, *code_from_source;
-  
+
   if (!force_error && prev_lineno == lineno)
     return;
 
@@ -3035,7 +3022,7 @@ yyerror (msg)
     java_warning_count++;
   else
     java_error_count++;
-  
+
   if (elc.col == 0 && msg && msg[1] == ';')
     {
       elc.col  = ctxp->p_line->char_col-1;
@@ -3047,7 +3034,7 @@ yyerror (msg)
   prev_msg = msg;
 
   code_from_source = java_get_line_col (ctxp->filename, elc.line, elc.col);
-  obstack_grow0 (&temporary_obstack, 
+  obstack_grow0 (&temporary_obstack,
                 code_from_source, strlen (code_from_source));
   remainder = obstack_finish (&temporary_obstack);
   if (do_warning)
@@ -3075,7 +3062,7 @@ issue_warning_error_from_context (cl, msg, ap)
   force_error = 1;
 
   ctxp->elc.line = EXPR_WFL_LINENO (cl);
-  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : 
+  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 :
                    (EXPR_WFL_COLNO (cl) == 0xffe ? -2 : EXPR_WFL_COLNO (cl)));
 
   /* We have a CL, that's a good reason for using it if it contains data */
@@ -3094,28 +3081,26 @@ issue_warning_error_from_context (cl, msg, ap)
 /* Issue an error message at a current source line CL */
 
 void
-parse_error_context VPARAMS ((tree cl, const char *msg, ...))
+parse_error_context (tree cl, const char *msg, ...)
 {
-  VA_OPEN (ap, msg);
-  VA_FIXEDARG (ap, tree, cl);
-  VA_FIXEDARG (ap, const char *, msg);
+  va_list ap;
+  va_start (ap, msg);
   issue_warning_error_from_context (cl, msg, ap);
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 /* Issue a warning at a current source line CL */
 
 static void
-parse_warning_context VPARAMS ((tree cl, const char *msg, ...))
+parse_warning_context (tree cl, const char *msg, ...)
 {
-  VA_OPEN (ap, msg);
-  VA_FIXEDARG (ap, tree, cl);
-  VA_FIXEDARG (ap, const char *, msg);
+  va_list ap;
+  va_start (ap, msg);
 
   force_error = do_warning = 1;
   issue_warning_error_from_context (cl, msg, ap);
   do_warning = force_error = 0;
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 
 static tree
@@ -3143,7 +3128,7 @@ find_expr_with_wfl (node)
        case LOOP_EXPR:
          node = TREE_OPERAND (node, 0);
          continue;
-         
+
        case LABELED_BLOCK_EXPR:
          node = TREE_OPERAND (node, 1);
          continue;
@@ -3196,7 +3181,7 @@ int
 java_report_errors ()
 {
   if (java_error_count)
-    fprintf (stderr, "%d error%s", 
+    fprintf (stderr, "%d error%s",
             java_error_count, (java_error_count == 1 ? "" : "s"));
   if (java_warning_count)
     fprintf (stderr, "%s%d warning%s", (java_error_count ? ", " : ""),
@@ -3240,8 +3225,8 @@ classitf_redefinition_error (context, id, decl, cl)
      const char *context;
      tree id, decl, cl;
 {
-  parse_error_context (cl, "%s `%s' already defined in %s:%d", 
-                      context, IDENTIFIER_POINTER (id), 
+  parse_error_context (cl, "%s `%s' already defined in %s:%d",
+                      context, IDENTIFIER_POINTER (id),
                       DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
   /* Here we should point out where its redefined. It's a unicode. FIXME */
 }
@@ -3260,7 +3245,7 @@ variable_redefinition_error (context, name, type, line)
     type_name = lang_printable_name (type, 0);
 
   parse_error_context (context,
-                      "Variable `%s' is already defined in this method and was declared `%s %s' at line %d", 
+                      "Variable `%s' is already defined in this method and was declared `%s %s' at line %d",
                       IDENTIFIER_POINTER (name),
                       type_name, IDENTIFIER_POINTER (name), line);
 }
@@ -3295,7 +3280,7 @@ build_array_from_name (type, type_wfl, name, ret_name)
 
   /* Eventually get more dims */
   more_dims = build_type_name_from_array_name (name, &name);
-  
+
   /* If we have, then craft a new type for this variable */
   if (more_dims)
     {
@@ -3390,9 +3375,9 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
   int uaaf = CLASS_MODIFIERS;  /* Usually allowed access flags */
 
   if (!quiet_flag)
-    fprintf (stderr, " %s%s %s", 
+    fprintf (stderr, " %s%s %s",
             (CPC_INNER_P () ? "inner" : ""),
-            (is_interface ? "interface" : "class"), 
+            (is_interface ? "interface" : "class"),
             IDENTIFIER_POINTER (qualified_name));
 
   /* Scope of an interface/class type name:
@@ -3402,7 +3387,7 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
       && (node = find_name_in_single_imports (raw_name))
       && !CPC_INNER_P ())
     {
-      parse_error_context 
+      parse_error_context
        (cl, "%s name `%s' clashes with imported type `%s'",
         (is_interface ? "Interface" : "Class"),
         IDENTIFIER_POINTER (raw_name), IDENTIFIER_POINTER (node));
@@ -3410,7 +3395,7 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
     }
   if (decl && CLASS_COMPLETE_P (decl))
     {
-      classitf_redefinition_error ((is_interface ? "Interface" : "Class"), 
+      classitf_redefinition_error ((is_interface ? "Interface" : "Class"),
                                   qualified_name, decl, cl);
       return 1;
     }
@@ -3424,18 +3409,17 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
     {
       const char *f;
 
-      /* Contains OS dependent assumption on path separator. FIXME */
-      for (f = &input_filename [strlen (input_filename)]; 
-          f != input_filename && f[0] != '/' && f[0] != DIR_SEPARATOR;
+      for (f = &input_filename [strlen (input_filename)];
+          f != input_filename && ! IS_DIR_SEPARATOR (f[0]);
           f--)
        ;
-      if (f[0] == '/' || f[0] == DIR_SEPARATOR)
+      if (IS_DIR_SEPARATOR (f[0]))
        f++;
-      if (strncmp (IDENTIFIER_POINTER (raw_name), 
+      if (strncmp (IDENTIFIER_POINTER (raw_name),
                   f , IDENTIFIER_LENGTH (raw_name)) ||
          f [IDENTIFIER_LENGTH (raw_name)] != '.')
        parse_error_context
-         (cl, "Public %s `%s' must be defined in a file called `%s.java'", 
+         (cl, "Public %s `%s' must be defined in a file called `%s.java'",
                             (is_interface ? "interface" : "class"),
                             IDENTIFIER_POINTER (qualified_name),
                             IDENTIFIER_POINTER (raw_name));
@@ -3450,7 +3434,7 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
         complaining a second time */
       if (CPC_INNER_P () && !TOPLEVEL_CLASS_DECL_P (GET_CPC()))
        {
-         parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes", 
+         parse_error_context (cl, "Inner class `%s' can't be static. Static classes can only occur in interfaces and top-level classes",
                               IDENTIFIER_POINTER (qualified_name));
          sca = ACC_STATIC;
        }
@@ -3478,14 +3462,14 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
        }
     }
 
-  if (is_interface) 
+  if (is_interface)
     {
       if (CPC_INNER_P ())
        uaaf = INTERFACE_INNER_MODIFIERS;
       else
        uaaf = INTERFACE_MODIFIERS;
-      
-      check_modifiers ("Illegal modifier `%s' for interface declaration", 
+
+      check_modifiers ("Illegal modifier `%s' for interface declaration",
                       flags, uaaf);
     }
   else
@@ -3496,30 +3480,28 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
   return 0;
 }
 
-static void
+/* Construct a nested class name.  If the final component starts with
+   a digit, return true.  Otherwise return false.  */
+static int
 make_nested_class_name (cpc_list)
      tree cpc_list;
 {
   tree name;
 
   if (!cpc_list)
-    return;
-  else
-    make_nested_class_name (TREE_CHAIN (cpc_list));
+    return 0;
+
+  make_nested_class_name (TREE_CHAIN (cpc_list));
 
   /* Pick the qualified name when dealing with the first upmost
      enclosing class */
-  name = (TREE_CHAIN (cpc_list) ? 
-         TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
+  name = (TREE_CHAIN (cpc_list)
+         TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
   obstack_grow (&temporary_obstack,
                IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
-  /* Why is NO_DOLLAR_IN_LABEL defined? */
-#if 0
-#ifdef NO_DOLLAR_IN_LABEL
-  internal_error ("Can't use '$' as a separator for inner classes");
-#endif
-#endif
   obstack_1grow (&temporary_obstack, '$');
+
+  return ISDIGIT (IDENTIFIER_POINTER (name)[0]);
 }
 
 /* Can't redefine a class already defined in an earlier scope. */
@@ -3530,11 +3512,11 @@ check_inner_class_redefinition (raw_name, cl)
 {
   tree scope_list;
 
-  for (scope_list = GET_CPC_LIST (); scope_list; 
+  for (scope_list = GET_CPC_LIST (); scope_list;
        scope_list = GET_NEXT_ENCLOSING_CPC (scope_list))
     if (raw_name == GET_CPC_UN_NODE (scope_list))
       {
-       parse_error_context 
+       parse_error_context
          (cl, "The class name `%s' is already defined in this scope. An inner class may not have the same simple name as any of its enclosing classes",
           IDENTIFIER_POINTER (raw_name));
        return 1;
@@ -3547,7 +3529,7 @@ check_inner_class_redefinition (raw_name, cl)
 
 static tree
 resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
-     struct hash_table *circularity_hash;
+     htab_t circularity_hash;
      tree cl, *enclosing, *super, class_type;
 {
   tree local_enclosing = *enclosing;
@@ -3557,8 +3539,8 @@ resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
     {
       tree intermediate, decl;
 
-      hash_lookup (circularity_hash, 
-                  (const  hash_table_key) local_enclosing, TRUE, NULL);
+      *htab_find_slot (circularity_hash, local_enclosing, INSERT) =
+       local_enclosing;
 
       if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
        return decl;
@@ -3586,12 +3568,11 @@ resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
 
       /* We may not have checked for circular inheritance yet, so do so
          here to prevent an infinite loop. */
-      if (hash_lookup (circularity_hash,
-                      (const hash_table_key) local_super, FALSE, NULL))
+      if (htab_find (circularity_hash, local_super) != NULL)
         {
           if (!cl)
             cl = lookup_cl (local_enclosing);
-         
+
           parse_error_context
             (cl, "Cyclic inheritance involving %s",
             IDENTIFIER_POINTER (DECL_NAME (local_enclosing)));
@@ -3628,7 +3609,7 @@ find_as_inner_class (enclosing, name, cl)
     qual = build_tree_list (cl, NULL_TREE);
   else
     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
-  
+
   if ((to_return = find_as_inner_class_do (qual, enclosing)))
     return to_return;
 
@@ -3638,10 +3619,10 @@ find_as_inner_class (enclosing, name, cl)
     {
       tree acc = NULL_TREE, decl = NULL_TREE, ptr;
 
-      for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl; 
+      for (qual = EXPR_WFL_QUALIFICATION (cl); qual && !decl;
           qual = TREE_CHAIN (qual))
        {
-         acc = merge_qualified_name (acc, 
+         acc = merge_qualified_name (acc,
                                      EXPR_WFL_NODE (TREE_PURPOSE (qual)));
          BUILD_PTR_FROM_NAME (ptr, acc);
          decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
@@ -3649,7 +3630,7 @@ find_as_inner_class (enclosing, name, cl)
 
       /* A NULL qual and a decl means that the search ended
          successfully?!? We have to do something then. FIXME */
-      
+
       if (decl)
        enclosing = decl;
       else
@@ -3658,7 +3639,7 @@ find_as_inner_class (enclosing, name, cl)
   /* Otherwise, create a qual for the other part of the resolution. */
   else
     qual = build_tree_list (build_expr_wfl (name, NULL, 0, 0), NULL_TREE);
-  
+
   return find_as_inner_class_do (qual, enclosing);
 }
 
@@ -3704,7 +3685,7 @@ set_nested_class_simple_name_value (outer, set)
   tree l;
 
   for (l = DECL_INNER_CLASS_LIST (outer); l; l = TREE_CHAIN (l))
-    IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ? 
+    IDENTIFIER_GLOBAL_VALUE (TREE_VALUE (l)) = (set ?
                                                TREE_PURPOSE (l) : NULL_TREE);
 }
 
@@ -3714,10 +3695,9 @@ link_nested_class_to_enclosing ()
   if (GET_ENCLOSING_CPC ())
     {
       tree enclosing = GET_ENCLOSING_CPC_CONTEXT ();
-      DECL_INNER_CLASS_LIST (enclosing) = 
+      DECL_INNER_CLASS_LIST (enclosing) =
        tree_cons (GET_CPC (), GET_CPC_UN (),
                   DECL_INNER_CLASS_LIST (enclosing));
-      enclosing = enclosing;
     }
 }
 
@@ -3729,9 +3709,22 @@ maybe_make_nested_class_name (name)
 
   if (CPC_INNER_P ())
     {
-      make_nested_class_name (GET_CPC_LIST ());
+      /* If we're in a function, we must append a number to create the
+        nested class name.  However, we don't do this if the class we
+        are constructing is anonymous, because in that case we'll
+        already have a number as the class name.  */
+      if (! make_nested_class_name (GET_CPC_LIST ())
+         && current_function_decl != NULL_TREE
+         && ! ISDIGIT (IDENTIFIER_POINTER (name)[0]))
+       {
+         char buf[10];
+         sprintf (buf, "%d", anonymous_class_counter);
+         ++anonymous_class_counter;
+         obstack_grow (&temporary_obstack, buf, strlen (buf));
+         obstack_1grow (&temporary_obstack, '$');
+       }
       obstack_grow0 (&temporary_obstack,
-                    IDENTIFIER_POINTER (name), 
+                    IDENTIFIER_POINTER (name),
                     IDENTIFIER_LENGTH (name));
       id = get_identifier (obstack_finish (&temporary_obstack));
       if (ctxp->package)
@@ -3776,7 +3769,7 @@ maybe_create_class_interface_decl (decl, raw_name, qualified_name, cl)
   /* Install a new dependency list element */
   create_jdep_list (ctxp);
 
-  SOURCE_FRONTEND_DEBUG (("Defining class/interface %s", 
+  SOURCE_FRONTEND_DEBUG (("Defining class/interface %s",
                          IDENTIFIER_POINTER (qualified_name)));
   return decl;
 }
@@ -3827,7 +3820,7 @@ create_interface (flags, id, super)
 
   EXPR_WFL_NODE (id) = q_name; /* Keep source location, even if refined. */
 
-  /* Basic checks: scope, redefinition, modifiers */ 
+  /* Basic checks: scope, redefinition, modifiers */
   if (check_class_interface_creation (1, flags, raw_name, q_name, decl, id))
     {
       PUSH_ERROR ();
@@ -3852,15 +3845,15 @@ create_interface (flags, id, super)
        - abstract is obsolete (comes first, it's a warning, or should be)
        - Can't use twice the same (checked in the modifier rule) */
   if ((flags & ACC_ABSTRACT) && flag_redundant)
-    parse_warning_context 
+    parse_warning_context
       (MODIFIER_WFL (ABSTRACT_TK),
-       "Redundant use of `abstract' modifier. Interface `%s' is implicitely abstract", IDENTIFIER_POINTER (raw_name));
+       "Redundant use of `abstract' modifier. Interface `%s' is implicitly abstract", IDENTIFIER_POINTER (raw_name));
 
   /* Create a new decl if DECL is NULL, otherwise fix it */
   decl = maybe_create_class_interface_decl (decl, raw_name, q_name, id);
 
   /* Set super info and mark the class a complete */
-  set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl), 
+  set_super_info (ACC_INTERFACE | flags, TREE_TYPE (decl),
                  object_type_node, ctxp->interface_number);
   ctxp->interface_number = 0;
   CLASS_COMPLETE_P (decl) = 1;
@@ -3869,10 +3862,6 @@ create_interface (flags, id, super)
   return decl;
 }
 
-/* Anonymous class counter. Will be reset to 1 every time a non
-   anonymous class gets created. */
-static int anonymous_class_counter = 1;
-
 /* Patch anonymous class CLASS, by either extending or implementing
    DEP.  */
 
@@ -3977,7 +3966,7 @@ create_class (flags, id, super, interfaces)
       PUSH_ERROR ();
       return NULL_TREE;
     }
-  
+
   /* Suspend the current parsing context if we're parsing an inner
      class or an anonymous class. */
   if (CPC_INNER_P ())
@@ -3987,13 +3976,13 @@ create_class (flags, id, super, interfaces)
       if (CLASS_INTERFACE (GET_CPC ()))
        flags |= ACC_PUBLIC;
     }
-    
+
   /* Push a new context for (static) initialized upon declaration fields */
   java_parser_context_push_initialized_field ();
 
-  /* Class modifier check: 
+  /* Class modifier check:
        - Allowed modifier (already done at that point)
-       - abstract AND final forbidden 
+       - abstract AND final forbidden
        - Public classes defined in the correct file */
   if ((flags & ACC_ABSTRACT) && (flags & ACC_FINAL))
     parse_error_context
@@ -4013,7 +4002,7 @@ create_class (flags, id, super, interfaces)
          return NULL_TREE;
        }
 
-      super_decl_type = 
+      super_decl_type =
        register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
     }
   else if (TREE_TYPE (decl) != object_type_node)
@@ -4030,7 +4019,7 @@ create_class (flags, id, super, interfaces)
     }
 
   /* Set super info and mark the class as complete. */
-  set_super_info (flags, TREE_TYPE (decl), super_decl_type, 
+  set_super_info (flags, TREE_TYPE (decl), super_decl_type,
                  ctxp->interface_number);
   ctxp->interface_number = 0;
   CLASS_COMPLETE_P (decl) = 1;
@@ -4065,13 +4054,16 @@ static void
 end_class_declaration (resume)
      int resume;
 {
-  /* If an error occured, context weren't pushed and won't need to be
+  /* If an error occurred, context weren't pushed and won't need to be
      popped by a resume. */
-  int no_error_occured = ctxp->next && GET_CPC () != error_mark_node;
+  int no_error_occurred = ctxp->next && GET_CPC () != error_mark_node;
+
+  if (GET_CPC () != error_mark_node)
+    dump_java_tree (TDI_class, GET_CPC ());
 
   java_parser_context_pop_initialized_field ();
   POP_CPC ();
-  if (resume && no_error_occured)
+  if (resume && no_error_occurred)
     java_parser_context_resume ();
 
   /* We're ending a class declaration, this is a good time to reset
@@ -4091,14 +4083,14 @@ add_inner_class_fields (class_decl, fct_decl)
 
   f = add_field (TREE_TYPE (class_decl),
                 build_current_thisn (TREE_TYPE (class_decl)),
-                build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))), 
+                build_pointer_type (TREE_TYPE (DECL_CONTEXT (class_decl))),
                 ACC_PRIVATE);
   FIELD_THISN (f) = 1;
 
   if (!fct_decl)
     return;
-    
-  for (block = GET_CURRENT_BLOCK (fct_decl); 
+
+  for (block = GET_CURRENT_BLOCK (fct_decl);
        block && TREE_CODE (block) == BLOCK; block = BLOCK_SUPERCONTEXT (block))
     {
       tree decl;
@@ -4106,11 +4098,11 @@ add_inner_class_fields (class_decl, fct_decl)
        {
          tree name, pname;
          tree wfl, init, list;
-         
+
          /* Avoid non final arguments. */
          if (!LOCAL_FINAL_P (decl))
            continue;
-         
+
          MANGLE_OUTER_LOCAL_VARIABLE_NAME (name, DECL_NAME (decl));
          MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID (pname, DECL_NAME (decl));
          wfl = build_wfl_node (name);
@@ -4122,7 +4114,7 @@ add_inner_class_fields (class_decl, fct_decl)
             invoking it (hence the constructor will also feature a
             hidden parameter, set to the value of the outer context
             local at the time the inner class is created.)
-            
+
             Note: we take into account all possible locals that can
             be accessed by the inner class. It's actually not trivial
             to minimize these aliases down to the ones really
@@ -4137,14 +4129,14 @@ add_inner_class_fields (class_decl, fct_decl)
             identify locals really used in the inner class. We leave
             the flag FIELD_LOCAL_ALIAS_USED around for that future
             use.
-            
+
             On the other hand, it only affect local inner classes,
             whose constructors (and finit$ call) will be featuring
             unecessary arguments. It's easy for a developper to keep
             this number of parameter down by using the `final'
             keyword only when necessary. For the time being, we can
             issue a warning on unecessary finals. FIXME */
-         init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl), 
+         init = build_assignment (ASSIGN_TK, EXPR_WFL_LINECOL (wfl),
                                   wfl, init);
 
          /* Register the field. The TREE_LIST holding the part
@@ -4214,6 +4206,13 @@ lookup_field_wrapper (class, name)
       decl = lookup_field (&type, name);
     }
 
+  /* If the field still hasn't been found, try the next enclosing context. */
+  if (!decl && INNER_CLASS_TYPE_P (class))
+    {
+      tree outer_type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (class)));
+      decl = lookup_field_wrapper (outer_type, name);
+    }
+
   java_parser_context_restore_global ();
   return decl == error_mark_node ? NULL : decl;
 }
@@ -4231,19 +4230,19 @@ duplicate_declaration_error_p (new_field_name, new_type, cl)
   if (decl)
     {
       char *t1 = xstrdup (purify_type_name
-                        ((TREE_CODE (new_type) == POINTER_TYPE 
+                        ((TREE_CODE (new_type) == POINTER_TYPE
                           && TREE_TYPE (new_type) == NULL_TREE) ?
                          IDENTIFIER_POINTER (TYPE_NAME (new_type)) :
                          lang_printable_name (new_type, 1)));
       /* The type may not have been completed by the time we report
         the error */
       char *t2 = xstrdup (purify_type_name
-                        ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE 
+                        ((TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
                           && TREE_TYPE (TREE_TYPE (decl)) == NULL_TREE) ?
                          IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))) :
                          lang_printable_name (TREE_TYPE (decl), 1)));
-      parse_error_context 
-       (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)", 
+      parse_error_context
+       (cl , "Duplicate variable declaration: `%s %s' was `%s %s' (%s:%d)",
         t1, IDENTIFIER_POINTER (new_field_name),
         t2, IDENTIFIER_POINTER (DECL_NAME (decl)),
         DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
@@ -4296,7 +4295,7 @@ register_fields (flags, type, variable_list)
   /* If TYPE is fully resolved and we don't have a reference, make one */
   PROMOTE_RECORD_IF_COMPLETE (type, must_chain);
 
-  for (current = variable_list, saved_type = type; current; 
+  for (current = variable_list, saved_type = type; current;
        current = TREE_CHAIN (current), type = saved_type)
     {
       tree real_type;
@@ -4308,7 +4307,7 @@ register_fields (flags, type, variable_list)
       /* Can't declare non-final static fields in inner classes */
       if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (class_type)
           && !(flags & ACC_FINAL))
-       parse_error_context 
+       parse_error_context
           (cl, "Field `%s' can't be static in inner class `%s' unless it is final",
           IDENTIFIER_POINTER (EXPR_WFL_NODE (cl)),
           lang_printable_name (class_type, 0));
@@ -4362,11 +4361,11 @@ register_fields (flags, type, variable_list)
          FIELD_LOCAL_ALIAS (field_decl) = 1;
          FIELD_FINAL (field_decl) = 0;
        }
-      
+
       /* Check if we must chain. */
       if (must_chain)
        register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
-         
+
       /* If we have an initialization value tied to the field */
       if (init)
        {
@@ -4381,7 +4380,7 @@ register_fields (flags, type, variable_list)
                 appropriately. */
              TREE_CHAIN (init) = CPC_STATIC_INITIALIZER_STMT (ctxp);
              SET_CPC_STATIC_INITIALIZER_STMT (ctxp, init);
-             if (TREE_OPERAND (init, 1) 
+             if (TREE_OPERAND (init, 1)
                  && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
                TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
            }
@@ -4413,8 +4412,8 @@ generate_finit (class_type)
   tree list = TYPE_FINIT_STMT_LIST (class_type);
   tree mdecl, current, parms;
 
-  parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION, 
-                                                 class_type, NULL_TREE, 
+  parms = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
+                                                 class_type, NULL_TREE,
                                                  &count);
   CRAFTED_PARAM_LIST_FIXUP (parms);
   mdecl = create_artificial_method (class_type, ACC_PRIVATE, void_type_node,
@@ -4426,8 +4425,8 @@ generate_finit (class_type)
   start_artificial_method_body (mdecl);
 
   for (current = list; current; current = TREE_CHAIN (current))
-    java_method_add_stmt (mdecl, 
-                         build_debugable_stmt (EXPR_WFL_LINECOL (current), 
+    java_method_add_stmt (mdecl,
+                         build_debugable_stmt (EXPR_WFL_LINECOL (current),
                                                current));
   end_artificial_method_body (mdecl);
   return mdecl;
@@ -4456,7 +4455,7 @@ generate_instinit (class_type)
                       mdecl, NULL_TREE);
 
   /* Gather all the statements in a compound */
-  for (current = TYPE_II_STMT_LIST (class_type); 
+  for (current = TYPE_II_STMT_LIST (class_type);
        current; current = TREE_CHAIN (current))
     compound = add_stmt_to_compound (compound, NULL_TREE, current);
 
@@ -4465,10 +4464,10 @@ generate_instinit (class_type)
      We do that only if all ctors of CLASS_TYPE are set to catch a
      checked exception. This doesn't apply to anonymous classes (since
      they don't have declared ctors.) */
-  if (!ANONYMOUS_CLASS_P (class_type) && 
+  if (!ANONYMOUS_CLASS_P (class_type) &&
       ctors_unchecked_throws_clause_p (class_type))
     {
-      compound = encapsulate_with_try_catch (0, exception_type_node, compound, 
+      compound = encapsulate_with_try_catch (0, exception_type_node, compound,
                                             build1 (THROW_EXPR, NULL_TREE,
                                                     build_wfl_node (wpv_id)));
       DECL_FUNCTION_THROWS (mdecl) = build_tree_list (NULL_TREE,
@@ -4531,7 +4530,7 @@ method_header (flags, type, mdecl, throws)
     return error_mark_node;
   meth = TREE_VALUE (mdecl);
   id = TREE_PURPOSE (mdecl);
-  
+
   check_modifiers_consistency (flags);
 
   if (GET_CPC ())
@@ -4539,7 +4538,7 @@ method_header (flags, type, mdecl, throws)
 
   if (!this_class || this_class == error_mark_node)
     return NULL_TREE;
-  
+
   /* There are some forbidden modifiers for an abstract method and its
      class must be abstract as well.  */
   if (type && (flags & ACC_ABSTRACT))
@@ -4548,11 +4547,12 @@ method_header (flags, type, mdecl, throws)
       ABSTRACT_CHECK (flags, ACC_STATIC, id, "Static");
       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
-      ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
+      ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED, id, "Synchronized");
+      ABSTRACT_CHECK (flags, ACC_STRICT, id, "Strictfp");
       if (!CLASS_ABSTRACT (TYPE_NAME (this_class))
          && !CLASS_INTERFACE (TYPE_NAME (this_class)))
-       parse_error_context 
-         (id, "Class `%s' must be declared abstract to define abstract method `%s'", 
+       parse_error_context
+         (id, "Class `%s' must be declared abstract to define abstract method `%s'",
           IDENTIFIER_POINTER (DECL_NAME (GET_CPC ())),
           IDENTIFIER_POINTER (EXPR_WFL_NODE (id)));
     }
@@ -4564,7 +4564,7 @@ method_header (flags, type, mdecl, throws)
       /* 8.6: Constructor declarations: we might be trying to define a
          method without specifying a return type. */
       if (EXPR_WFL_NODE (id) != GET_CPC_UN ())
-       parse_error_context 
+       parse_error_context
          (id, "Invalid method declaration, return type required");
       /* 8.6.3: Constructor modifiers */
       else
@@ -4574,6 +4574,7 @@ method_header (flags, type, mdecl, throws)
          JCONSTRUCTOR_CHECK (flags, ACC_FINAL, id, "final");
          JCONSTRUCTOR_CHECK (flags, ACC_NATIVE, id, "native");
          JCONSTRUCTOR_CHECK (flags, ACC_SYNCHRONIZED, id, "synchronized");
+         JCONSTRUCTOR_CHECK (flags, ACC_STRICT, id, "strictfp");
        }
       /* If we found error here, we don't consider it's OK to tread
         the method definition as a constructor, for the rest of this
@@ -4602,7 +4603,7 @@ method_header (flags, type, mdecl, throws)
   /* Inner class can't declare static methods */
   if ((flags & ACC_STATIC) && !TOPLEVEL_CLASS_TYPE_P (this_class))
     {
-      parse_error_context 
+      parse_error_context
        (id, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
         IDENTIFIER_POINTER (EXPR_WFL_NODE (id)),
         lang_printable_name (this_class, 0));
@@ -4644,7 +4645,7 @@ method_header (flags, type, mdecl, throws)
   /* When defining an abstract or interface method, the curly
      bracket at level 1 doesn't exist because there is no function
      body */
-  lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
+  lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 :
            EXPR_WFL_LINENO (id));
 
   /* Remember the original argument list */
@@ -4665,7 +4666,7 @@ method_header (flags, type, mdecl, throws)
       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
     }
   else
-    meth = add_method (this_class, flags, meth_name, 
+    meth = add_method (this_class, flags, meth_name,
                       build_java_signature (meth));
 
   /* Remember final parameters */
@@ -4691,7 +4692,7 @@ method_header (flags, type, mdecl, throws)
        {
          register_incomplete_type (JDEP_EXCEPTION, TREE_VALUE (current),
                                    NULL_TREE, NULL_TREE);
-         JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) = 
+         JDEP_GET_PATCH (CLASSD_LAST (ctxp->classd_list)) =
            &TREE_VALUE (current);
        }
       DECL_FUNCTION_THROWS (meth) = throws;
@@ -4706,7 +4707,7 @@ method_header (flags, type, mdecl, throws)
       DECL_CONSTRUCTOR_P (meth) = 1;
       /* Compute and store the number of artificial parameters declared
         for this constructor */
-      for (count = 0, current = TYPE_FIELDS (this_class); current; 
+      for (count = 0, current = TYPE_FIELDS (this_class); current;
           current = TREE_CHAIN (current))
        if (FIELD_LOCAL_ALIAS (current))
          count++;
@@ -4759,7 +4760,7 @@ finish_method_declaration (method_body)
   if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
     {
       tree name = DECL_NAME (current_function_decl);
-      parse_error_context (DECL_FUNCTION_WFL (current_function_decl), 
+      parse_error_context (DECL_FUNCTION_WFL (current_function_decl),
                           "%s method `%s' can't have a body defined",
                           (METHOD_NATIVE (current_function_decl) ?
                            "Native" : "Abstract"),
@@ -4770,15 +4771,15 @@ finish_method_declaration (method_body)
     {
       tree name = DECL_NAME (current_function_decl);
       parse_error_context
-       (DECL_FUNCTION_WFL (current_function_decl), 
+       (DECL_FUNCTION_WFL (current_function_decl),
         "Non native and non abstract method `%s' must have a body defined",
         IDENTIFIER_POINTER (name));
       method_body = NULL_TREE;
     }
 
-  if (flag_emit_class_files && method_body 
-      && TREE_CODE (method_body) == NOP_EXPR 
-      && TREE_TYPE (current_function_decl) 
+  if (flag_emit_class_files && method_body
+      && TREE_CODE (method_body) == NOP_EXPR
+      && TREE_TYPE (current_function_decl)
       && TREE_TYPE (TREE_TYPE (current_function_decl)) == void_type_node)
     method_body = build1 (RETURN_EXPR, void_type_node, NULL);
 
@@ -4795,7 +4796,7 @@ finish_method_declaration (method_body)
      ARG_FINAL_P parameter that might have been set on some of this
      function parameters. */
   UNMARK_FINAL_PARMS (current_function_decl);
-  
+
   /* So we don't have an irrelevant function declaration context for
      the next static block we'll see. */
   current_function_decl = NULL_TREE;
@@ -4817,55 +4818,46 @@ constructor_circularity_msg (from, to)
 /* Verify a circular call to METH. Return 1 if an error is found, 0
    otherwise.  */
 
+static GTY(()) tree vcc_list;
 static int
 verify_constructor_circularity (meth, current)
      tree meth, current;
 {
-  static tree list = NULL_TREE;
-  static int initialized_p;
   tree c;
 
-  /* If we haven't already registered LIST with the garbage collector,
-     do so now.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&list, 1);
-      initialized_p = 1;
-    }
-
   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
     {
       if (TREE_VALUE (c) == meth)
        {
          char *t;
-         if (list)
+         if (vcc_list)
            {
              tree liste;
-             list = nreverse (list);
-             for (liste = list; liste; liste = TREE_CHAIN (liste))
+             vcc_list = nreverse (vcc_list);
+             for (liste = vcc_list; liste; liste = TREE_CHAIN (liste))
                {
-                 parse_error_context 
+                 parse_error_context
                    (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
                     constructor_circularity_msg
-                     (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste)))); 
+                     (TREE_VALUE (liste), TREE_VALUE (TREE_PURPOSE (liste))));
                  java_error_count--;
                }
            }
          t = xstrdup (lang_printable_name (meth, 0));
-         parse_error_context (TREE_PURPOSE (c), 
+         parse_error_context (TREE_PURPOSE (c),
                               "%s: recursive invocation of constructor `%s'",
                               constructor_circularity_msg (current, meth), t);
          free (t);
-         list = NULL_TREE;
+         vcc_list = NULL_TREE;
          return 1;
        }
     }
   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
     {
-      list = tree_cons (c, current, list);
+      vcc_list = tree_cons (c, current, vcc_list);
       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
        return 1;
-      list = TREE_CHAIN (list);
+      vcc_list = TREE_CHAIN (vcc_list);
     }
   return 0;
 }
@@ -4906,7 +4898,7 @@ check_abstract_method_header (meth)
   OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (ABSTRACT_TK), flags,
                              ACC_ABSTRACT, "abstract method",
                              IDENTIFIER_POINTER (DECL_NAME (meth)));
-  OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags, 
+  OBSOLETE_MODIFIER_WARNING2 (MODIFIER_WFL (PUBLIC_TK), flags,
                              ACC_PUBLIC, "abstract method",
                              IDENTIFIER_POINTER (DECL_NAME (meth)));
 
@@ -4936,13 +4928,13 @@ method_declarator (id, list)
      this$<n> decl in the name field of its parameter declaration.  We
      also might have to hide the outer context local alias
      initializers. Not done when the class is a toplevel class. */
-  if (PURE_INNER_CLASS_DECL_P (GET_CPC ()) 
+  if (PURE_INNER_CLASS_DECL_P (GET_CPC ())
       && EXPR_WFL_NODE (id) == GET_CPC_UN ())
     {
       tree aliases_list, type, thisn;
       /* First the aliases, linked to the regular parameters */
       aliases_list =
-       build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION, 
+       build_alias_initializer_parameter_list (AIPL_FUNCTION_DECLARATION,
                                                TREE_TYPE (GET_CPC ()),
                                                NULL_TREE, NULL);
       list = chainon (nreverse (aliases_list), list);
@@ -4953,7 +4945,7 @@ method_declarator (id, list)
       list = tree_cons (build_wfl_node (thisn), build_pointer_type (type),
                        list);
     }
-  
+
   for (current = list; current; current = TREE_CHAIN (current))
     {
       int must_chain = 0;
@@ -4996,7 +4988,7 @@ method_declarator (id, list)
       if (must_chain)
        {
          patch_stage = JDEP_METHOD;
-         type = register_incomplete_type (patch_stage, 
+         type = register_incomplete_type (patch_stage,
                                           type_wfl, wfl_name, type);
          jdep = CLASSD_LAST (ctxp->classd_list);
          JDEP_MISC (jdep) = id;
@@ -5006,7 +4998,7 @@ method_declarator (id, list)
       arg_node = build_tree_list (name, real_type);
       /* Remeber arguments declared final. */
       ARG_FINAL_P (arg_node) = ARG_FINAL_P (current);
-      
+
       if (jdep)
        JDEP_GET_PATCH (jdep) = &TREE_VALUE (arg_node);
       TREE_CHAIN (arg_node) = arg_types;
@@ -5021,7 +5013,7 @@ static int
 unresolved_type_p (wfl, returned)
      tree wfl;
      tree *returned;
-     
+
 {
   if (TREE_CODE (wfl) == EXPR_WITH_FILE_LOCATION)
     {
@@ -5056,7 +5048,7 @@ parser_qualified_classname (name)
 
   if (ctxp->package)
     return merge_qualified_name (ctxp->package, name);
-  else 
+  else
     return name;
 }
 
@@ -5072,17 +5064,17 @@ parser_check_super_interface (super_decl, this_decl, this_wfl)
   /* Has to be an interface */
   if (!CLASS_INTERFACE (super_decl))
     {
-      parse_error_context 
-       (this_wfl, "Can't use %s `%s' to implement/extend %s `%s'",
+      parse_error_context
+       (this_wfl, "%s `%s' can't implement/extend %s `%s'",
+        (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ?
+         "Interface" : "Class"),
+        IDENTIFIER_POINTER (DECL_NAME (this_decl)),
         (TYPE_ARRAY_P (super_type) ? "array" : "class"),
-        IDENTIFIER_POINTER (DECL_NAME (super_decl)),
-        (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (this_decl))) ? 
-         "interface" : "class"),
-        IDENTIFIER_POINTER (DECL_NAME (this_decl)));
+        IDENTIFIER_POINTER (DECL_NAME (super_decl)));
       return 1;
     }
 
-  /* Check top-level interface access. Inner classes are subject to member 
+  /* Check top-level interface access. Inner classes are subject to member
      access rules (6.6.1). */
   if (! INNER_CLASS_P (super_type)
       && check_pkg_class_access (DECL_NAME (super_decl),
@@ -5107,7 +5099,7 @@ parser_check_super (super_decl, this_decl, wfl)
   /* SUPER should be a CLASS (neither an array nor an interface) */
   if (TYPE_ARRAY_P (super_type) || CLASS_INTERFACE (TYPE_NAME (super_type)))
     {
-      parse_error_context 
+      parse_error_context
        (wfl, "Class `%s' can't subclass %s `%s'",
         IDENTIFIER_POINTER (DECL_NAME (this_decl)),
         (CLASS_INTERFACE (TYPE_NAME (super_type)) ? "interface" : "array"),
@@ -5127,7 +5119,7 @@ parser_check_super (super_decl, this_decl, wfl)
   if (! INNER_CLASS_P (super_type)
       && (check_pkg_class_access (DECL_NAME (super_decl), wfl, true)))
     return 1;
-  
+
   SOURCE_FRONTEND_DEBUG (("Completing class %s with %s",
                          IDENTIFIER_POINTER (DECL_NAME (this_decl)),
                          IDENTIFIER_POINTER (DECL_NAME (super_decl))));
@@ -5141,7 +5133,7 @@ static void
 create_jdep_list (ctxp)
      struct parser_ctxt *ctxp;
 {
-  jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));     
+  jdeplist *new = (jdeplist *)xmalloc (sizeof (jdeplist));
   new->first = new->last = NULL;
   new->next = ctxp->classd_list;
   ctxp->classd_list = new;
@@ -5178,7 +5170,9 @@ obtain_incomplete_type (type_name)
   else
     abort ();
 
+  /* Workaround from build_pointer_type for incomplete types.  */
   BUILD_PTR_FROM_NAME (ptr, name);
+  TYPE_MODE (ptr) = ptr_mode;
   layout_type (ptr);
 
   return ptr;
@@ -5211,7 +5205,7 @@ register_incomplete_type (kind, wfl, decl, ptr)
       && GET_ENCLOSING_CPC ())
     JDEP_ENCLOSING (new) = TREE_VALUE (GET_ENCLOSING_CPC ());
   else if (kind == JDEP_SUPER)
-    JDEP_ENCLOSING (new) = (GET_ENCLOSING_CPC () ? 
+    JDEP_ENCLOSING (new) = (GET_ENCLOSING_CPC () ?
                            TREE_VALUE (GET_ENCLOSING_CPC ()) : NULL_TREE);
   else
     JDEP_ENCLOSING (new) = GET_CPC ();
@@ -5241,14 +5235,23 @@ check_inner_circular_reference (source, target)
 
   if (!basetype_vec)
     return NULL_TREE;
-  
+
   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
     {
-      tree su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
+      tree su;
+
+      /* We can end up with a NULL_TREE or an incomplete type here if
+        we encountered previous type resolution errors. It's safe to
+        simply ignore these cases.  */
+      if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)
+       continue;
+      su = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
+      if (INCOMPLETE_TYPE_P (su))
+       continue;
 
       if (inherits_from_p (su, target))
        return lookup_cl (TYPE_NAME (su));
-      
+
       for (ctx = DECL_CONTEXT (TYPE_NAME (su)); ctx; ctx = DECL_CONTEXT (ctx))
        {
          /* An enclosing context shouldn't be TARGET */
@@ -5285,7 +5288,7 @@ check_circular_reference (type)
        return lookup_cl (TYPE_NAME (type));
       return NULL_TREE;
     }
-    
+
   for (i = 0; i < TREE_VEC_LENGTH (basetype_vec); i++)
     {
       tree vec_elt = TREE_VEC_ELT (basetype_vec, i);
@@ -5341,7 +5344,7 @@ build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
        switch (mode)
          {
          case AIPL_FUNCTION_DECLARATION:
-           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
+           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id,
                                                         &buffer [4]);
            purpose = build_wfl_node (mangled_id);
            if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE)
@@ -5357,7 +5360,7 @@ build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
            break;
 
          case AIPL_FUNCTION_FINIT_INVOCATION:
-           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id, 
+           MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR (mangled_id,
                                                         &buffer [4]);
            /* Now, this is wrong. purpose should always be the NAME
               of something and value its matching value (decl, type,
@@ -5390,7 +5393,7 @@ build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
       }
   if (additional_parms)
     {
-      if (ANONYMOUS_CLASS_P (class_type) 
+      if (ANONYMOUS_CLASS_P (class_type)
           && mode == AIPL_FUNCTION_CTOR_INVOCATION)
         additional_parms = nreverse (additional_parms);
       parm = chainon (additional_parms, parm);
@@ -5403,7 +5406,7 @@ build_alias_initializer_parameter_list (mode, class_type, parm, artificial)
    where found. ARGS is non NULL when a special signature must be
    enforced. This is the case for anonymous classes.  */
 
-static void
+static tree
 craft_constructor (class_decl, args)
      tree class_decl, args;
 {
@@ -5414,7 +5417,7 @@ craft_constructor (class_decl, args)
   int i = 0, artificial = 0;
   tree decl, ctor_name;
   char buffer [80];
-  
+
   /* The constructor name is <init> unless we're dealing with an
      anonymous class, in which case the name will be fixed after having
      be expanded. */
@@ -5434,7 +5437,7 @@ craft_constructor (class_decl, args)
       /* Some more arguments to be hidden here. The values of the local
         variables of the outer context that the inner class needs to see. */
       parm = build_alias_initializer_parameter_list (AIPL_FUNCTION_CREATION,
-                                                    class_type, parm, 
+                                                    class_type, parm,
                                                     &artificial);
     }
 
@@ -5446,12 +5449,13 @@ craft_constructor (class_decl, args)
     }
 
   CRAFTED_PARAM_LIST_FIXUP (parm);
-  decl = create_artificial_method (class_type, flags, void_type_node, 
+  decl = create_artificial_method (class_type, flags, void_type_node,
                                   ctor_name, parm);
   fix_method_argument_names (parm, decl);
   /* Now, mark the artificial parameters. */
   DECL_FUNCTION_NAP (decl) = artificial;
   DECL_FUNCTION_SYNTHETIC_CTOR (decl) = DECL_CONSTRUCTOR_P (decl) = 1;
+  return decl;
 }
 
 
@@ -5524,7 +5528,7 @@ jdep_resolve_class (dep)
                            JDEP_DECL (dep), JDEP_WFL (dep));
       JDEP_RESOLVED (dep, decl);
     }
-    
+
   if (!decl)
     complete_class_report_errors (dep);
   else if (PURE_INNER_CLASS_DECL_P (decl))
@@ -5554,12 +5558,12 @@ java_complete_class ()
   /* Process imports */
   process_imports ();
 
-  /* Rever things so we have the right order */
+  /* Reverse things so we have the right order */
   ctxp->class_list = nreverse (ctxp->class_list);
   ctxp->classd_list = reverse_jdep_list (ctxp);
 
-  for (cclassd = ctxp->classd_list, cclass = ctxp->class_list; 
-       cclass && cclassd; 
+  for (cclassd = ctxp->classd_list, cclass = ctxp->class_list;
+       cclass && cclassd;
        cclass = TREE_CHAIN (cclass), cclassd = CLASSD_CHAIN (cclassd))
     {
       jdep *dep;
@@ -5583,7 +5587,7 @@ java_complete_class ()
              /* Simply patch super */
              if (parser_check_super (decl, JDEP_DECL (dep), JDEP_WFL (dep)))
                continue;
-             BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO 
+             BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO
                (TREE_TYPE (JDEP_DECL (dep)))), 0)) = TREE_TYPE (decl);
              break;
 
@@ -5598,7 +5602,7 @@ java_complete_class ()
                DECL_ALIGN (field_decl) = 0;
                DECL_USER_ALIGN (field_decl) = 0;
                layout_decl (field_decl, 0);
-               SOURCE_FRONTEND_DEBUG 
+               SOURCE_FRONTEND_DEBUG
                  (("Completed field/var decl `%s' with `%s'",
                    IDENTIFIER_POINTER (DECL_NAME (field_decl)),
                    IDENTIFIER_POINTER (DECL_NAME (decl))));
@@ -5615,11 +5619,11 @@ java_complete_class ()
                      if (TREE_CODE (type) == RECORD_TYPE)
                        type = promote_type (type);
                      JDEP_APPLY_PATCH (dep, type);
-                     SOURCE_FRONTEND_DEBUG 
+                     SOURCE_FRONTEND_DEBUG
                        (((JDEP_KIND (dep) == JDEP_METHOD_RETURN ?
                           "Completing fct `%s' with ret type `%s'":
                           "Completing arg `%s' with type `%s'"),
-                         IDENTIFIER_POINTER (EXPR_WFL_NODE 
+                         IDENTIFIER_POINTER (EXPR_WFL_NODE
                                              (JDEP_DECL_WFL (dep))),
                          IDENTIFIER_POINTER (DECL_NAME (decl))));
                    }
@@ -5636,7 +5640,7 @@ java_complete_class ()
                  tree mdecl = JDEP_DECL (dep), signature;
                  /* Recompute and reset the signature, check first that
                     all types are now defined. If they're not,
-                    dont build the signature. */
+                    don't build the signature. */
                  if (check_method_types_complete (mdecl))
                    {
                      signature = build_java_signature (TREE_TYPE (mdecl));
@@ -5664,14 +5668,14 @@ java_complete_class ()
 
            case JDEP_TYPE:
              JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
-             SOURCE_FRONTEND_DEBUG 
+             SOURCE_FRONTEND_DEBUG
                (("Completing a random type dependency on a '%s' node",
                  tree_code_name [TREE_CODE (JDEP_DECL (dep))]));
              break;
 
            case JDEP_EXCEPTION:
              JDEP_APPLY_PATCH (dep, TREE_TYPE (decl));
-             SOURCE_FRONTEND_DEBUG 
+             SOURCE_FRONTEND_DEBUG
                (("Completing `%s' `throws' argument node",
                  IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep)))));
              break;
@@ -5699,7 +5703,7 @@ resolve_class (enclosing, class_type, decl, cl)
   tree resolved_type = TREE_TYPE (class_type);
   int array_dims = 0;
   tree resolved_type_decl;
-  
+
   if (resolved_type != NULL_TREE)
     {
       tree resolved_type_decl = TYPE_NAME (resolved_type);
@@ -5720,12 +5724,12 @@ resolve_class (enclosing, class_type, decl, cl)
     WFL_STRIP_BRACKET (cl, cl);
 
   /* 2- Resolve the bare type */
-  if (!(resolved_type_decl = do_resolve_class (enclosing, class_type, 
+  if (!(resolved_type_decl = do_resolve_class (enclosing, class_type,
                                               decl, cl)))
     return NULL_TREE;
   resolved_type = TREE_TYPE (resolved_type_decl);
 
-  /* 3- If we have and array, reconstruct the array down to its nesting */
+  /* 3- If we have an array, reconstruct the array down to its nesting */
   if (array_dims)
     {
       for (; array_dims; array_dims--)
@@ -5748,39 +5752,61 @@ do_resolve_class (enclosing, class_type, decl, cl)
 {
   tree new_class_decl = NULL_TREE, super = NULL_TREE;
   tree saved_enclosing_type = enclosing ? TREE_TYPE (enclosing) : NULL_TREE;
-  struct hash_table _ht, *circularity_hash = &_ht;
-
-  /* This hash table is used to register the classes we're going
-     through when searching the current class as an inner class, in
-     order to detect circular references. Remember to free it before
-     returning the section 0- of this function. */
-  hash_table_init (circularity_hash, hash_newfunc,
-                  java_hash_hash_tree_node, java_hash_compare_tree_node);
-
-  /* 0- Search in the current class as an inner class.
-     Maybe some code here should be added to load the class or
-     something, at least if the class isn't an inner class and ended
-     being loaded from class file. FIXME. */
-  while (enclosing)
-    {
-      new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing,
-                                           &super, class_type);
-      if (new_class_decl)
-       break;
+  tree decl_result;
+  htab_t circularity_hash;
 
-      /* If we haven't found anything because SUPER reached Object and
-        ENCLOSING happens to be an innerclass, try the enclosing context. */
-      if ((!super || super == object_type_node) && 
-         enclosing && INNER_CLASS_DECL_P (enclosing))
-       enclosing = DECL_CONTEXT (enclosing);
-      else
-       enclosing = NULL_TREE;
+  if (QUALIFIED_P (TYPE_NAME (class_type)))
+    {
+      /* If the type name is of the form `Q . Id', then Q is either a
+        package name or a class name.  First we try to find Q as a
+        class and then treat Id as a member type.  If we can't find Q
+        as a class then we fall through.  */
+      tree q, left, left_type, right;
+      breakdown_qualified (&left, &right, TYPE_NAME (class_type));
+      BUILD_PTR_FROM_NAME (left_type, left);
+      q = do_resolve_class (enclosing, left_type, decl, cl);
+      if (q)
+       {
+         enclosing = q;
+         saved_enclosing_type = TREE_TYPE (q);
+         BUILD_PTR_FROM_NAME (class_type, right);
+       }
     }
 
-  hash_table_free (circularity_hash);
+  if (enclosing)
+    {
+      /* This hash table is used to register the classes we're going
+        through when searching the current class as an inner class, in
+        order to detect circular references. Remember to free it before
+        returning the section 0- of this function. */
+      circularity_hash = htab_create (20, htab_hash_pointer, htab_eq_pointer,
+                                     NULL);
 
-  if (new_class_decl)
-    return new_class_decl;
+      /* 0- Search in the current class as an inner class.
+        Maybe some code here should be added to load the class or
+        something, at least if the class isn't an inner class and ended
+        being loaded from class file. FIXME. */
+      while (enclosing)
+       {
+         new_class_decl = resolve_inner_class (circularity_hash, cl, &enclosing,
+                                               &super, class_type);
+         if (new_class_decl)
+           break;
+
+         /* If we haven't found anything because SUPER reached Object and
+            ENCLOSING happens to be an innerclass, try the enclosing context. */
+         if ((!super || super == object_type_node) &&
+             enclosing && INNER_CLASS_DECL_P (enclosing))
+           enclosing = DECL_CONTEXT (enclosing);
+         else
+           enclosing = NULL_TREE;
+       }
+
+      htab_delete (circularity_hash);
+
+      if (new_class_decl)
+       return new_class_decl;
+    }
 
   /* 1- Check for the type in single imports. This will change
      TYPE_NAME() if something relevant is found */
@@ -5809,7 +5835,7 @@ do_resolve_class (enclosing, class_type, decl, cl)
     if (find_in_imports_on_demand (saved_enclosing_type, class_type))
       return NULL_TREE;
 
-  /* If found in find_in_imports_on_demant, the type has already been
+  /* If found in find_in_imports_on_demand, the type has already been
      loaded. */
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     return new_class_decl;
@@ -5821,22 +5847,22 @@ do_resolve_class (enclosing, class_type, decl, cl)
 
       /* If there is a current package (ctxp->package), it's the first
         element of package_list and we can skip it. */
-      for (package = (ctxp->package ? 
+      for (package = (ctxp->package ?
                      TREE_CHAIN (package_list) : package_list);
           package; package = TREE_CHAIN (package))
        if ((new_class_decl = qualify_and_find (class_type,
-                                              TREE_PURPOSE (package), 
+                                              TREE_PURPOSE (package),
                                               TYPE_NAME (class_type))))
          return new_class_decl;
     }
 
-  /* 5- Check an other compilation unit that bears the name of type */
+  /* 5- Check another compilation unit that bears the name of type */
   load_class (TYPE_NAME (class_type), 0);
-  
+
   if (!cl)
     cl = lookup_cl (decl);
-  
-  /* If we don't have a value for CL, then we're being called recursively. 
+
+  /* If we don't have a value for CL, then we're being called recursively.
      We can't check package access just yet, but it will be taken care of
      by the caller. */
   if (cl)
@@ -5844,9 +5870,34 @@ do_resolve_class (enclosing, class_type, decl, cl)
       if (check_pkg_class_access (TYPE_NAME (class_type), cl, true))
         return NULL_TREE;
     }
-  
+
   /* 6- Last call for a resolution */
-  return IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
+  decl_result = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type));
+
+  /* The final lookup might have registered a.b.c into a.b$c If we
+     failed at the first lookup, progressively change the name if
+     applicable and use the matching DECL instead. */
+  if (!decl_result && QUALIFIED_P (TYPE_NAME (class_type)))
+    {
+      char *separator;
+      tree name = TYPE_NAME (class_type);
+      char *namebuffer = alloca (IDENTIFIER_LENGTH (name) + 1);
+
+      strcpy (namebuffer, IDENTIFIER_POINTER (name));
+
+      do {
+
+       /* Reach the last '.', and if applicable, replace it by a `$' and
+          see if this exists as a type. */
+       if ((separator = strrchr (namebuffer, '.')))
+         {
+           *separator = '$';
+           name = get_identifier (namebuffer);
+           decl_result = IDENTIFIER_CLASS_VALUE (name);
+         }
+      } while (!decl_result && separator);
+    }
+  return decl_result;
 }
 
 static tree
@@ -5926,7 +5977,7 @@ resolve_and_layout (something, cl)
   /* Check methods */
   if (CLASS_FROM_SOURCE_P (decl_type))
     java_check_methods (decl);
-  /* Layout the type if necessary */ 
+  /* Layout the type if necessary */
   if (decl_type != current_class && !CLASS_LOADED_P (decl_type))
     safe_layout_class (decl_type);
 
@@ -5945,7 +5996,7 @@ resolve_no_layout (name, cl)
   java_parser_context_save_global ();
   decl = resolve_class (TYPE_NAME (current_class), ptr, NULL_TREE, cl);
   java_parser_context_restore_global ();
-  
+
   return decl;
 }
 
@@ -5985,7 +6036,7 @@ complete_class_report_errors (dep)
   switch (JDEP_KIND (dep))
     {
     case JDEP_SUPER:
-      parse_error_context  
+      parse_error_context
        (JDEP_WFL (dep), "Superclass `%s' of class `%s' not found",
         purify_type_name (name),
         IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
@@ -6005,7 +6056,7 @@ complete_class_report_errors (dep)
       break;
     case JDEP_METHOD_RETURN:   /* Covers return type */
       parse_error_context
-       (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'", 
+       (JDEP_WFL (dep), "Type `%s' not found in the declaration of the return type of method `%s'",
         purify_type_name (name),
         IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_DECL_WFL (dep))));
       break;
@@ -6018,13 +6069,13 @@ complete_class_report_errors (dep)
       break;
     case JDEP_VARIABLE:
       parse_error_context
-       (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'", 
-        purify_type_name (IDENTIFIER_POINTER 
+       (JDEP_WFL (dep), "Type `%s' not found in the declaration of the local variable `%s'",
+        purify_type_name (IDENTIFIER_POINTER
                           (EXPR_WFL_NODE (JDEP_WFL (dep)))),
         IDENTIFIER_POINTER (DECL_NAME (JDEP_DECL (dep))));
       break;
     case JDEP_EXCEPTION:       /* As specified by `throws' */
-      parse_error_context 
+      parse_error_context
          (JDEP_WFL (dep), "Class `%s' not found in `throws'",
         IDENTIFIER_POINTER (EXPR_WFL_NODE (JDEP_WFL (dep))));
       break;
@@ -6051,11 +6102,11 @@ get_printable_method_name (decl)
       name = DECL_NAME (decl);
       DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
     }
-      
+
   to_return = lang_printable_name (decl, 0);
   if (DECL_CONSTRUCTOR_P (decl))
     DECL_NAME (decl) = name;
-  
+
   return to_return;
 }
 
@@ -6083,7 +6134,7 @@ check_method_redefinition (class, method)
          && sig == TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (redef))
          && !DECL_ARTIFICIAL (method))
        {
-         parse_error_context 
+         parse_error_context
            (DECL_FUNCTION_WFL (method), "Duplicate %s declaration `%s'",
             (DECL_CONSTRUCTOR_P (redef) ? "constructor" : "method"),
             get_printable_method_name (redef));
@@ -6109,14 +6160,14 @@ check_abstract_method_definitions (do_interface, class_decl, type)
       tree other_super, other_method, method_sig, method_name;
       int found = 0;
       int end_type_reached = 0;
-      
+
       if (!METHOD_ABSTRACT (method) || METHOD_FINAL (method))
        continue;
-      
+
       /* Now verify that somewhere in between TYPE and CLASS,
         abstract method METHOD gets a non abstract definition
         that is inherited by CLASS.  */
-      
+
       method_sig = build_java_signature (TREE_TYPE (method));
       method_name = DECL_NAME (method);
       if (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION)
@@ -6126,14 +6177,14 @@ check_abstract_method_definitions (do_interface, class_decl, type)
       do {
        if (other_super == end_type)
          end_type_reached = 1;
-       
+
        /* Method search */
        for (other_method = TYPE_METHODS (other_super); other_method;
             other_method = TREE_CHAIN (other_method))
          {
            tree s = build_java_signature (TREE_TYPE (other_method));
            tree other_name = DECL_NAME (other_method);
-           
+
            if (TREE_CODE (other_name) == EXPR_WITH_FILE_LOCATION)
              other_name = EXPR_WFL_NODE (other_name);
            if (!DECL_CLINIT_P (other_method)
@@ -6148,21 +6199,21 @@ check_abstract_method_definitions (do_interface, class_decl, type)
          }
        other_super = CLASSTYPE_SUPER (other_super);
       } while (!end_type_reached);
+
       /* Report that abstract METHOD didn't find an implementation
         that CLASS can use. */
       if (!found)
        {
-         char *t = xstrdup (lang_printable_name 
+         char *t = xstrdup (lang_printable_name
                            (TREE_TYPE (TREE_TYPE (method)), 0));
          tree ccn = DECL_NAME (TYPE_NAME (DECL_CONTEXT (method)));
-         
-         parse_error_context 
+
+         parse_error_context
            (lookup_cl (class_decl),
             "Class `%s' doesn't define the abstract method `%s %s' from %s `%s'. This method must be defined or %s `%s' must be declared abstract",
             IDENTIFIER_POINTER (DECL_NAME (class_decl)),
-            t, lang_printable_name (method, 0), 
-            (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ? 
+            t, lang_printable_name (method, 0),
+            (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (method))) ?
              "interface" : "class"),
             IDENTIFIER_POINTER (ccn),
             (CLASS_INTERFACE (class_decl) ? "interface" : "class"),
@@ -6230,7 +6281,7 @@ check_method_types_complete (decl)
 
   if (!INCOMPLETE_TYPE_P (TREE_TYPE (type)))
     return 0;
-  
+
   args = TYPE_ARG_TYPES (type);
   if (TREE_CODE (type) == METHOD_TYPE)
     args = TREE_CHAIN (args);
@@ -6254,12 +6305,12 @@ java_check_methods (class_decl)
     java_check_abstract_methods (class_decl);
   else
     java_check_regular_methods (class_decl);
-  
+
   CLASS_METHOD_CHECKED_P (TREE_TYPE (class_decl)) = 1;
 }
 
 /* Check all the methods of CLASS_DECL. Methods are first completed
-   then checked according to regular method existance rules.  If no
+   then checked according to regular method existence rules.  If no
    constructor for CLASS_DECL were encountered, then build its
    declaration.  */
 
@@ -6269,7 +6320,7 @@ java_check_regular_methods (class_decl)
 {
   int saw_constructor = ANONYMOUS_CLASS_P (TREE_TYPE (class_decl));
   tree method;
-  tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
+  tree class = TREE_TYPE (class_decl);
   tree found = NULL_TREE;
   tree mthrows;
 
@@ -6306,9 +6357,9 @@ java_check_regular_methods (class_decl)
           mthrows; mthrows = TREE_CHAIN (mthrows))
        {
          if (!inherits_from_p (TREE_VALUE (mthrows), throwable_type_node))
-           parse_error_context 
+           parse_error_context
              (TREE_PURPOSE (mthrows), "Class `%s' in `throws' clause must be a subclass of class `java.lang.Throwable'",
-              IDENTIFIER_POINTER 
+              IDENTIFIER_POINTER
                 (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))));
        }
 
@@ -6319,7 +6370,7 @@ java_check_regular_methods (class_decl)
       if (METHOD_STATIC (method) && !TOPLEVEL_CLASS_DECL_P (class_decl))
        {
          char *t = xstrdup (lang_printable_name (class, 0));
-         parse_error_context 
+         parse_error_context
            (method_wfl, "Method `%s' can't be static in inner class `%s'. Only members of interfaces and top-level classes can be static",
             lang_printable_name (method, 0), t);
          free (t);
@@ -6336,7 +6387,7 @@ java_check_regular_methods (class_decl)
 
       /* If `found' is declared in an interface, make sure the
         modifier matches. */
-      if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found))) 
+      if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
          && clinit_identifier_node != DECL_NAME (found)
          && !METHOD_PUBLIC (method))
        {
@@ -6351,13 +6402,13 @@ java_check_regular_methods (class_decl)
         types. */
       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
        {
-         char *t = xstrdup 
+         char *t = xstrdup
            (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
-         parse_error_context 
+         parse_error_context
            (method_wfl,
-            "Method `%s' was defined with return type `%s' in class `%s'", 
+            "Method `%s' was defined with return type `%s' in class `%s'",
             lang_printable_name (found, 0), t,
-            IDENTIFIER_POINTER 
+            IDENTIFIER_POINTER
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          free (t);
        }
@@ -6370,7 +6421,7 @@ java_check_regular_methods (class_decl)
          /* Static *can* override static */
          if (METHOD_STATIC (found) && METHOD_STATIC (method))
            continue;
-         parse_error_context 
+         parse_error_context
            (method_wfl,
             "%s methods can't be overriden. Method `%s' is %s in class `%s'",
             (METHOD_FINAL (found) ? "Final" : "Static"),
@@ -6384,7 +6435,7 @@ java_check_regular_methods (class_decl)
       /* Static method can't override instance method. */
       if (METHOD_STATIC (method))
        {
-         parse_error_context 
+         parse_error_context
            (method_wfl,
             "Instance methods can't be overriden by a static method. Method `%s' is an instance method in class `%s'",
             lang_printable_name (found, 0),
@@ -6402,17 +6453,17 @@ java_check_regular_methods (class_decl)
            taken care of.  */
       if (!CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (found)))
          && ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method))
-             || (METHOD_PROTECTED (found) 
+             || (METHOD_PROTECTED (found)
                  && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
              || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
                  && METHOD_PRIVATE (method))))
        {
-         parse_error_context 
+         parse_error_context
            (method_wfl,
             "Methods can't be overridden to be more private. Method `%s' is not %s in class `%s'", lang_printable_name (method, 0),
-            (METHOD_PUBLIC (method) ? "public" : 
+            (METHOD_PUBLIC (method) ? "public" :
              (METHOD_PRIVATE (method) ? "private" : "protected")),
-            IDENTIFIER_POINTER (DECL_NAME 
+            IDENTIFIER_POINTER (DECL_NAME
                                 (TYPE_NAME (DECL_CONTEXT (found)))));
          continue;
        }
@@ -6423,7 +6474,7 @@ java_check_regular_methods (class_decl)
 
       /* Inheriting multiple methods with the same signature. FIXME */
     }
-  
+
   if (!TYPE_NVIRTUALS (class))
     TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
@@ -6435,7 +6486,7 @@ java_check_regular_methods (class_decl)
     abort ();
 }
 
-/* Return a non zero value if the `throws' clause of METHOD (if any)
+/* Return a nonzero value if the `throws' clause of METHOD (if any)
    is incompatible with the `throws' clause of FOUND (if any).  */
 
 static void
@@ -6455,17 +6506,17 @@ check_throws_clauses (method, method_wfl, found)
       if (IS_UNCHECKED_EXCEPTION_P (TREE_VALUE (mthrows)))
        continue;
       /* Checked expression must be compatible */
-      for (fthrows = DECL_FUNCTION_THROWS (found); 
+      for (fthrows = DECL_FUNCTION_THROWS (found);
           fthrows; fthrows = TREE_CHAIN (fthrows))
        if (inherits_from_p (TREE_VALUE (mthrows), TREE_VALUE (fthrows)))
          break;
       if (!fthrows)
        {
-         parse_error_context 
+         parse_error_context
            (method_wfl, "Invalid checked exception class `%s' in `throws' clause. The exception must be a subclass of an exception thrown by `%s' from class `%s'",
             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TREE_VALUE (mthrows)))),
             lang_printable_name (found, 0),
-            IDENTIFIER_POINTER 
+            IDENTIFIER_POINTER
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
        }
     }
@@ -6494,11 +6545,11 @@ java_check_abstract_methods (interface_decl)
        {
          char *t;
          t = xstrdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
-         parse_error_context 
+         parse_error_context
            (DECL_FUNCTION_WFL (found),
             "Method `%s' was defined with return type `%s' in class `%s'",
             lang_printable_name (found, 0), t,
-            IDENTIFIER_POINTER 
+            IDENTIFIER_POINTER
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          free (t);
          continue;
@@ -6516,23 +6567,23 @@ java_check_abstract_methods (interface_decl)
       if (!vec_elt)
        continue;
       sub_interface = BINFO_TYPE (vec_elt);
-      for (sub_interface_method = TYPE_METHODS (sub_interface); 
+      for (sub_interface_method = TYPE_METHODS (sub_interface);
           sub_interface_method;
           sub_interface_method = TREE_CHAIN (sub_interface_method))
        {
-         found = lookup_java_interface_method2 (interface, 
+         found = lookup_java_interface_method2 (interface,
                                                 sub_interface_method);
          if (found && (found != sub_interface_method))
            {
-             parse_error_context 
+             parse_error_context
                (lookup_cl (sub_interface_method),
                 "Interface `%s' inherits method `%s' from interface `%s'. This method is redefined with a different return type in interface `%s'",
                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
                 lang_printable_name (found, 0),
-                IDENTIFIER_POINTER 
-                  (DECL_NAME (TYPE_NAME 
+                IDENTIFIER_POINTER
+                  (DECL_NAME (TYPE_NAME
                               (DECL_CONTEXT (sub_interface_method)))),
-                IDENTIFIER_POINTER 
+                IDENTIFIER_POINTER
                   (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
            }
        }
@@ -6557,13 +6608,13 @@ lookup_java_interface_method2 (class, method_decl)
     {
       tree vec_elt = TREE_VEC_ELT (basetype_vec, i), to_return;
       if ((BINFO_TYPE (vec_elt) != object_type_node)
-         && (to_return = 
+         && (to_return =
              lookup_java_method2 (BINFO_TYPE (vec_elt), method_decl, 1)))
        return to_return;
     }
   for (i = 0; i < n; i++)
     {
-      to_return = lookup_java_interface_method2 
+      to_return = lookup_java_interface_method2
        (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)), method_decl);
       if (to_return)
        return to_return;
@@ -6584,7 +6635,7 @@ lookup_java_method2 (clas, method_decl, do_interface)
 
   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
   name = DECL_NAME (method_decl);
-  method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
+  method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
                 EXPR_WFL_NODE (name) : name);
   method_type = TREE_TYPE (TREE_TYPE (method_decl));
 
@@ -6597,7 +6648,7 @@ lookup_java_method2 (clas, method_decl, do_interface)
          tree name = DECL_NAME (method);
          if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
               EXPR_WFL_NODE (name) : name) == method_name
-             && method_sig == method_signature 
+             && method_sig == method_signature
              && TREE_TYPE (TREE_TYPE (method)) != method_type)
            return method;
        }
@@ -6609,34 +6660,33 @@ lookup_java_method2 (clas, method_decl, do_interface)
 /* Return the line that matches DECL line number, and try its best to
    position the column number. Used during error reports.  */
 
+static GTY(()) tree cl_v;
 static tree
 lookup_cl (decl)
      tree decl;
 {
-  static tree cl = NULL_TREE;
   char *line, *found;
-  
+
   if (!decl)
     return NULL_TREE;
 
-  if (cl == NULL_TREE)
+  if (cl_v == NULL_TREE)
     {
-      cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
-      ggc_add_tree_root (&cl, 1);
+      cl_v = build_expr_wfl (NULL_TREE, NULL, 0, 0);
     }
 
-  EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
-  EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
+  EXPR_WFL_FILENAME_NODE (cl_v) = get_identifier (DECL_SOURCE_FILE (decl));
+  EXPR_WFL_SET_LINECOL (cl_v, DECL_SOURCE_LINE_FIRST (decl), -1);
 
-  line = java_get_line_col (EXPR_WFL_FILENAME (cl), 
-                           EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
+  line = java_get_line_col (EXPR_WFL_FILENAME (cl_v),
+                           EXPR_WFL_LINENO (cl_v), EXPR_WFL_COLNO (cl_v));
 
-  found = strstr ((const char *)line, 
+  found = strstr ((const char *)line,
                  (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
   if (found)
-    EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
+    EXPR_WFL_SET_LINECOL (cl_v, EXPR_WFL_LINENO (cl_v), found - line);
 
-  return cl;
+  return cl_v;
 }
 
 /* Look for a simple name in the single-type import list */
@@ -6667,15 +6717,14 @@ process_imports ()
       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
       char *original_name;
 
-      obstack_grow0 (&temporary_obstack,
-                    IDENTIFIER_POINTER (to_be_found),
-                    IDENTIFIER_LENGTH (to_be_found));
-      original_name = obstack_finish (&temporary_obstack);
+      original_name = xmemdup (IDENTIFIER_POINTER (to_be_found),
+                              IDENTIFIER_LENGTH (to_be_found),
+                              IDENTIFIER_LENGTH (to_be_found) + 1);
 
       /* Don't load twice something already defined. */
       if (IDENTIFIER_CLASS_VALUE (to_be_found))
        continue;
-      
+
       while (1)
        {
          tree left;
@@ -6684,7 +6733,7 @@ process_imports ()
          load_class (to_be_found, 0);
          error_found =
            check_pkg_class_access (to_be_found, TREE_PURPOSE (import), true);
-         
+
          /* We found it, we can bail out */
          if (IDENTIFIER_CLASS_VALUE (to_be_found))
            break;
@@ -6706,7 +6755,7 @@ process_imports ()
          error_found = 1;
        }
 
-      obstack_free (&temporary_obstack, original_name);
+      free (original_name);
       if (error_found)
        return 1;
     }
@@ -6721,7 +6770,7 @@ find_in_imports (enclosing_type, class_type)
      tree enclosing_type;
      tree class_type;
 {
-  tree import = (enclosing_type ? TYPE_IMPORT_LIST (enclosing_type) : 
+  tree import = (enclosing_type ? TYPE_IMPORT_LIST (enclosing_type) :
                 ctxp->import_list);
   while (import)
     {
@@ -6809,7 +6858,7 @@ read_import_dir (wfl)
                  int current_entry_len = zipd->filename_length;
 
                  if (current_entry_len >= BUFFER_LENGTH (filename)
-                     && strncmp (filename->data, current_entry, 
+                     && strncmp (filename->data, current_entry,
                                  BUFFER_LENGTH (filename)) != 0)
                    continue;
                  found |= note_possible_classname (current_entry,
@@ -6836,7 +6885,7 @@ read_import_dir (wfl)
          *filename->ptr++ = '/';
          for (;;)
            {
-             int len; 
+             int len;
              const char *d_name;
              struct dirent *direntp = readdir (dirp);
              if (!direntp)
@@ -6876,9 +6925,9 @@ read_import_dir (wfl)
 }
 
 /* Possibly find a type in the import on demands specified
-   types. Returns 1 if an error occured, 0 otherwise. Run throught the
+   types. Returns 1 if an error occurred, 0 otherwise. Run through the
    entire list, to detected potential double definitions.  */
-                
+
 static int
 find_in_imports_on_demand (enclosing_type, class_type)
      tree enclosing_type;
@@ -6899,15 +6948,15 @@ find_in_imports_on_demand (enclosing_type, class_type)
       const char *id_name;
       tree decl, type_name_copy;
 
-      obstack_grow (&temporary_obstack, 
+      obstack_grow (&temporary_obstack,
                    IDENTIFIER_POINTER (EXPR_WFL_NODE (TREE_PURPOSE (import))),
                    IDENTIFIER_LENGTH (EXPR_WFL_NODE (TREE_PURPOSE (import))));
       obstack_1grow (&temporary_obstack, '.');
-      obstack_grow0 (&temporary_obstack, 
+      obstack_grow0 (&temporary_obstack,
                     IDENTIFIER_POINTER (class_type_name),
                     IDENTIFIER_LENGTH (class_type_name));
       id_name = obstack_finish (&temporary_obstack);
-             
+
       if (! (node = maybe_get_identifier (id_name)))
        continue;
 
@@ -6945,7 +6994,7 @@ find_in_imports_on_demand (enclosing_type, class_type)
          TYPE_NAME (class_type) = type_name_copy;
          continue;
        }
-      
+
       /* If the loaded class is accessible, we keep a tab on it to
         detect and report multiple inclusions. */
       if (IS_A_CLASSFILE_NAME (node))
@@ -6958,13 +7007,13 @@ find_in_imports_on_demand (enclosing_type, class_type)
          else if (seen_once >= 0)
            {
              tree location = (cl ? cl : TREE_PURPOSE (import));
-             tree package = (cl ? EXPR_WFL_NODE (cl) : 
+             tree package = (cl ? EXPR_WFL_NODE (cl) :
                              EXPR_WFL_NODE (TREE_PURPOSE (import)));
              seen_once++;
-             parse_error_context 
+             parse_error_context
                (location,
                 "Type `%s' also potentially defined in package `%s'",
-                IDENTIFIER_POINTER (TYPE_NAME (class_type)), 
+                IDENTIFIER_POINTER (TYPE_NAME (class_type)),
                 IDENTIFIER_POINTER (package));
            }
        }
@@ -6977,7 +7026,7 @@ find_in_imports_on_demand (enclosing_type, 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
+/* Add package NAME to the list of packages encountered so far. To
    speed up class lookup in do_resolve_class, we make sure a
    particular package is added only once.  */
 
@@ -6985,66 +7034,47 @@ static void
 register_package (name)
      tree name;
 {
-  static struct hash_table _pht, *pht = NULL;
+  static htab_t pht;
+  PTR *e;
+
+  if (pht == NULL)
+    pht = htab_create (50, htab_hash_pointer, htab_eq_pointer, 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))
+  e = htab_find_slot (pht, name, INSERT);
+  if (*e == NULL)
     {
       package_list = chainon (package_list, build_tree_list (name, NULL));
-      hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
+      *e = name;
     }
 }
 
 static tree
-resolve_package (pkg, next)
-     tree pkg, *next;
+resolve_package (pkg, next, type_name)
+     tree pkg, *next, *type_name;
 {
-  tree current, acc;
-  tree type_name = NULL_TREE;
-  const char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
+  tree current;
+  tree decl = NULL_TREE;
+  *type_name = NULL_TREE;
 
   /* The trick is to determine when the package name stops and were
      the name of something contained in the package starts. Then we
      return a fully qualified name of what we want to get. */
 
-  /* Do a quick search on well known package names */
-  if (!strncmp (name, "java.lang.reflect", 17))
-    {
-      *next = 
-       TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
-      type_name = lookup_package_type (name, 17);
-    }
-  else if (!strncmp (name, "java.lang", 9))
-    {
-      *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
-      type_name = lookup_package_type (name, 9);
-    }
-
-  /* If we found something here, return */
-  if (type_name)
-    return type_name; 
-
   *next = EXPR_WFL_QUALIFICATION (pkg);
 
   /* Try to progressively construct a type name */
   if (TREE_CODE (pkg) == EXPR_WITH_FILE_LOCATION)
-    for (acc = NULL_TREE, current = EXPR_WFL_QUALIFICATION (pkg); 
+    for (current = EXPR_WFL_QUALIFICATION (pkg);
         current; current = TREE_CHAIN (current))
       {
        /* If we don't have what we're expecting, exit now. TYPE_NAME
           will be null and the error caught later. */
        if (TREE_CODE (QUAL_WFL (current)) != EXPR_WITH_FILE_LOCATION)
          break;
-       acc = merge_qualified_name (acc, EXPR_WFL_NODE (QUAL_WFL (current)));
-       if ((type_name = resolve_no_layout (acc, NULL_TREE)))
+       *type_name =
+         merge_qualified_name (*type_name, EXPR_WFL_NODE (QUAL_WFL (current)));
+       if ((decl = resolve_no_layout (*type_name, NULL_TREE)))
          {
-           type_name = acc;
            /* resolve_package should be used in a loop, hence we
               point at this one to naturally process the next one at
               the next iteration. */
@@ -7052,24 +7082,11 @@ resolve_package (pkg, next)
            break;
          }
       }
-  return type_name;
+  return decl;
 }
 
-static tree
-lookup_package_type (name, from)
-     const char *name;
-     int from;
-{
-  char subname [128];
-  const char *sub = &name[from+1];
-  while (*sub != '.' && *sub)
-    sub++;
-  strncpy (subname, name, sub-name);
-  subname [sub-name] = '\0';
-  return get_identifier (subname);
-}
 
-/* Check accessibility of inner classes according to member access rules. 
+/* Check accessibility of inner classes according to member access rules.
    DECL is the inner class, ENCLOSING_DECL is the class from which the
    access is being attempted. */
 
@@ -7096,11 +7113,11 @@ check_inner_class_access (decl, enclosing_decl, cl)
          class in which DECL is declared. */
       tree top_level = decl;
       while (DECL_CONTEXT (top_level))
-        top_level = DECL_CONTEXT (top_level);      
+        top_level = DECL_CONTEXT (top_level);
       while (DECL_CONTEXT (enclosing_decl))
         enclosing_decl = DECL_CONTEXT (enclosing_decl);
       if (top_level == enclosing_decl)
-        return;      
+        return;
       access = "private";
     }
   else if (CLASS_PROTECTED (decl))
@@ -7109,7 +7126,7 @@ check_inner_class_access (decl, enclosing_decl, cl)
       /* Access is permitted from within the same package... */
       if (in_same_package (decl, enclosing_decl))
         return;
-      
+
       /* ... or from within the body of a subtype of the context in which
          DECL is declared. */
       decl_context = DECL_CONTEXT (decl);
@@ -7117,19 +7134,19 @@ check_inner_class_access (decl, enclosing_decl, cl)
         {
          if (CLASS_INTERFACE (decl))
            {
-             if (interface_of_p (TREE_TYPE (decl_context), 
+             if (interface_of_p (TREE_TYPE (decl_context),
                                  enclosing_decl_type))
                return;
            }
          else
            {
              /* Eww. The order of the arguments is different!! */
-             if (inherits_from_p (enclosing_decl_type, 
+             if (inherits_from_p (enclosing_decl_type,
                                   TREE_TYPE (decl_context)))
                return;
            }
          enclosing_decl = DECL_CONTEXT (enclosing_decl);
-       }      
+       }
       access = "protected";
     }
   else if (! CLASS_PUBLIC (decl))
@@ -7181,7 +7198,7 @@ check_pkg_class_access (class_name, cl, verbose)
        return 0;
 
       if (verbose)
-       parse_error_context 
+       parse_error_context
          (cl, "Can't access %s `%s'. Only public classes and interfaces in other packages can be accessed",
           (CLASS_INTERFACE (TYPE_NAME (type)) ? "interface" : "class"),
           IDENTIFIER_POINTER (class_name));
@@ -7213,14 +7230,16 @@ declare_local_variables (modifier, type, vlist)
 
   if (modifier)
     {
-      int i;
-      for (i = 0; i <= 10; i++) if (1 << i & modifier) break;
+      size_t i;
+      for (i = 0; i < ARRAY_SIZE (ctxp->modifier_ctx); i++)
+       if (1 << i & modifier)
+         break;
       if (modifier == ACC_FINAL)
        final_p = 1;
-      else 
+      else
        {
-         parse_error_context 
-           (ctxp->modifier_ctx [i], 
+         parse_error_context
+           (ctxp->modifier_ctx [i],
             "Only `final' is allowed as a local variables modifier");
          return;
        }
@@ -7266,16 +7285,16 @@ declare_local_variables (modifier, type, vlist)
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
       DECL_FINAL (decl) = final_p;
       BLOCK_CHAIN_DECL (decl);
-      
+
       /* If doing xreferencing, replace the line number with the WFL
          compound value */
       if (flag_emit_xref)
        DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
-      
+
       /* Don't try to use an INIT statement when an error was found */
       if (init && java_error_count)
        init = NULL_TREE;
-      
+
       /* Add the initialization function to the current function's code */
       if (init)
        {
@@ -7286,7 +7305,7 @@ declare_local_variables (modifier, type, vlist)
                                build_debugable_stmt (EXPR_WFL_LINECOL (init),
                                                      init));
        }
-    
+
       /* Setup dependency the type of the decl */
       if (must_chain)
        {
@@ -7321,7 +7340,7 @@ source_start_java_method (fndecl)
     {
       tree type = TREE_VALUE (tem);
       tree name = TREE_PURPOSE (tem);
-      
+
       /* If type is incomplete. Create an incomplete decl and ask for
         the decl to be patched later */
       if (INCOMPLETE_TYPE_P (type))
@@ -7366,17 +7385,17 @@ create_artificial_method (class, flags, type, name, args)
   tree mdecl;
 
   java_parser_context_save_global ();
-  lineno = 0;                                                              
-  mdecl = make_node (FUNCTION_TYPE);                               
+  lineno = 0;
+  mdecl = make_node (FUNCTION_TYPE);
   TREE_TYPE (mdecl) = type;
   TYPE_ARG_TYPES (mdecl) = args;
-  mdecl = add_method (class, flags, name, build_java_signature (mdecl)); 
+  mdecl = add_method (class, flags, name, build_java_signature (mdecl));
   java_parser_context_restore_global ();
-  DECL_ARTIFICIAL (mdecl) = 1;                                     
+  DECL_ARTIFICIAL (mdecl) = 1;
   return mdecl;
 }
 
-/* Starts the body if an artifical method.  */
+/* Starts the body if an artificial method.  */
 
 static void
 start_artificial_method_body (mdecl)
@@ -7400,6 +7419,25 @@ end_artificial_method_body (mdecl)
   exit_block ();
 }
 
+/* Dump a tree of some kind.  This is a convenience wrapper for the
+   dump_* functions in tree-dump.c.  */
+static void
+dump_java_tree (phase, t)
+     enum tree_dump_index phase;
+     tree t;
+{
+  FILE *stream;
+  int flags;
+
+  stream = dump_begin (phase, &flags);
+  flags |= TDF_SLIM;
+  if (stream)
+    {
+      dump_node (t, flags, stream);
+      dump_end (phase, stream);
+    }
+}
+
 /* Terminate a function and expand its body.  */
 
 static void
@@ -7419,6 +7457,12 @@ source_end_java_method ()
   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
 
+  /* We've generated all the trees for this function, and it has been
+     patched.  Dump it to a file if the user requested it.  */
+  dump_java_tree (TDI_original, fndecl);
+
+  java_optimize_inline (fndecl);
+
   /* Generate function's code */
   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
       && ! flag_emit_class_files
@@ -7436,6 +7480,8 @@ source_end_java_method ()
       lineno = DECL_SOURCE_LINE_LAST (fndecl);
       expand_function_end (input_filename, lineno, 0);
 
+      DECL_SOURCE_LINE (fndecl) = DECL_SOURCE_LINE_FIRST (fndecl);
+
       /* Run the optimizers and output assembler code for this function. */
       rest_of_compilation (fndecl);
     }
@@ -7461,10 +7507,10 @@ add_stmt_to_block (b, type, stmt)
      tree b, type, stmt;
 {
   tree body = BLOCK_EXPR_BODY (b), c;
-  
+
   if (java_error_count)
     return body;
-    
+
   if ((c = add_stmt_to_compound (body, type, stmt)) == body)
     return body;
 
@@ -7480,6 +7526,10 @@ static tree
 add_stmt_to_compound (existing, type, stmt)
      tree existing, type, stmt;
 {
+  /* Keep track of this for inlining.  */
+  if (current_function_decl)
+    ++DECL_NUM_STMTS (current_function_decl);
+
   if (existing)
     return build (COMPOUND_EXPR, type, existing, stmt);
   else
@@ -7494,10 +7544,10 @@ void java_layout_seen_class_methods ()
 
   while (1)
     {
-      for (current = previous_list; 
+      for (current = previous_list;
           current != end; current = TREE_CHAIN (current))
        layout_class_methods (TREE_TYPE (TREE_VALUE (current)));
-      
+
       if (previous_list != all_class_list)
        {
          end = previous_list;
@@ -7508,20 +7558,12 @@ void java_layout_seen_class_methods ()
     }
 }
 
+static GTY(()) tree stop_reordering;
 void
 java_reorder_fields ()
 {
-  static tree stop_reordering = NULL_TREE;
-  static int initialized_p;
   tree current;
 
-  /* Register STOP_REORDERING with the garbage collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&stop_reordering, 1);
-      initialized_p = 1;
-    }
-
   for (current = gclass_list; current; current = TREE_CHAIN (current))
     {
       current_class = TREE_TYPE (TREE_VALUE (current));
@@ -7546,7 +7588,7 @@ java_reorder_fields ()
            after having reversed the fields */
        else
          {
-           TYPE_FIELDS (current_class) = 
+           TYPE_FIELDS (current_class) =
              nreverse (TYPE_FIELDS (current_class));
            TYPE_SIZE (current_class) = NULL_TREE;
          }
@@ -7676,7 +7718,7 @@ java_complete_expand_methods (class_decl)
 
       if (!DECL_CONSTRUCTOR_P (decl))
        continue;
-      
+
       no_body = !DECL_FUNCTION_BODY (decl);
       /* Don't generate debug info on line zero when expanding a
         generated constructor. */
@@ -7695,7 +7737,7 @@ java_complete_expand_methods (class_decl)
       /* Ctors aren't part of this batch. */
       if (DECL_CONSTRUCTOR_P (decl) || DECL_CLINIT_P (decl))
        continue;
-      
+
       /* Skip abstract or native methods -- but do handle native
         methods when generating JNI stubs.  */
       if (METHOD_ABSTRACT (decl) || (! flag_jni && METHOD_NATIVE (decl)))
@@ -7706,7 +7748,9 @@ java_complete_expand_methods (class_decl)
 
       if (METHOD_NATIVE (decl))
        {
-         tree body = build_jni_stub (decl);
+         tree body;
+         current_function_decl = decl;
+         body = build_jni_stub (decl);
          BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl)) = body;
        }
 
@@ -7721,7 +7765,7 @@ java_complete_expand_methods (class_decl)
       java_complete_expand_method (clinit);
       ctxp->explicit_constructor_p = 0;
     }
-  
+
   /* We might have generated a class$ that we now want to expand */
   if (TYPE_DOT_CLASS (current_class))
     java_complete_expand_method (TYPE_DOT_CLASS (current_class));
@@ -7730,7 +7774,7 @@ java_complete_expand_methods (class_decl)
      prove wrong.) */
   if (!CLASS_INTERFACE (class_decl))
     for (decl = TYPE_METHODS (current_class); decl; decl = TREE_CHAIN (decl))
-      if (DECL_CONSTRUCTOR_P (decl) 
+      if (DECL_CONSTRUCTOR_P (decl)
          && verify_constructor_circularity (decl, decl))
        break;
 
@@ -7751,7 +7795,7 @@ maybe_generate_pre_expand_clinit (class_type)
     return NULL_TREE;
 
   /* Go through all static fields and pre expand them */
-  for (current = TYPE_FIELDS (class_type); current; 
+  for (current = TYPE_FIELDS (class_type); current;
        current = TREE_CHAIN (current))
     if (FIELD_STATIC (current))
       build_field_ref (NULL_TREE, class_type, DECL_NAME (current));
@@ -7802,8 +7846,8 @@ maybe_generate_pre_expand_clinit (class_type)
    MODIFY_EXPR with a constant value.  */
 
 static int
-analyze_clinit_body (bbody)
-     tree bbody;
+analyze_clinit_body (this_class, bbody)
+     tree this_class, bbody;
 {
   while (bbody)
     switch (TREE_CODE (bbody))
@@ -7811,25 +7855,33 @@ analyze_clinit_body (bbody)
       case BLOCK:
        bbody = BLOCK_EXPR_BODY (bbody);
        break;
-       
+
       case EXPR_WITH_FILE_LOCATION:
        bbody = EXPR_WFL_NODE (bbody);
        break;
-       
+
       case COMPOUND_EXPR:
-       if (analyze_clinit_body (TREE_OPERAND (bbody, 0)))
+       if (analyze_clinit_body (this_class, TREE_OPERAND (bbody, 0)))
          return 1;
        bbody = TREE_OPERAND (bbody, 1);
        break;
-       
+
       case MODIFY_EXPR:
        /* If we're generating to class file and we're dealing with an
           array initialization, we return 1 to keep <clinit> */
        if (TREE_CODE (TREE_OPERAND (bbody, 1)) == NEW_ARRAY_INIT
            && flag_emit_class_files)
          return 1;
-       /* Return 0 if the operand is constant, 1 otherwise.  */
-       return ! TREE_CONSTANT (TREE_OPERAND (bbody, 1));
+
+       /* There are a few cases where we're required to keep
+          <clinit>:
+          - If this is an assignment whose operand is not constant,
+          - If this is an assignment to a non-initialized field,
+          - If this field is not a member of the current class.
+       */
+       return (! TREE_CONSTANT (TREE_OPERAND (bbody, 1))
+               || ! DECL_INITIAL (TREE_OPERAND (bbody, 0))
+               || DECL_CONTEXT (TREE_OPERAND (bbody, 0)) != this_class);
 
       default:
        return 1;
@@ -7848,8 +7900,7 @@ maybe_yank_clinit (mdecl)
 {
   tree type, current;
   tree fbody, bbody;
-  int found = 0;
-  
+
   if (!DECL_CLINIT_P (mdecl))
     return 0;
 
@@ -7864,22 +7915,21 @@ maybe_yank_clinit (mdecl)
     return 0;
   if (bbody && ! flag_emit_class_files && bbody != empty_stmt_node)
     return 0;
-  
+
   type = DECL_CONTEXT (mdecl);
   current = TYPE_FIELDS (type);
 
-  for (current = (current ? TREE_CHAIN (current) : current); 
+  for (current = (current ? TREE_CHAIN (current) : current);
        current; current = TREE_CHAIN (current))
     {
       tree f_init;
 
-      /* We're not interested in non static field */
+      /* We're not interested in non-static fields.  */
       if (!FIELD_STATIC (current))
        continue;
 
-      /* nor in fields with initializers. */
+      /* Nor in fields without initializers. */
       f_init = DECL_INITIAL (current);
-
       if (f_init == NULL_TREE)
        continue;
 
@@ -7889,27 +7939,22 @@ maybe_yank_clinit (mdecl)
         correctly. */
       if (! JSTRING_TYPE_P (TREE_TYPE (current))
          && ! JNUMERIC_TYPE_P (TREE_TYPE (current)))
-       break;
+       return 0;
 
       if (! FIELD_FINAL (current) || ! TREE_CONSTANT (f_init))
-       break;
+       return 0;
     }
 
   /* Now we analyze the method body and look for something that
      isn't a MODIFY_EXPR */
-  if (bbody == empty_stmt_node)
-    found = 0;
-  else
-    found = analyze_clinit_body (bbody);
-
-  if (current || found)
+  if (bbody != empty_stmt_node && analyze_clinit_body (type, bbody))
     return 0;
 
   /* Get rid of <clinit> in the class' list of methods */
   if (TYPE_METHODS (type) == mdecl)
     TYPE_METHODS (type) = TREE_CHAIN (mdecl);
   else
-    for (current = TYPE_METHODS (type); current; 
+    for (current = TYPE_METHODS (type); current;
         current = TREE_CHAIN (current))
       if (TREE_CHAIN (current) == mdecl)
        {
@@ -7935,7 +7980,7 @@ start_complete_expand_method (mdecl)
 
   for (; tem; tem = TREE_CHAIN (tem))
     {
-      /* TREE_CHAIN (tem) will change after pushdecl. */ 
+      /* TREE_CHAIN (tem) will change after pushdecl. */
       tree next = TREE_CHAIN (tem);
       tree type = TREE_TYPE (tem);
       if (PROMOTE_PROTOTYPES
@@ -7967,7 +8012,7 @@ java_complete_expand_method (mdecl)
   /* Fix constructors before expanding them */
   if (DECL_CONSTRUCTOR_P (mdecl))
     fix_constructors (mdecl);
-  
+
   /* Expand functions that have a body */
   if (!DECL_FUNCTION_BODY (mdecl))
     return;
@@ -7984,60 +8029,57 @@ java_complete_expand_method (mdecl)
   announce_function (mdecl);
   if (! quiet_flag)
     fprintf (stderr, "]");
-  
+
   /* Prepare the function for tree completion */
   start_complete_expand_method (mdecl);
 
   /* Install the current this */
-  current_this = (!METHOD_STATIC (mdecl) ? 
+  current_this = (!METHOD_STATIC (mdecl) ?
                  BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
 
   /* Purge the `throws' list of unchecked exceptions (we save a copy
      of the list and re-install it later.) */
   exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
   purge_unchecked_exceptions (mdecl);
-  
+
   /* Install exceptions thrown with `throws' */
   PUSH_EXCEPTIONS (DECL_FUNCTION_THROWS (mdecl));
-  
+
   if (block_body != NULL_TREE)
     {
       block_body = java_complete_tree (block_body);
-      
+
       /* Before we check initialization, attached all class initialization
         variable to the block_body */
-      hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
+      htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
                     attach_init_test_initialization_flags, block_body);
-      
+
       if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
        {
          check_for_initialization (block_body, mdecl);
-         
+
          /* Go through all the flags marking the initialization of
             static variables and see whether they're definitively
             assigned, in which case the type is remembered as
             definitively initialized in MDECL. */
-         /* FIXME this doesn't work state is too short.
          if (STATIC_CLASS_INIT_OPT_P ())
            {
-             hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
-                            attach_initialized_static_class, (PTR)&state);
-
-             / * Always register the context as properly initialized in
+             /* Always register the context as properly initialized in
                 MDECL. This used with caution helps removing extra
-                initialization of self. * /
+                initialization of self. */
              if (METHOD_STATIC (mdecl))
-               hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
-                            (hash_table_key) DECL_CONTEXT (mdecl),
-                            TRUE, NULL);
+               {
+                 *(htab_find_slot
+                   (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
+                    DECL_CONTEXT (mdecl), INSERT)) = DECL_CONTEXT (mdecl);
+               }
            }
-         */
        }
       ctxp->explicit_constructor_p = 0;
     }
-  
+
   BLOCK_EXPR_BODY (fbody) = block_body;
-  
+
   /* If we saw a return but couldn't evaluate it properly, we'll have
      an error_mark_node here. */
   if (block_body != error_mark_node
@@ -8077,14 +8119,43 @@ java_expand_method_bodies (class)
 
       current_function_decl = decl;
 
+      /* Save the function for inlining.  */
+      if (flag_inline_trees)
+       DECL_SAVED_TREE (decl) =
+         BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (decl));
+
       /* It's time to assign the variable flagging static class
         initialization based on which classes invoked static methods
         are definitely initializing. This should be flagged. */
       if (STATIC_CLASS_INIT_OPT_P ())
-       hash_traverse (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl),
-                      adjust_init_test_initialization, NULL);
+       {
+         tree list = DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (decl);
+         for (; list != NULL_TREE;  list = TREE_CHAIN (list))
+           {
+             /* Executed for each statement calling a static function.
+                LIST is a TREE_LIST whose PURPOSE is the called function
+                and VALUE is a compound whose second operand can be patched
+                with static class initialization flag assignments.  */
+
+             tree called_method = TREE_PURPOSE (list);
+             tree compound = TREE_VALUE (list);
+             tree assignment_compound_list
+               = build_tree_list (called_method, NULL);
+
+             /* For each class definitely initialized in
+                CALLED_METHOD, fill ASSIGNMENT_COMPOUND with
+                assignment to the class initialization flag. */
+             htab_traverse (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
+                            emit_test_initialization,
+                            assignment_compound_list);
+
+             if (TREE_VALUE (assignment_compound_list))
+               TREE_OPERAND (compound, 1)
+                 = TREE_VALUE (assignment_compound_list);
+           }
+       }
 
-      /* Prepare the function for RTL expansion */  
+      /* Prepare the function for RTL expansion */
       start_complete_expand_method (decl);
 
       /* Expand function start, generate initialization flag
@@ -8125,7 +8196,7 @@ build_outer_field_access (id, decl)
       && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
     {
       tree thisn = build_current_thisn (current_class);
-      access = make_qualified_primary (build_wfl_node (thisn), 
+      access = make_qualified_primary (build_wfl_node (thisn),
                                       id, EXPR_WFL_LINECOL (id));
     }
   /* Otherwise, generate access methods to outer this and access the
@@ -8156,18 +8227,18 @@ build_outer_field_access (id, decl)
   return resolve_expression_name (access, NULL);
 }
 
-/* Return a non zero value if NODE describes an outer field inner
+/* Return a nonzero value if NODE describes an outer field inner
    access.  */
 
 static int
 outer_field_access_p (type, decl)
     tree type, decl;
 {
-  if (!INNER_CLASS_TYPE_P (type) 
+  if (!INNER_CLASS_TYPE_P (type)
       || TREE_CODE (decl) != FIELD_DECL
       || DECL_CONTEXT (decl) == type)
     return 0;
-  
+
   /* If the inner class extends the declaration context of the field
      we're try to acces, then this isn't an outer field access */
   if (inherits_from_p (type, DECL_CONTEXT (decl)))
@@ -8192,7 +8263,7 @@ outer_field_access_p (type, decl)
   return 0;
 }
 
-/* Return a non zero value if NODE represents an outer field inner
+/* Return a nonzero value if NODE represents an outer field inner
    access that was been already expanded. As a side effect, it returns
    the name of the field being accessed and the argument passed to the
    access function, suitable for a regeneration of the access method
@@ -8210,21 +8281,21 @@ outer_field_expanded_access_p (node, name, arg_type, arg)
   /* Well, gcj generates slightly different tree nodes when compiling
      to native or bytecodes. It's the case for function calls. */
 
-  if (flag_emit_class_files 
+  if (flag_emit_class_files
       && TREE_CODE (node) == CALL_EXPR
       && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
     identified = 1;
   else if (!flag_emit_class_files)
     {
       node = TREE_OPERAND (node, 0);
-      
+
       if (node && TREE_OPERAND (node, 0)
          && TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR)
        {
          node = TREE_OPERAND (node, 0);
          if (TREE_OPERAND (node, 0)
              && TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
-             && (OUTER_FIELD_ACCESS_IDENTIFIER_P 
+             && (OUTER_FIELD_ACCESS_IDENTIFIER_P
                  (DECL_NAME (TREE_OPERAND (node, 0)))))
            identified = 1;
        }
@@ -8250,10 +8321,10 @@ outer_field_access_fix (wfl, node, rhs)
     tree wfl, node, rhs;
 {
   tree name, arg_type, arg;
-  
+
   if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
     {
-      node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl), 
+      node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl),
                                            arg_type, name, arg, rhs);
       return java_complete_tree (node);
     }
@@ -8261,7 +8332,7 @@ outer_field_access_fix (wfl, node, rhs)
 }
 
 /* Construct the expression that calls an access method:
-     <type>.access$<n>(<arg1> [, <arg2>]); 
+     <type>.access$<n>(<arg1> [, <arg2>]);
 
    ARG2 can be NULL and will be omitted in that case. It will denote a
    read access.  */
@@ -8273,7 +8344,7 @@ build_outer_field_access_expr (lc, type, access_method_name, arg1, arg2)
 {
   tree args, cn, access;
 
-  args = arg1 ? arg1 : 
+  args = arg1 ? arg1 :
     build_wfl_node (build_current_thisn (current_class));
   args = build_tree_list (NULL_TREE, args);
 
@@ -8314,12 +8385,12 @@ build_outer_field_access_methods (decl)
     tree decl;
 {
   tree id, args, stmt, mdecl;
-  
+
   if (FIELD_INNER_ACCESS_P (decl))
     return FIELD_INNER_ACCESS (decl);
 
   MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+
   /* Create the identifier and a function named after it. */
   id = build_new_access_id ();
 
@@ -8333,14 +8404,14 @@ build_outer_field_access_methods (decl)
   stmt = make_qualified_primary (build_wfl_node (inst_id),
                                 build_wfl_node (DECL_NAME (decl)), 0);
   stmt = build_return (0, stmt);
-  mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
+  mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
                                           TREE_TYPE (decl), id, args, stmt);
   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
 
   /* Create the write access method. No write access for final variable */
   if (!FIELD_FINAL (decl))
     {
-      args = build_tree_list (inst_id, 
+      args = build_tree_list (inst_id,
                              build_pointer_type (DECL_CONTEXT (decl)));
       TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
       TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
@@ -8348,8 +8419,8 @@ build_outer_field_access_methods (decl)
                                     build_wfl_node (DECL_NAME (decl)), 0);
       stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
                                                build_wfl_node (wpv_id)));
-      mdecl = build_outer_field_access_method (DECL_CONTEXT (decl), 
-                                              TREE_TYPE (decl), id, 
+      mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
+                                              TREE_TYPE (decl), id,
                                               args, stmt);
     }
   DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
@@ -8360,7 +8431,7 @@ build_outer_field_access_methods (decl)
 
 /* Build an field access method NAME.  */
 
-static tree 
+static tree
 build_outer_field_access_method (class, type, name, args, body)
     tree class, type, name, args, body;
 {
@@ -8411,17 +8482,17 @@ build_outer_method_access_method (decl)
 
   carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
   /* Create the arguments, as much as the original */
-  for (; carg && carg != end_params_node; 
+  for (; carg && carg != end_params_node;
        carg = TREE_CHAIN (carg))
     {
       sprintf (buffer, "write_parm_value$%d", parm_id_count++);
-      args = chainon (args, build_tree_list (get_identifier (buffer), 
+      args = chainon (args, build_tree_list (get_identifier (buffer),
                                             TREE_VALUE (carg)));
     }
   args = chainon (args, end_params_node);
 
   /* Create the method */
-  mdecl = create_artificial_method (class, ACC_STATIC, 
+  mdecl = create_artificial_method (class, ACC_STATIC,
                                    TREE_TYPE (TREE_TYPE (decl)), id, args);
   layout_class_method (class, NULL_TREE, mdecl, NULL_TREE);
   /* There is a potential bug here. We should be able to use
@@ -8445,10 +8516,10 @@ build_outer_method_access_method (decl)
     call_args = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (carg)),
                           call_args);
 
-  body = build_method_invocation (build_wfl_node (DECL_NAME (decl)), 
+  body = build_method_invocation (build_wfl_node (DECL_NAME (decl)),
                                  call_args);
   if (!METHOD_STATIC (decl))
-    body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)), 
+    body = make_qualified_primary (build_wfl_node (TREE_PURPOSE (args)),
                                   body, 0);
   if (TREE_TYPE (TREE_TYPE (decl)) != void_type_node)
     body = build_return (0, body);
@@ -8468,7 +8539,7 @@ build_outer_method_access_method (decl)
    the enclosing instance of an inner class. The enclosing instance is
    kept in a generated field called this$<n>, with <n> being the
    inner class nesting level (starting from 0.)  */
-    
+
 /* Build an access to a given this$<n>, always chaining access call to
    others. Access methods to this$<n> are build on the fly if
    necessary. This CAN'T be used to solely access this$<n-1> from
@@ -8482,7 +8553,7 @@ build_access_to_thisn (from, to, lc)
 {
   tree access = NULL_TREE;
 
-  while (from != to)
+  while (from != to && PURE_INNER_CLASS_TYPE_P (from))
     {
       if (!access)
         {
@@ -8502,8 +8573,8 @@ build_access_to_thisn (from, to, lc)
          access = make_qualified_primary (cn, access, lc);
        }
 
-      /* if FROM isn't an inter class, that's fine, we've done
-         enough. What we're looking for can be accessed from there. */
+      /* If FROM isn't an inner class, that's fine, we've done enough.
+         What we're looking for can be accessed from there.  */
       from = DECL_CONTEXT (TYPE_NAME (from));
       if (!from)
        break;
@@ -8514,7 +8585,7 @@ build_access_to_thisn (from, to, lc)
 
 /* Build an access function to the this$<n> local to TYPE. NULL_TREE
    is returned if nothing needs to be generated. Otherwise, the method
-   generated and a method decl is returned.  
+   generated and a method decl is returned.
 
    NOTE: These generated methods should be declared in a class file
    attribute so that they can't be referred to directly.  */
@@ -8542,7 +8613,7 @@ maybe_build_thisn_access_method (type)
   fix_method_argument_names (args, mdecl);
   layout_class_method (type, NULL_TREE, mdecl, NULL_TREE);
   stmt = build_current_thisn (type);
-  stmt = make_qualified_primary (build_wfl_node (inst_id), 
+  stmt = make_qualified_primary (build_wfl_node (inst_id),
                                 build_wfl_node (stmt), 0);
   stmt = build_return (0, stmt);
 
@@ -8562,37 +8633,29 @@ maybe_build_thisn_access_method (type)
    This function can be invoked with TYPE to NULL, available and then
    has to count the parser context.  */
 
+static GTY(()) tree saved_thisn;
+static GTY(()) tree saved_type;
+
 static tree
 build_current_thisn (type)
     tree type;
 {
   static int saved_i = -1;
-  static tree saved_thisn = NULL_TREE;
-  static tree saved_type = NULL_TREE;
   static int saved_type_i = 0;
-  static int initialized_p;
   tree decl;
   char buffer [24];
   int i = 0;
 
-  /* Register SAVED_THISN and SAVED_TYPE with the garbage collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&saved_thisn, 1);
-      ggc_add_tree_root (&saved_type, 1);
-      initialized_p = 1;
-    }
-
   if (type)
     {
       if (type == saved_type)
        i = saved_type_i;
       else
        {
-         for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type)); 
+         for (i = -1, decl = DECL_CONTEXT (TYPE_NAME (type));
               decl; decl = DECL_CONTEXT (decl), i++)
            ;
-      
+
          saved_type = type;
          saved_type_i = i;
        }
@@ -8602,7 +8665,7 @@ build_current_thisn (type)
 
   if (i == saved_i)
     return saved_thisn;
-    
+
   sprintf (buffer, "this$%d", i);
   saved_i = i;
   saved_thisn = get_identifier (buffer);
@@ -8639,6 +8702,9 @@ build_thisn_assign ()
         throw new NoClassDefFoundError(e.getMessage());}
     } */
 
+static GTY(()) tree get_message_wfl;
+static GTY(()) tree type_parm_wfl;
+
 static tree
 build_dot_class_method (class)
      tree class;
@@ -8648,14 +8714,10 @@ build_dot_class_method (class)
   tree args, tmp, saved_current_function_decl, mdecl;
   tree stmt, throw_stmt;
 
-  static tree get_message_wfl, type_parm_wfl;
-
   if (!get_message_wfl)
     {
       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
-      ggc_add_tree_root (&get_message_wfl, 1);
-      ggc_add_tree_root (&type_parm_wfl, 1);
     }
 
   /* Build the arguments */
@@ -8664,32 +8726,32 @@ build_dot_class_method (class)
   TREE_CHAIN (args) = end_params_node;
 
   /* Build the qualified name java.lang.Class.forName */
-  tmp = MQN (MQN (MQN (BWF ("java"), 
+  tmp = MQN (MQN (MQN (BWF ("java"),
                       BWF ("lang")), BWF ("Class")), BWF ("forName"));
   load_class (class_not_found_type_node, 1);
   load_class (no_class_def_found_type_node, 1);
-  
+
   /* Create the "class$" function */
-  mdecl = create_artificial_method (class, ACC_STATIC, 
+  mdecl = create_artificial_method (class, ACC_STATIC,
                                    build_pointer_type (class_type_node),
                                    classdollar_identifier_node, args);
-  DECL_FUNCTION_THROWS (mdecl) = 
+  DECL_FUNCTION_THROWS (mdecl) =
     build_tree_list (NULL_TREE, no_class_def_found_type_node);
 
   /* We start by building the try block. We need to build:
        return (java.lang.Class.forName (type)); */
-  stmt = build_method_invocation (tmp, 
+  stmt = build_method_invocation (tmp,
                                  build_tree_list (NULL_TREE, type_parm_wfl));
   stmt = build_return (0, stmt);
 
   /* Now onto the catch block. We start by building the expression
      throwing a new exception: throw new NoClassDefFoundError (_.getMessage) */
-  throw_stmt = make_qualified_name (build_wfl_node (wpv_id), 
+  throw_stmt = make_qualified_name (build_wfl_node (wpv_id),
                                    get_message_wfl, 0);
   throw_stmt = build_method_invocation (throw_stmt, NULL_TREE);
-  
+
   /* Build new NoClassDefFoundError (_.getMessage) */
-  throw_stmt = build_new_invocation 
+  throw_stmt = build_new_invocation
     (build_wfl_node (get_identifier ("NoClassDefFoundError")),
      build_tree_list (build_pointer_type (string_type_node), throw_stmt));
 
@@ -8727,7 +8789,7 @@ build_dot_class_method_invocation (type)
   sig_id = unmangle_classname (IDENTIFIER_POINTER (sig_id),
                               IDENTIFIER_LENGTH (sig_id));
 
-  s = build_string (IDENTIFIER_LENGTH (sig_id), 
+  s = build_string (IDENTIFIER_LENGTH (sig_id),
                    IDENTIFIER_POINTER (sig_id));
   return build_method_invocation (build_wfl_node (classdollar_identifier_node),
                                  build_tree_list (NULL_TREE, s));
@@ -8764,17 +8826,17 @@ fix_constructors (mdecl)
          const char *n = IDENTIFIER_POINTER (DECL_NAME (sclass_decl));
          DECL_NAME (mdecl) = DECL_NAME (sclass_decl);
          parse_error_context
-           (lookup_cl (TYPE_NAME (class_type)), 
+           (lookup_cl (TYPE_NAME (class_type)),
             "No constructor matching `%s' found in class `%s'",
             lang_printable_name (mdecl, 0), n);
          DECL_NAME (mdecl) = save;
        }
-      
+
       /* The constructor body must be crafted by hand. It's the
         constructor we defined when we realize we didn't have the
         CLASSNAME() constructor */
       start_artificial_method_body (mdecl);
-      
+
       /* Insert an assignment to the this$<n> hidden field, if
          necessary */
       if ((thisn_assign = build_thisn_assign ()))
@@ -8792,13 +8854,13 @@ fix_constructors (mdecl)
       end_artificial_method_body (mdecl);
     }
   /* Search for an explicit constructor invocation */
-  else 
+  else
     {
       int found = 0;
       int invokes_this = 0;
       tree found_call = NULL_TREE;
       tree main_block = BLOCK_EXPR_BODY (body);
-      
+
       while (body)
        switch (TREE_CODE (body))
          {
@@ -8838,7 +8900,7 @@ fix_constructors (mdecl)
                                           TREE_OPERAND (found_call, 0));
          TREE_OPERAND (found_call, 0) = empty_stmt_node;
        }
-      
+
       DECL_INIT_CALLS_THIS (mdecl) = invokes_this;
 
       /* Insert the instance initializer block right after. */
@@ -8882,12 +8944,12 @@ verify_constructor_super (mdecl)
            tree arg_type = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (sdecl)));
            if (super_inner)
              arg_type = TREE_CHAIN (arg_type);
-           for (m_arg_type = mdecl_arg_type; 
-                (arg_type != end_params_node 
+           for (m_arg_type = mdecl_arg_type;
+                (arg_type != end_params_node
                  && m_arg_type != end_params_node);
-                arg_type = TREE_CHAIN (arg_type), 
+                arg_type = TREE_CHAIN (arg_type),
                   m_arg_type = TREE_CHAIN (m_arg_type))
-             if (!valid_method_invocation_conversion_p 
+             if (!valid_method_invocation_conversion_p
                     (TREE_VALUE (arg_type),
                      TREE_VALUE (m_arg_type)))
                break;
@@ -8912,6 +8974,7 @@ verify_constructor_super (mdecl)
 
 /* Generate code for all context remembered for code generation.  */
 
+static GTY(()) tree reversed_class_list;
 void
 java_expand_classes ()
 {
@@ -8924,8 +8987,7 @@ java_expand_classes ()
   java_layout_classes ();
   java_parse_abort_on_error ();
 
-  cur_ctxp = ctxp_for_generation;
-  for (; cur_ctxp; cur_ctxp = cur_ctxp->next)
+  for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
     {
       ctxp = cur_ctxp;
       input_filename = ctxp->filename;
@@ -8935,9 +8997,11 @@ java_expand_classes ()
     }
   input_filename = main_input_filename;
 
-  /* Find anonymous classes and expand their constructor, now they
-     have been fixed. */
-  for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
+
+  /* Find anonymous classes and expand their constructor. This extra pass is
+     neccessary because the constructor itself is only generated when the
+     method in which it is defined is expanded. */
+  for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
     {
       tree current;
       ctxp = cur_ctxp;
@@ -8954,7 +9018,7 @@ java_expand_classes ()
                      restore_line_number_status (1);
                      java_complete_expand_method (d);
                      restore_line_number_status (0);
-                     break;    /* We now there are no other ones */
+                     break;    /* There is only one constructor. */
                    }
                }
            }
@@ -8965,18 +9029,56 @@ java_expand_classes ()
      anything, unless we're emitting xrefs or checking the syntax only
      (but not using -fsyntax-only for the purpose of generating
      bytecode. */
-  if (java_error_count && !flag_emit_xref 
+  if (java_error_count && !flag_emit_xref
       && (!flag_syntax_only && !flag_emit_class_files))
     return;
 
   /* Now things are stable, go for generation of the class data. */
-  for (cur_ctxp = ctxp_for_generation;  cur_ctxp;  cur_ctxp = cur_ctxp->next)
+
+  /* We pessimistically marked all fields external until we knew
+     what set of classes we were planning to compile.  Now mark
+     those that will be generated locally as not external.  */
+  for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
     {
       tree current;
       ctxp = cur_ctxp;
       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
        {
-         current_class = TREE_TYPE (current);
+         tree class = TREE_TYPE (current);
+         tree field;
+         for (field = TYPE_FIELDS (class); field ; field = TREE_CHAIN (field))
+           if (FIELD_STATIC (field))
+             DECL_EXTERNAL (field) = 0;
+       }
+    }
+
+  /* Compile the classes.  */
+  for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
+    {
+      tree current;
+      reversed_class_list = NULL;
+
+      ctxp = cur_ctxp;
+
+      /* We write out the classes in reverse order.  This ensures that
+        inner classes are written before their containing classes,
+        which is important for parallel builds.  Otherwise, the
+        class file for the outer class may be found, but the class
+        file for the inner class may not be present.  In that
+        situation, the compiler cannot fall back to the original
+        source, having already read the outer class, so we must
+        prevent that situation.  */
+      for (current = ctxp->class_list;
+          current;
+          current = TREE_CHAIN (current))
+       reversed_class_list
+         = tree_cons (NULL_TREE, current, reversed_class_list);
+
+      for (current = reversed_class_list;
+          current;
+          current = TREE_CHAIN (current))
+       {
+         current_class = TREE_TYPE (TREE_VALUE (current));
          outgoing_cpool = TYPE_CPOOL (current_class);
          if (flag_emit_class_files)
            write_classfile (current_class);
@@ -9074,7 +9176,7 @@ make_qualified_name (left, right, location)
       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (left);
       EXPR_WFL_QUALIFICATION (left) = build_tree_list (wfl, NULL_TREE);
     }
-  
+
   wfl = build_expr_wfl (right_id, ctxp->filename, 0, 0);
   EXPR_WFL_LINECOL (wfl) = location;
   chainon (EXPR_WFL_QUALIFICATION (left), build_tree_list (wfl, NULL_TREE));
@@ -9124,7 +9226,7 @@ resolve_expression_name (id, orig)
         return decl;
 
       /* 15.13.1: NAME can appear within a class declaration */
-      else 
+      else
         {
          decl = lookup_field_wrapper (current_class, name);
          if (decl)
@@ -9199,13 +9301,13 @@ resolve_expression_name (id, orig)
 
   /* We've got an error here */
   if (INNER_CLASS_TYPE_P (current_class))
-    parse_error_context (id, 
+    parse_error_context (id,
                         "Local variable `%s' can't be accessed from within the inner class `%s' unless it is declared final",
                         IDENTIFIER_POINTER (name),
                         IDENTIFIER_POINTER (DECL_NAME
                                             (TYPE_NAME (current_class))));
   else
-    parse_error_context (id, "Undefined variable `%s'", 
+    parse_error_context (id, "Undefined variable `%s'",
                         IDENTIFIER_POINTER (name));
 
   return error_mark_node;
@@ -9215,14 +9317,14 @@ static void
 static_ref_err (wfl, field_id, class_type)
     tree wfl, field_id, class_type;
 {
-  parse_error_context 
-    (wfl, 
+  parse_error_context
+    (wfl,
      "Can't make a static reference to nonstatic variable `%s' in class `%s'",
-     IDENTIFIER_POINTER (field_id), 
+     IDENTIFIER_POINTER (field_id),
      IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
 }
 
-/* 15.10.1 Field Acess Using a Primary and/or Expression Name.
+/* 15.10.1 Field Access Using a Primary and/or Expression Name.
    We return something suitable to generate the field access. We also
    return the field decl in FIELD_DECL and its type in FIELD_TYPE.  If
    recipient's address can be null. */
@@ -9241,8 +9343,8 @@ resolve_field_access (qual_wfl, field_decl, field_type)
     return error_mark_node;
 
   /* Resolve the LENGTH field of an array here */
-  if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node 
-      && type_found && TYPE_ARRAY_P (type_found) 
+  if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node
+      && type_found && TYPE_ARRAY_P (type_found)
       && ! flag_emit_class_files && ! flag_emit_xref)
     {
       tree length = build_java_array_length_access (where_found);
@@ -9269,8 +9371,8 @@ resolve_field_access (qual_wfl, field_decl, field_type)
       if (!type_found)
        type_found = DECL_CONTEXT (decl);
       is_static = FIELD_STATIC (decl);
-      field_ref = build_field_ref ((is_static && !flag_emit_xref? 
-                                   NULL_TREE : where_found), 
+      field_ref = build_field_ref ((is_static && !flag_emit_xref?
+                                   NULL_TREE : where_found),
                                   type_found, DECL_NAME (decl));
       if (field_ref == error_mark_node)
        return error_mark_node;
@@ -9283,7 +9385,7 @@ resolve_field_access (qual_wfl, field_decl, field_type)
   if (field_decl)
     *field_decl = decl;
   if (field_type)
-    *field_type = (QUAL_DECL_TYPE (decl) ? 
+    *field_type = (QUAL_DECL_TYPE (decl) ?
                   QUAL_DECL_TYPE (decl) : TREE_TYPE (decl));
   return field_ref;
 }
@@ -9327,7 +9429,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
   int is_static;
   tree decl = NULL_TREE, type = NULL_TREE, q;
   /* For certain for of inner class instantiation */
-  tree saved_current, saved_this;              
+  tree saved_current, saved_this;
 #define RESTORE_THIS_AND_CURRENT_CLASS                                 \
   { current_class = saved_current; current_this = saved_this;}
 
@@ -9348,7 +9450,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
             build the code to access it. */
          if (JDECL_P (decl) && !FIELD_STATIC (decl))
            {
-             decl = maybe_access_field (decl, *where_found, 
+             decl = maybe_access_field (decl, *where_found,
                                         DECL_CONTEXT (decl));
              if (decl == error_mark_node)
                return 1;
@@ -9364,7 +9466,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
             saved and restored shortly after */
          saved_current = current_class;
          saved_this = current_this;
-         if (decl 
+         if (decl
              && (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
                  || from_qualified_this))
            {
@@ -9388,6 +9490,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          *where_found = patch_method_invocation (qual_wfl, decl, type,
                                                  from_super,
                                                  &is_static, &ret_decl);
+         from_super = 0;
          if (*where_found == error_mark_node)
            {
              RESTORE_THIS_AND_CURRENT_CLASS;
@@ -9395,12 +9498,14 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
            }
          *type_found = type = QUAL_DECL_TYPE (*where_found);
 
+         *where_found = force_evaluation_order (*where_found);
+
          /* If we're creating an inner class instance, check for that
             an enclosing instance is in scope */
          if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR
              && INNER_ENCLOSING_SCOPE_CHECK (type))
            {
-             parse_error_context 
+             parse_error_context
                (qual_wfl, "No enclosing instance for inner class `%s' is in scope%s",
                 lang_printable_name (type, 0),
                 (!current_this ? "" :
@@ -9414,8 +9519,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          RESTORE_THIS_AND_CURRENT_CLASS;
 
          /* EH check. No check on access$<n> functions */
-         if (location 
-             && !OUTER_FIELD_ACCESS_IDENTIFIER_P 
+         if (location
+             && !OUTER_FIELD_ACCESS_IDENTIFIER_P
                    (DECL_NAME (current_function_decl)))
            check_thrown_exceptions (location, ret_decl);
 
@@ -9509,7 +9614,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
        {
          if (!current_this)
            {
-             parse_error_context 
+             parse_error_context
                (wfl, "Keyword `this' used outside allowed context");
              return 1;
            }
@@ -9519,7 +9624,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
              parse_error_context (wfl, "Can't reference `this' before the superclass constructor has been called");
              return 1;
            }
-         /* We have to generate code for intermediate acess */
+         /* We have to generate code for intermediate access */
          if (!from_type || TREE_TYPE (TREE_TYPE (current_this)) == type)
            {
              *where_found = decl = current_this;
@@ -9532,8 +9637,8 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
              if (!enclosing_context_p (type, current_class))
                {
                  char *p  = xstrdup (lang_printable_name (type, 0));
-                 parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'", 
-                                      p, p, 
+                 parse_error_context (qual_wfl, "Can't use variable `%s.this': type `%s' isn't an outer type of type `%s'",
+                                      p, p,
                                       lang_printable_name (current_class, 0));
                  free (p);
                  return 1;
@@ -9564,12 +9669,12 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          if (METHOD_STATIC (current_function_decl)
              || current_class == object_type_node)
            {
-             parse_error_context 
+             parse_error_context
                (wfl, "Keyword `super' used outside allowed context");
              return 1;
            }
          /* Otherwise, treat SUPER as (SUPER_CLASS)THIS */
-         node = build_cast (EXPR_WFL_LINECOL (qual_wfl), 
+         node = build_cast (EXPR_WFL_LINECOL (qual_wfl),
                             CLASSTYPE_SUPER (current_class),
                             build_this (EXPR_WFL_LINECOL (qual_wfl)));
          *where_found = decl = java_complete_tree (node);
@@ -9584,11 +9689,12 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
         assume a variable/class name was meant. */
       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
        {
-         tree name = resolve_package (wfl, &q);
-         if (name)
+         tree name;
+         if ((decl = resolve_package (wfl, &q, &name)))
            {
              tree list;
-             *where_found = decl = resolve_no_layout (name, qual_wfl);
+             *where_found = decl;
+
              /* We want to be absolutely sure that the class is laid
                  out. We're going to search something inside it. */
              *type_found = type = TREE_TYPE (decl);
@@ -9610,7 +9716,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          else
            {
              if (from_super || from_cast)
-               parse_error_context 
+               parse_error_context
                  ((from_cast ? qual_wfl : wfl),
                   "No variable `%s' defined in class `%s'",
                   IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
@@ -9618,7 +9724,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
              else
                parse_error_context
                  (qual_wfl, "Undefined variable or class name: `%s'",
-                  IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
+                  IDENTIFIER_POINTER (name));
              return 1;
            }
        }
@@ -9632,7 +9738,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          /* Sneak preview. If next we see a `new', we're facing a
             qualification with resulted in a type being selected
             instead of a field.  Report the error */
-         if(TREE_CHAIN (q) 
+         if(TREE_CHAIN (q)
             && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR)
            {
              parse_error_context (qual_wfl, "Undefined variable `%s'",
@@ -9642,7 +9748,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
 
          if (not_accessible_p (TREE_TYPE (decl), decl, type, 0))
            {
-             parse_error_context 
+             parse_error_context
                (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
                 java_accstring_lookup (get_access_flags_from_decl (decl)),
                 GET_TYPE_NAME (type),
@@ -9656,7 +9762,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          from_type = 1;
        }
       /* We resolve an expression name */
-      else 
+      else
        {
          tree field_decl = NULL_TREE;
 
@@ -9714,14 +9820,14 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
 
              if (!from_type && !JREFERENCE_TYPE_P (type))
                {
-                 parse_error_context 
+                 parse_error_context
                    (qual_wfl, "Attempt to reference field `%s' in `%s %s'",
                     IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
                     lang_printable_name (type, 0),
-                    IDENTIFIER_POINTER (DECL_NAME (field_decl)));
+                    IDENTIFIER_POINTER (DECL_NAME (decl)));
                  return 1;
                }
-             
+
              field_decl = lookup_field_wrapper (type,
                                                 EXPR_WFL_NODE (qual_wfl));
 
@@ -9735,7 +9841,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                  inner_decl = resolve_class (decl, ptr, NULL_TREE, qual_wfl);
                  if (inner_decl)
                    {
-                     check_inner_class_access (inner_decl, decl, qual_wfl); 
+                     check_inner_class_access (inner_decl, decl, qual_wfl);
                      type = TREE_TYPE (inner_decl);
                      decl = inner_decl;
                      from_type = 1;
@@ -9745,9 +9851,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
 
              if (field_decl == NULL_TREE)
                {
-                 parse_error_context 
+                 parse_error_context
                    (qual_wfl, "No variable `%s' defined in type `%s'",
-                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
+                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
                     GET_TYPE_NAME (type));
                  return 1;
                }
@@ -9762,37 +9868,37 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
              else
                field_decl_type = TREE_TYPE (field_decl);
-             if (!JPRIMITIVE_TYPE_P (field_decl_type) 
+             if (!JPRIMITIVE_TYPE_P (field_decl_type)
                  && !CLASS_LOADED_P (field_decl_type)
                  && !TYPE_ARRAY_P (field_decl_type))
                resolve_and_layout (field_decl_type, NULL_TREE);
-             
+
              /* Check on accessibility here */
              if (not_accessible_p (current_class, field_decl,
                                    DECL_CONTEXT (field_decl), from_super))
                {
-                 parse_error_context 
+                 parse_error_context
                    (qual_wfl,
                     "Can't access %s field `%s.%s' from `%s'",
-                    java_accstring_lookup 
+                    java_accstring_lookup
                       (get_access_flags_from_decl (field_decl)),
                     GET_TYPE_NAME (type),
                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
-                    IDENTIFIER_POINTER 
+                    IDENTIFIER_POINTER
                       (DECL_NAME (TYPE_NAME (current_class))));
                  return 1;
                }
              check_deprecation (qual_wfl, field_decl);
-             
+
              /* There are things to check when fields are accessed
                 from type. There are no restrictions on a static
                 declaration of the field when it is accessed from an
                 interface */
              is_static = FIELD_STATIC (field_decl);
-             if (!from_super && from_type 
-                 && !TYPE_INTERFACE_P (type) 
-                 && !is_static 
-                 && (current_function_decl 
+             if (!from_super && from_type
+                 && !TYPE_INTERFACE_P (type)
+                 && !is_static
+                 && (current_function_decl
                      && METHOD_STATIC (current_function_decl)))
                {
                  static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
@@ -9837,11 +9943,11 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
 
          /* Sneak preview. If decl is qualified by a `new', report
              the error here to be accurate on the peculiar construct */
-         if (TREE_CHAIN (q) 
+         if (TREE_CHAIN (q)
              && TREE_CODE (TREE_PURPOSE (TREE_CHAIN (q))) == NEW_CLASS_EXPR
              && !JREFERENCE_TYPE_P (type))
            {
-             parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'", 
+             parse_error_context (qual_wfl, "Attempt to reference field `new' in a `%s'",
                                   lang_printable_name (type, 0));
              return 1;
            }
@@ -9877,7 +9983,7 @@ not_accessible_p (reference, member, where, from_super)
   /* Access always granted for members declared public */
   if (access_flag & ACC_PUBLIC)
     return 0;
-  
+
   /* Check access on protected members */
   if (access_flag & ACC_PROTECTED)
     {
@@ -9897,7 +10003,7 @@ not_accessible_p (reference, member, where, from_super)
       if (where && !inherits_from_p (reference, where))
        return 1;
 
-      /* Otherwise, access is granted if occuring from the class where
+      /* Otherwise, access is granted if occurring from the class where
         member is declared or a subclass of it. Find the right
         context to perform the check */
       if (PURE_INNER_CLASS_TYPE_P (reference))
@@ -9926,7 +10032,7 @@ not_accessible_p (reference, member, where, from_super)
       return 1;
     }
 
-  /* Default access are permitted only when occuring within the
+  /* Default access are permitted only when occurring within the
      package in which the type (REFERENCE) is declared. In other words,
      REFERENCE is defined in the current package */
   if (ctxp->package)
@@ -9945,7 +10051,7 @@ check_deprecation (wfl, decl)
   /* Complain if the field is deprecated and the file it was defined
      in isn't compiled at the same time the file which contains its
      use is */
-  if (DECL_DEPRECATED (decl) 
+  if (DECL_DEPRECATED (decl)
       && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
     {
       char the [20];
@@ -9968,8 +10074,8 @@ check_deprecation (wfl, decl)
       /* Don't issue a message if the context as been deprecated as a
          whole. */
       if (! CLASS_DEPRECATED (TYPE_NAME (DECL_CONTEXT (decl))))
-       parse_warning_context 
-         (wfl, "The %s `%s' in class `%s' has been deprecated", 
+       parse_warning_context
+         (wfl, "The %s `%s' in class `%s' has been deprecated",
           the, lang_printable_name (decl, 0),
           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
     }
@@ -9977,15 +10083,15 @@ check_deprecation (wfl, decl)
 
 /* Returns 1 if class was declared in the current package, 0 otherwise */
 
+static GTY(()) tree cicp_cache;
 static int
 class_in_current_package (class)
      tree class;
 {
-  static tree cache = NULL_TREE;
   int qualified_flag;
   tree left;
 
-  if (cache == class)
+  if (cicp_cache == class)
     return 1;
 
   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
@@ -10006,15 +10112,7 @@ class_in_current_package (class)
   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
   if (ctxp->package == left)
     {
-      static int initialized_p;
-      /* Register CACHE with the garbage collector.  */
-      if (!initialized_p)
-       {
-         ggc_add_tree_root (&cache, 1);
-         initialized_p = 1;
-       }
-
-      cache = class;
+      cicp_cache = class;
       return 1;
     }
   return 0;
@@ -10029,7 +10127,7 @@ maybe_access_field (decl, where, type)
 {
   if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
       && !FIELD_STATIC (decl))
-    decl = build_field_ref (where ? where : current_this, 
+    decl = build_field_ref (where ? where : current_this,
                            (type ? type : DECL_CONTEXT (decl)),
                            DECL_NAME (decl));
   return decl;
@@ -10055,7 +10153,7 @@ patch_method_invocation (patch, primary, where, from_super,
   int is_super_init = 0;
   tree this_arg = NULL_TREE;
   int is_array_clone_call = 0;
-  
+
   /* Should be overriden if everything goes well. Otherwise, if
      something fails, it should keep this value. It stop the
      evaluation of a bogus assignment. See java_complete_tree,
@@ -10078,14 +10176,14 @@ patch_method_invocation (patch, primary, where, from_super,
         data during error report. */
       identifier_wfl = cut_identifier_in_qualified (wfl);
       identifier = EXPR_WFL_NODE (identifier_wfl);
-      
+
       /* Given the context, IDENTIFIER is syntactically qualified
         as a MethodName. We need to qualify what's before */
       qualify_ambiguous_name (wfl);
       resolved = resolve_field_access (wfl, NULL, NULL);
 
       if (TREE_CODE (resolved) == VAR_DECL && FIELD_STATIC (resolved)
-         && FIELD_FINAL (resolved) 
+         && FIELD_FINAL (resolved)
          && !inherits_from_p (DECL_CONTEXT (resolved), current_class)
          && !flag_emit_class_files && !flag_emit_xref)
        resolved = build_class_init (DECL_CONTEXT (resolved), resolved);
@@ -10095,14 +10193,14 @@ patch_method_invocation (patch, primary, where, from_super,
 
       type = GET_SKIP_TYPE (resolved);
       resolve_and_layout (type, NULL_TREE);
-      
+
       if (JPRIMITIVE_TYPE_P (type))
         {
          parse_error_context
            (identifier_wfl,
             "Can't invoke a method on primitive type `%s'",
             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
-         PATCH_METHOD_RETURN_ERROR ();         
+         PATCH_METHOD_RETURN_ERROR ();
        }
 
       list = lookup_method_invoke (0, identifier_wfl, type, identifier, args);
@@ -10116,17 +10214,17 @@ patch_method_invocation (patch, primary, where, from_super,
              parse_error_context
                (identifier_wfl,
                "Can't make static reference to method `%s' in interface `%s'",
-                IDENTIFIER_POINTER (identifier), 
+                IDENTIFIER_POINTER (identifier),
                 IDENTIFIER_POINTER (name));
              PATCH_METHOD_RETURN_ERROR ();
            }
          if (list && !METHOD_STATIC (list))
            {
              char *fct_name = xstrdup (lang_printable_name (list, 0));
-             parse_error_context 
+             parse_error_context
                (identifier_wfl,
                 "Can't make static reference to method `%s %s' in class `%s'",
-                lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
+                lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0),
                 fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
              free (fct_name);
              PATCH_METHOD_RETURN_ERROR ();
@@ -10134,10 +10232,10 @@ patch_method_invocation (patch, primary, where, from_super,
        }
       else
        this_arg = primary = resolved;
-      
+
       if (TYPE_ARRAY_P (type) && identifier == get_identifier ("clone"))
         is_array_clone_call = 1;
-      
+
       /* IDENTIFIER_WFL will be used to report any problem further */
       wfl = identifier_wfl;
     }
@@ -10147,13 +10245,13 @@ patch_method_invocation (patch, primary, where, from_super,
     {
       tree class_to_search = NULL_TREE;
       int lc;                  /* Looking for Constructor */
-      
+
       /* We search constructor in their target class */
       if (CALL_CONSTRUCTOR_P (patch))
        {
          if (TREE_CODE (patch) == NEW_CLASS_EXPR)
            class_to_search = EXPR_WFL_NODE (wfl);
-         else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) == 
+         else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
                   this_identifier_node)
            class_to_search = NULL_TREE;
          else if (EXPR_WFL_NODE (TREE_OPERAND (patch, 0)) ==
@@ -10161,7 +10259,7 @@ patch_method_invocation (patch, primary, where, from_super,
            {
              is_super_init = 1;
              if (CLASSTYPE_SUPER (current_class))
-               class_to_search = 
+               class_to_search =
                  DECL_NAME (TYPE_NAME (CLASSTYPE_SUPER (current_class)));
              else
                {
@@ -10177,19 +10275,19 @@ patch_method_invocation (patch, primary, where, from_super,
 
              if (!class_to_search)
                {
-                 parse_error_context 
+                 parse_error_context
                    (wfl, "Class `%s' not found in type declaration",
                     IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
                  PATCH_METHOD_RETURN_ERROR ();
                }
-             
+
              /* Can't instantiate an abstract class, but we can
                 invoke it's constructor. It's use within the `new'
                 context is denied here. */
-             if (CLASS_ABSTRACT (class_to_search) 
+             if (CLASS_ABSTRACT (class_to_search)
                  && TREE_CODE (patch) == NEW_CLASS_EXPR)
                {
-                 parse_error_context 
+                 parse_error_context
                    (wfl, "Class `%s' is an abstract class. It can't be instantiated",
                     IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
                  PATCH_METHOD_RETURN_ERROR ();
@@ -10241,13 +10339,13 @@ patch_method_invocation (patch, primary, where, from_super,
          can't be executed then. */
       if (!list)
        PATCH_METHOD_RETURN_ERROR ();
-      
+
       if (TYPE_ARRAY_P (class_to_search)
           && DECL_NAME (list) == get_identifier ("clone"))
         is_array_clone_call = 1;
 
       /* Check for static reference if non static methods */
-      if (check_for_static_method_reference (wfl, patch, list, 
+      if (check_for_static_method_reference (wfl, patch, list,
                                             class_to_search, primary))
        PATCH_METHOD_RETURN_ERROR ();
 
@@ -10257,7 +10355,7 @@ patch_method_invocation (patch, primary, where, from_super,
          && INNER_ENCLOSING_SCOPE_CHECK (class_to_search)
          && !DECL_INIT_P (current_function_decl))
        {
-         parse_error_context 
+         parse_error_context
            (wfl, "No enclosing instance for inner class `%s' is in scope%s",
             lang_printable_name (class_to_search, 0),
             (!current_this ? "" :
@@ -10285,17 +10383,17 @@ patch_method_invocation (patch, primary, where, from_super,
               x(a1,...,an) into TYPE_OF(this$<n>).x(a1,....an)
 
             2) We're generating bytecodes:
-            
+
             - LIST is non static. It's invocation is transformed from
               x(a1,....,an) into access$<n>(this$<n>,a1,...,an).
             - LIST is static. It's invocation is transformed from
               x(a1,....,an) into TYPE_OF(this$<n>).x(a1,....an).
 
             Of course, this$<n> can be abitrary complex, ranging from
-            this$0 (the immediate outer context) to 
-            access$0(access$0(...(this$0))). 
-            
-            maybe_use_access_method returns a non zero value if the
+            this$0 (the immediate outer context) to
+            access$0(access$0(...(this$0))).
+
+            maybe_use_access_method returns a nonzero value if the
             this_arg has to be moved into the (then generated) stub
             argument list. In the meantime, the selected function
             might have be replaced by a generated stub. */
@@ -10310,13 +10408,13 @@ patch_method_invocation (patch, primary, where, from_super,
 
   /* Merge point of all resolution schemes. If we have nothing, this
      is an error, already signaled */
-  if (!list) 
+  if (!list)
     PATCH_METHOD_RETURN_ERROR ();
 
   /* Check accessibility, position the is_static flag, build and
      return the call */
   if (not_accessible_p (DECL_CONTEXT (current_function_decl), list,
-                       (primary ? TREE_TYPE (TREE_TYPE (primary)) : 
+                       (primary ? TREE_TYPE (TREE_TYPE (primary)) :
                         NULL_TREE), from_super)
       /* Calls to clone() on array types are permitted as a special-case. */
       && !is_array_clone_call)
@@ -10347,7 +10445,7 @@ patch_method_invocation (patch, primary, where, from_super,
 
   /* If invoking a innerclass constructor, there are hidden parameters
      to pass */
-  if (TREE_CODE (patch) == NEW_CLASS_EXPR 
+  if (TREE_CODE (patch) == NEW_CLASS_EXPR
       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
     {
       /* And make sure we add the accessed local variables to be saved
@@ -10390,27 +10488,15 @@ patch_method_invocation (patch, primary, where, from_super,
 
   /* This handles the situation where a constructor invocation needs
      to have an enclosing context passed as a second parameter (the
-     constructor is one of an inner class. We extract it from the
-     current function.  */
-  if ((is_super_init || 
+     constructor is one of an inner class). */
+  if ((is_super_init ||
        (TREE_CODE (patch) == CALL_EXPR && name == this_identifier_node))
       && PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT (list)))
     {
-      tree enclosing_decl = DECL_CONTEXT (TYPE_NAME (current_class));
-      tree extra_arg;
-
-      if (ANONYMOUS_CLASS_P (current_class) || !DECL_CONTEXT (enclosing_decl))
-       {
-         extra_arg = DECL_FUNCTION_BODY (current_function_decl);
-         extra_arg = TREE_CHAIN (BLOCK_EXPR_DECLS (extra_arg));
-       }
-      else
-       {
-         tree dest = TREE_TYPE (DECL_CONTEXT (enclosing_decl));
-         extra_arg = 
-           build_access_to_thisn (TREE_TYPE (enclosing_decl), dest, 0);
-         extra_arg = java_complete_tree (extra_arg);
-       }
+      tree dest = TYPE_NAME (DECL_CONTEXT (list));
+      tree extra_arg =
+       build_access_to_thisn (current_class, DECL_CONTEXT (dest), 0);
+      extra_arg = java_complete_tree (extra_arg);
       args = tree_cons (NULL_TREE, extra_arg, args);
     }
 
@@ -10422,8 +10508,8 @@ patch_method_invocation (patch, primary, where, from_super,
      invoke any method relying on `this'. Exceptions are: we're
      invoking a static function, primary exists and is not the current
      this, we're creating a new object. */
-  if (ctxp->explicit_constructor_p 
-      && !is_static_flag 
+  if (ctxp->explicit_constructor_p
+      && !is_static_flag
       && (!primary || primary == current_this)
       && (TREE_CODE (patch) != NEW_CLASS_EXPR))
     {
@@ -10431,7 +10517,7 @@ patch_method_invocation (patch, primary, where, from_super,
       PATCH_METHOD_RETURN_ERROR ();
     }
   java_parser_context_restore_global ();
-  if (is_static) 
+  if (is_static)
     *is_static = is_static_flag;
   /* Sometimes, we want the decl of the selected method. Such as for
      EH checking */
@@ -10443,21 +10529,21 @@ patch_method_invocation (patch, primary, where, from_super,
   if (is_super_init && CLASS_HAS_FINIT_P (current_class))
     {
       tree finit_parms, finit_call;
-      
+
       /* Prepare to pass hidden parameters to finit$, if any. */
-      finit_parms = build_alias_initializer_parameter_list 
+      finit_parms = build_alias_initializer_parameter_list
        (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
-      
-      finit_call = 
+
+      finit_call =
        build_method_invocation (build_wfl_node (finit_identifier_node),
                                 finit_parms);
 
       /* Generate the code used to initialize fields declared with an
         initialization statement and build a compound statement along
         with the super constructor invocation. */
+      CAN_COMPLETE_NORMALLY (patch) = 1;
       patch = build (COMPOUND_EXPR, void_type_node, patch,
                     java_complete_tree (finit_call));
-      CAN_COMPLETE_NORMALLY (patch) = 1;
     }
   return patch;
 }
@@ -10469,12 +10555,12 @@ static int
 check_for_static_method_reference (wfl, node, method, where, primary)
      tree wfl, node, method, where, primary;
 {
-  if (METHOD_STATIC (current_function_decl) 
+  if (METHOD_STATIC (current_function_decl)
       && !METHOD_STATIC (method) && !primary && !CALL_CONSTRUCTOR_P (node))
     {
       char *fct_name = xstrdup (lang_printable_name (method, 0));
-      parse_error_context 
-       (wfl, "Can't make static reference to method `%s %s' in class `%s'", 
+      parse_error_context
+       (wfl, "Can't make static reference to method `%s %s' in class `%s'",
         lang_printable_name (TREE_TYPE (TREE_TYPE (method)), 0), fct_name,
         IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (where))));
       free (fct_name);
@@ -10498,13 +10584,13 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
   int to_return = 0;
   int non_static_context = !METHOD_STATIC (md);
 
-  if (is_super_init 
+  if (is_super_init
       || DECL_CONTEXT (md) == current_class
-      || !PURE_INNER_CLASS_TYPE_P (current_class) 
+      || !PURE_INNER_CLASS_TYPE_P (current_class)
       || DECL_FINIT_P (md)
       || DECL_INSTINIT_P (md))
     return 0;
-  
+
   /* If we're calling a method found in an enclosing class, generate
      what it takes to retrieve the right this. Don't do that if we're
      invoking a static method. Note that if MD's type is unrelated to
@@ -10529,7 +10615,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
                  ta = build_access_to_thisn (ctx, type, 0);
                  break;
                }
-             type = (DECL_CONTEXT (TYPE_NAME (type)) ? 
+             type = (DECL_CONTEXT (TYPE_NAME (type)) ?
                      TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))) : NULL_TREE);
            }
        }
@@ -10548,7 +10634,7 @@ maybe_use_access_method (is_super_init, mdecl, this_arg)
   *mdecl = md;
   *this_arg = ta;
 
-  /* Returnin a non zero value indicates we were doing a non static
+  /* Returnin a nonzero value indicates we were doing a non static
      method invokation that is now a static invocation. It will have
      callee displace `this' to insert it in the regular argument
      list. */
@@ -10573,7 +10659,7 @@ patch_invoke (patch, method, args)
   t = TYPE_ARG_TYPES (TREE_TYPE (method));
   if (TREE_CODE (patch) == NEW_CLASS_EXPR)
     t = TREE_CHAIN (t);
-  for (ta = args; t != end_params_node && ta; 
+  for (ta = args; t != end_params_node && ta;
        t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
        TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
@@ -10588,7 +10674,6 @@ patch_invoke (patch, method, args)
     func = method;
   else
     {
-      tree signature = build_java_signature (TREE_TYPE (method));
       switch (invocation_mode (method, CALL_USING_SUPER (patch)))
        {
        case INVOKE_VIRTUAL:
@@ -10613,9 +10698,12 @@ patch_invoke (patch, method, args)
 
        case INVOKE_SUPER:
        case INVOKE_STATIC:
-         func = build_known_method_ref (method, TREE_TYPE (method),
-                                        DECL_CONTEXT (method),
-                                        signature, args);
+         {
+           tree signature = build_java_signature (TREE_TYPE (method));
+           func = build_known_method_ref (method, TREE_TYPE (method),
+                                          DECL_CONTEXT (method),
+                                          signature, args);
+         }
          break;
 
        case INVOKE_INTERFACE:
@@ -10634,6 +10722,7 @@ patch_invoke (patch, method, args)
   TREE_TYPE (patch) = TREE_TYPE (TREE_TYPE (method));
   TREE_OPERAND (patch, 0) = func;
   TREE_OPERAND (patch, 1) = args;
+  patch = check_for_builtin (method, patch);
   original_call = patch;
 
   /* We're processing a `new TYPE ()' form. New is called and its
@@ -10645,6 +10734,8 @@ patch_invoke (patch, method, args)
     {
       tree class = DECL_CONTEXT (method);
       tree c1, saved_new, size, new;
+      tree alloc_node;
+
       if (flag_emit_class_files || flag_emit_xref)
        {
          TREE_TYPE (patch) = build_pointer_type (class);
@@ -10653,10 +10744,13 @@ patch_invoke (patch, method, args)
       if (!TYPE_SIZE (class))
        safe_layout_class (class);
       size = size_in_bytes (class);
+      alloc_node =
+       (class_has_finalize_method (class) ? alloc_object_node
+                                          : alloc_no_finalizer_node);
       new = build (CALL_EXPR, promote_type (class),
-                  build_address_of (alloc_object_node),
+                  build_address_of (alloc_node),
                   tree_cons (NULL_TREE, build_class_ref (class),
-                             build_tree_list (NULL_TREE, 
+                             build_tree_list (NULL_TREE,
                                               size_in_bytes (class))),
                   NULL_TREE);
       saved_new = save_expr (new);
@@ -10671,7 +10765,11 @@ patch_invoke (patch, method, args)
      is NULL.  */
   if (check != NULL_TREE)
     {
-      patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, patch);
+      /* We have to call force_evaluation_order now because creating a
+        COMPOUND_EXPR wraps the arg list in a way that makes it
+        unrecognizable by force_evaluation_order later.  Yuk.  */
+      patch = build (COMPOUND_EXPR, TREE_TYPE (patch), check, 
+                    force_evaluation_order (patch));
       TREE_SIDE_EFFECTS (patch) = 1;
     }
 
@@ -10687,14 +10785,17 @@ patch_invoke (patch, method, args)
     {
       tree list;
       tree fndecl = current_function_decl;
-      tree save = save_expr (patch);
+      /* We have to call force_evaluation_order now because creating a
+        COMPOUND_EXPR wraps the arg list in a way that makes it
+        unrecognizable by force_evaluation_order later.  Yuk.  */
+      tree save = save_expr (force_evaluation_order (patch));
       tree type = TREE_TYPE (patch);
 
       patch = build (COMPOUND_EXPR, type, save, empty_stmt_node);
-      list = build_tree_list (method, patch);
+      list = tree_cons (method, patch,
+                       DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl));
 
-      hash_lookup (&DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl),
-                  (const hash_table_key) list, TRUE, NULL);
+      DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = list;
 
       patch = build (COMPOUND_EXPR, type, patch, save);
     }
@@ -10764,7 +10865,14 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
      know the arguments' types. */
 
   if (lc && ANONYMOUS_CLASS_P (class))
-    craft_constructor (TYPE_NAME (class), atl);
+    {
+      tree saved_current_class;
+      tree mdecl = craft_constructor (TYPE_NAME (class), atl);
+      saved_current_class = current_class;
+      current_class = class;
+      fix_constructors (mdecl);
+      current_class = saved_current_class;
+    }
 
   /* Find all candidates and then refine the list, searching for the
      most specific method. */
@@ -10787,7 +10895,7 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
          char string [4096];
          if (!cm || not_accessible_p (class, cm, NULL_TREE, 0))
            continue;
-         sprintf 
+         sprintf
            (string, "  `%s' in `%s'%s",
             get_printable_method_name (cm),
             IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (cm)))),
@@ -10819,28 +10927,25 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
      int lc;
      tree class, name, arglist;
 {
-  static struct hash_table t, *searched_classes = NULL;
+  static htab_t searched_classes;
   static int search_not_done = 0;
   tree list = NULL_TREE, all_list = NULL_TREE;
 
-  /* Check the hash table to determine if this class has been searched 
+  /* Check the hash table to determine if this class has been searched
      already. */
   if (searched_classes)
     {
-      if (hash_lookup (searched_classes, 
-                      (const hash_table_key) class, FALSE, NULL))
-       return NULL;
+      if (htab_find (searched_classes, class) != NULL)
+       return NULL;
     }
   else
     {
-      hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
-                      java_hash_compare_tree_node);
-      searched_classes = &t;
+      searched_classes = htab_create (10, htab_hash_pointer,
+                                     htab_eq_pointer, NULL);
     }
-    
+
   search_not_done++;
-  hash_lookup (searched_classes, 
-              (const hash_table_key) class, TRUE, NULL);
+  *htab_find_slot (searched_classes, class, INSERT) = class;
 
   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
     {
@@ -10849,12 +10954,12 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
     }
 
   /* Search interfaces */
-  if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL 
+  if (TREE_CODE (TYPE_NAME (class)) == TYPE_DECL
       && CLASS_INTERFACE (TYPE_NAME (class)))
     {
       int i, n;
       tree basetype_vec = TYPE_BINFO_BASETYPES (class);
-      search_applicable_methods_list (lc, TYPE_METHODS (class), 
+      search_applicable_methods_list (lc, TYPE_METHODS (class),
                                      name, arglist, &list, &all_list);
       n = TREE_VEC_LENGTH (basetype_vec);
       for (i = 1; i < n; i++)
@@ -10862,7 +10967,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
          tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
          tree rlist;
 
-         rlist = find_applicable_accessible_methods_list (lc,  t, name, 
+         rlist = find_applicable_accessible_methods_list (lc,  t, name,
                                                           arglist);
          list = chainon (rlist, list);
        }
@@ -10870,7 +10975,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
   /* Search classes */
   else
     {
-      search_applicable_methods_list (lc, TYPE_METHODS (class), 
+      search_applicable_methods_list (lc, TYPE_METHODS (class),
                                      name, arglist, &list, &all_list);
 
       /* When looking finit$, class$ or instinit$, we turn LC to 1 so
@@ -10906,7 +11011,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
        {
           tree rlist;
           class = CLASSTYPE_SUPER (class);
-          rlist = find_applicable_accessible_methods_list (lc, class, 
+          rlist = find_applicable_accessible_methods_list (lc, class,
                                                            name, arglist);
           list = chainon (rlist, list);
         }
@@ -10920,15 +11025,13 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
     {
       if (!lc
          && TYPE_METHODS (object_type_node)
-         && !hash_lookup (searched_classes, 
-                           (const hash_table_key) object_type_node, 
-                           FALSE, NULL))
+         && htab_find (searched_classes, object_type_node) == NULL)
        {
-          search_applicable_methods_list (lc, 
+          search_applicable_methods_list (lc,
                                           TYPE_METHODS (object_type_node),
                                           name, arglist, &list, &all_list);
         }
-      hash_table_free (searched_classes);
+      htab_delete (searched_classes);
       searched_classes = NULL;
     }
 
@@ -10939,7 +11042,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
 
 /* Effectively search for the appropriate method in method */
 
-static void 
+static void
 search_applicable_methods_list (lc, method, name, arglist, list, all_list)
      int lc;
      tree method, name, arglist;
@@ -10951,14 +11054,14 @@ search_applicable_methods_list (lc, method, name, arglist, list, all_list)
          other classes */
       if (lc && !DECL_CONSTRUCTOR_P (method))
        continue;
-      else if (!lc && (DECL_CONSTRUCTOR_P (method) 
+      else if (!lc && (DECL_CONSTRUCTOR_P (method)
                       || (DECL_NAME (method) != name)))
        continue;
 
       if (argument_types_convertible (method, arglist))
        {
          /* Retain accessible methods only */
-         if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
+         if (!not_accessible_p (DECL_CONTEXT (current_function_decl),
                                 method, NULL_TREE, 0))
            *list = tree_cons (NULL_TREE, method, *list);
          else
@@ -10995,13 +11098,13 @@ find_most_specific_methods_list (list)
          /* Compare arguments and location where methods where declared */
          if (argument_types_convertible (method_v, current_v))
            {
-             if (valid_method_invocation_conversion_p 
+             if (valid_method_invocation_conversion_p
                  (DECL_CONTEXT (method_v), DECL_CONTEXT (current_v))
                  || (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v))
                      && enclosing_context_p (DECL_CONTEXT (method_v),
                                              DECL_CONTEXT (current_v))))
                {
-                 int v = (DECL_SPECIFIC_COUNT (current_v) += 
+                 int v = (DECL_SPECIFIC_COUNT (current_v) +=
                    (INNER_CLASS_TYPE_P (DECL_CONTEXT (current_v)) ? 2 : 1));
                  max = (v > max ? v : max);
                }
@@ -11058,25 +11161,15 @@ find_most_specific_methods_list (list)
    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
    to change less often than M1. */
 
+static GTY(()) tree m2_arg_value;
+static GTY(()) tree m2_arg_cache;
+
 static int
 argument_types_convertible (m1, m2_or_arglist)
     tree m1, m2_or_arglist;
 {
-  static tree m2_arg_value = NULL_TREE;
-  static tree m2_arg_cache = NULL_TREE;
-  static int initialized_p;
-
   register tree m1_arg, m2_arg;
 
-  /* Register M2_ARG_VALUE and M2_ARG_CACHE with the garbage
-     collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&m2_arg_value, 1);
-      ggc_add_tree_root (&m2_arg_cache, 1);
-      initialized_p = 1;
-    }
-
   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
 
   if (m2_arg_value == m2_or_arglist)
@@ -11141,7 +11234,9 @@ qualify_ambiguous_name (id)
       {
       case CALL_EXPR:
        qual_wfl = TREE_OPERAND (qual_wfl, 0);
-       if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
+       if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION
+           || (EXPR_WFL_QUALIFICATION (qual_wfl)
+               && TREE_CODE (EXPR_WFL_QUALIFICATION (qual_wfl)) == TREE_LIST))
          {
            qual = EXPR_WFL_QUALIFICATION (qual_wfl);
            qual_wfl = QUAL_WFL (qual);
@@ -11185,11 +11280,17 @@ qualify_ambiguous_name (id)
 
     else if (code == INTEGER_CST)
       name = qual_wfl;
-    
+
     else if (code == CONVERT_EXPR &&
             TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
       name = TREE_OPERAND (qual_wfl, 0);
-    
+
+    else if (code == CONVERT_EXPR
+            && TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == CALL_EXPR
+            && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0))
+                == EXPR_WITH_FILE_LOCATION))
+      name = TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0);
+
     else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
             TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
       name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
@@ -11197,7 +11298,7 @@ qualify_ambiguous_name (id)
     else if (code == TREE_LIST)
       name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
 
-    else if (code == STRING_CST || code == CONDITIONAL_EXPR 
+    else if (code == STRING_CST || code == CONDITIONAL_EXPR
             || code == PLUS_EXPR)
       {
        qual = TREE_CHAIN (qual);
@@ -11222,7 +11323,7 @@ qualify_ambiguous_name (id)
        if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
            && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
               EXPR_WITH_FILE_LOCATION
-           && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) == 
+           && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
               this_identifier_node)
            {
              qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
@@ -11255,12 +11356,12 @@ qualify_ambiguous_name (id)
        super_found = again = 1;
       }
   } while (again);
-  
+
   /* If name appears within the scope of a local variable declaration
      or parameter declaration, then it is an expression name. We don't
      carry this test out if we're in the context of the use of SUPER
      or THIS */
-  if (!this_found && !super_found 
+  if (!this_found && !super_found
       && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
       && (decl = IDENTIFIER_LOCAL_VALUE (name)))
     {
@@ -11286,7 +11387,7 @@ qualify_ambiguous_name (id)
      - NAME is declared in an another compilation unit of the package
        of the compilation unit containing NAME,
      - NAME is declared by exactly on type-import-on-demand declaration
-     of the compilation unit containing NAME. 
+     of the compilation unit containing NAME.
      - NAME is actually a STRING_CST.
      This can't happen if the expression was qualified by `this.' */
   else if (! this_found &&
@@ -11310,7 +11411,7 @@ qualify_ambiguous_name (id)
      containing NAME. FIXME */
 
   /* Otherwise, NAME is reclassified as a package name */
-  else 
+  else
     RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
 
   /* Propagate the qualification accross other components of the
@@ -11320,7 +11421,7 @@ qualify_ambiguous_name (id)
     {
       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
        RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
-      else 
+      else
        RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
     }
 
@@ -11342,17 +11443,17 @@ breakdown_qualified (left, right, source)
     tree *left, *right, source;
 {
   char *p, *base;
-  int   l = IDENTIFIER_LENGTH (source);
+  int l = IDENTIFIER_LENGTH (source);
 
   base = alloca (l + 1);
   memcpy (base, IDENTIFIER_POINTER (source), l + 1);
 
-  /* Breakdown NAME into REMAINDER . IDENTIFIER */
+  /* Breakdown NAME into REMAINDER . IDENTIFIER */
   p = base + l - 1;
   while (*p != '.' && p != base)
     p--;
 
-  /* We didn't find a '.'. Return an error */
+  /* We didn't find a '.'. Return an error */
   if (p == base)
     return 1;
 
@@ -11360,7 +11461,7 @@ breakdown_qualified (left, right, source)
   if (right)
     *right = get_identifier (p+1);
   *left = get_identifier (base);
-  
+
   return 0;
 }
 
@@ -11373,7 +11474,7 @@ in_same_package (name1, name2)
   tree tmp;
   tree pkg1;
   tree pkg2;
-  
+
   if (TREE_CODE (name1) == TYPE_DECL)
     name1 = DECL_NAME (name1);
   if (TREE_CODE (name2) == TYPE_DECL)
@@ -11389,7 +11490,7 @@ in_same_package (name1, name2)
 
   breakdown_qualified (&pkg1, &tmp, name1);
   breakdown_qualified (&pkg2, &tmp, name2);
-  
+
   return (pkg1 == pkg2);
 }
 
@@ -11406,22 +11507,9 @@ java_complete_tree (node)
       && DECL_INITIAL (node) != NULL_TREE
       && !flag_emit_xref)
     {
-      tree value = DECL_INITIAL (node);
-      DECL_INITIAL (node) = NULL_TREE;
-      value = fold_constant_for_init (value, node);
-      DECL_INITIAL (node) = value;
+      tree value = fold_constant_for_init (node, node);
       if (value != NULL_TREE)
-       {
-         /* fold_constant_for_init sometimes widens the original type
-             of the constant (i.e. byte to int). It's not desirable,
-             especially if NODE is a function argument. */
-         if ((TREE_CODE (value) == INTEGER_CST
-              || TREE_CODE (value) == REAL_CST)
-             && TREE_TYPE (node) != TREE_TYPE (value))
-           return convert (TREE_TYPE (node), value);
-         else
-           return value;
-       }
+       return value;
     }
   return node;
 }
@@ -11482,7 +11570,7 @@ java_complete_lhs (node)
          int error_seen = 0;
          if (TREE_CODE (stmt) == COMPOUND_EXPR)
            {
-             /* Re-order from (((A; B); C); ...; Z) to 
+             /* Re-order from (((A; B); C); ...; Z) to
                 (A; (B; (C ; (...; Z)))).
                 This makes it easier to scan the statements left-to-right
                 without using recursion (which might overflow the stack
@@ -11628,11 +11716,11 @@ java_complete_lhs (node)
       nn = ctxp->current_loop;
 
       /* It must be assignable to the type of the switch expression. */
-      if (!try_builtin_assignconv (NULL_TREE, 
+      if (!try_builtin_assignconv (NULL_TREE,
                                   TREE_TYPE (TREE_OPERAND (nn, 0)), cn))
        {
          EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
-         parse_error_context 
+         parse_error_context
            (wfl_operator,
             "Incompatible type for case. Can't convert `%s' to `int'",
             lang_printable_name (TREE_TYPE (cn), 0));
@@ -11663,7 +11751,7 @@ java_complete_lhs (node)
       if (SWITCH_HAS_DEFAULT (nn))
        {
          EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
-         parse_error_context (wfl_operator, 
+         parse_error_context (wfl_operator,
                               "Duplicate case label: `default'");
          return error_mark_node;
        }
@@ -11738,7 +11826,7 @@ java_complete_lhs (node)
       /* 3- Expression section */
     case COMPOUND_EXPR:
       wfl_op2 = TREE_OPERAND (node, 1);
-      TREE_OPERAND (node, 0) = nn = 
+      TREE_OPERAND (node, 0) = nn =
        java_complete_tree (TREE_OPERAND (node, 0));
       if (wfl_op2 == empty_stmt_node)
        CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
@@ -11754,14 +11842,28 @@ java_complete_lhs (node)
              if (TREE_CODE (nn) != EXIT_EXPR)
                {
                  SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
-                 parse_error_context (wfl_operator, "Unreachable statement");
+                 if (SUPPRESS_UNREACHABLE_ERROR (nn))
+                   {
+                     /* Perhaps this warning should have an
+                        associated flag.  The code being compiled is
+                        pedantically correct, but useless.  */
+                     parse_warning_context (wfl_operator,
+                                            "Unreachable statement");
+                   }
+                 else
+                   parse_error_context (wfl_operator,
+                                        "Unreachable statement");
                }
            }
          TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
          if (TREE_OPERAND (node, 1) == error_mark_node)
            return error_mark_node;
+         /* Even though we might allow the case where the first
+            operand doesn't return normally, we still should compute
+            CAN_COMPLETE_NORMALLY correctly.  */
          CAN_COMPLETE_NORMALLY (node)
-           = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
+           = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
+              && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
        }
       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
       break;
@@ -11811,7 +11913,7 @@ java_complete_lhs (node)
            }
          else
            TREE_TYPE (node) = TREE_TYPE (EXPR_WFL_NODE (node));
-         
+
        }
       break;
 
@@ -11821,7 +11923,7 @@ java_complete_lhs (node)
       for (cn = TREE_OPERAND (node, 1); cn; cn = TREE_CHAIN (cn))
        {
          int location = EXPR_WFL_LINECOL (TREE_VALUE (cn));
-         tree dim = convert (int_type_node, 
+         tree dim = convert (int_type_node,
                              java_complete_tree (TREE_VALUE (cn)));
          if (dim == error_mark_node)
            {
@@ -11833,7 +11935,7 @@ java_complete_lhs (node)
              TREE_VALUE (cn) = dim;
              /* Setup the location of the current dimension, for
                 later error report. */
-             TREE_PURPOSE (cn) = 
+             TREE_PURPOSE (cn) =
                build_expr_wfl (NULL_TREE, input_filename, 0, 0);
              EXPR_WFL_LINECOL (TREE_PURPOSE (cn)) = location;
            }
@@ -11882,8 +11984,8 @@ java_complete_lhs (node)
          check_thrown_exceptions (EXPR_WFL_LINECOL (node), decl);
          /* If we call this(...), register signature and positions */
          if (in_this)
-           DECL_CONSTRUCTOR_CALLS (current_function_decl) = 
-             tree_cons (wfl, decl, 
+           DECL_CONSTRUCTOR_CALLS (current_function_decl) =
+             tree_cons (wfl, decl,
                         DECL_CONSTRUCTOR_CALLS (current_function_decl));
          CAN_COMPLETE_NORMALLY (node) = 1;
          return force_evaluation_order (node);
@@ -11893,20 +11995,20 @@ java_complete_lhs (node)
       /* Save potential wfls */
       wfl_op1 = TREE_OPERAND (node, 0);
       TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
-      
+
       if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
          && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
          && DECL_INITIAL (nn) != NULL_TREE)
        {
          tree value;
-         
+
          value = fold_constant_for_init (nn, nn);
 
          /* When we have a primitype type, or a string and we're not
              emitting a class file, we actually don't want to generate
              anything for the assignment. */
          if (value != NULL_TREE &&
-             (JPRIMITIVE_TYPE_P (TREE_TYPE (value)) || 
+             (JPRIMITIVE_TYPE_P (TREE_TYPE (value)) ||
               (TREE_TYPE (value) == string_ptr_type_node &&
                ! flag_emit_class_files)))
            {
@@ -11942,11 +12044,11 @@ java_complete_lhs (node)
        {
          /* This might break when accessing outer field from inner
              class. TESTME, FIXME */
-         tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
+         tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0));
 
          /* Hand stabilize the lhs on both places */
          TREE_OPERAND (node, 0) = lvalue;
-         TREE_OPERAND (TREE_OPERAND (node, 1), 0) = 
+         TREE_OPERAND (TREE_OPERAND (node, 1), 0) =
            (flag_emit_class_files ? lvalue : save_expr (lvalue));
 
          /* 15.25.2.a: Left hand is not an array access. FIXME */
@@ -11956,9 +12058,9 @@ java_complete_lhs (node)
          if ((cn = patch_string (nn)))
            nn = cn;
 
-         /* The last part of the rewrite for E1 op= E2 is to have 
+         /* The last part of the rewrite for E1 op= E2 is to have
             E1 = (T)(E1 op E2), with T being the type of E1. */
-         nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), 
+         nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2),
                                               TREE_TYPE (lvalue), nn));
 
          /* If the assignment is compound and has reference type,
@@ -12009,8 +12111,10 @@ java_complete_lhs (node)
       else
        {
          node = patch_assignment (node, wfl_op1);
+         if (node == error_mark_node)
+           return error_mark_node;
          /* Reorganize the tree if necessary. */
-         if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) 
+         if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node))
                       || JSTRING_P (TREE_TYPE (node))))
            node = java_refold (node);
        }
@@ -12019,9 +12123,9 @@ java_complete_lhs (node)
         undergone a conversion in patch_assignment. We do that only when
         it's necessary to have DECL_INITIAL properly set. */
       nn = TREE_OPERAND (node, 0);
-      if (TREE_CODE (nn) == VAR_DECL 
+      if (TREE_CODE (nn) == VAR_DECL
          && DECL_INITIAL (nn) && CONSTANT_VALUE_P (DECL_INITIAL (nn))
-         && FIELD_STATIC (nn) && FIELD_FINAL (nn) 
+         && FIELD_STATIC (nn) && FIELD_FINAL (nn)
          && (JPRIMITIVE_TYPE_P (TREE_TYPE (nn))
              || TREE_TYPE (nn) == string_ptr_type_node))
        DECL_INITIAL (nn) = TREE_OPERAND (node, 1);
@@ -12043,7 +12147,7 @@ java_complete_lhs (node)
     case RDIV_EXPR:
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
-    case EQ_EXPR: 
+    case EQ_EXPR:
     case NE_EXPR:
     case GT_EXPR:
     case GE_EXPR:
@@ -12162,13 +12266,13 @@ java_complete_lhs (node)
       if (ctxp->explicit_constructor_p)
        {
          EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
-         parse_error_context 
+         parse_error_context
            (wfl_operator, "Can't reference `this' or `super' before the superclass constructor has been called");
          TREE_TYPE (node) = error_mark_node;
          return error_mark_node;
        }
       return current_this;
-      
+
     case CLASS_LITERAL:
       CAN_COMPLETE_NORMALLY (node) = 1;
       node = patch_incomplete_class_ref (node);
@@ -12188,7 +12292,7 @@ java_complete_lhs (node)
   return node;
 }
 
-/* Complete function call's argument. Return a non zero value is an
+/* Complete function call's argument. Return a nonzero value is an
    error was found.  */
 
 static int
@@ -12252,7 +12356,7 @@ build_expr_block (body, decls)
   return node;
 }
 
-/* Create a new function block and link it approriately to current
+/* Create a new function block and link it appropriately to current
    function block chain */
 
 static tree
@@ -12265,7 +12369,7 @@ enter_block ()
      for the first time for a given function. The current function body
      (DECL_FUNCTION_BODY) is set to be block B.  */
 
-  tree fndecl = current_function_decl; 
+  tree fndecl = current_function_decl;
 
   if (!fndecl) {
     BLOCK_SUPERCONTEXT (b) = current_static_block;
@@ -12327,7 +12431,7 @@ lookup_name_in_blocks (name)
       if (TREE_CODE (b) != BLOCK)
        abort ();
 
-      for (current = BLOCK_EXPR_DECLS (b); current; 
+      for (current = BLOCK_EXPR_DECLS (b); current;
           current = TREE_CHAIN (current))
        if (DECL_NAME (current) == name)
          return current;
@@ -12360,7 +12464,7 @@ build_wfl_wrap (node, location)
     int location;
 {
   tree wfl, node_to_insert = node;
-  
+
   /* We want to process THIS . xxx symbolicaly, to keep it consistent
      with the way we're processing SUPER. A THIS from a primary as a
      different form than a SUPER. Turn THIS into something symbolic */
@@ -12408,7 +12512,7 @@ build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
      int lloc, rloc;
 {
   tree invok;
-  tree wfl = 
+  tree wfl =
     build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
   EXPR_WFL_LINECOL (wfl) = lloc;
   invok = build_method_invocation (name, args);
@@ -12462,8 +12566,82 @@ build_assignment (op, op_location, lhs, rhs)
   return assignment;
 }
 
-/* Print an INTEGER_CST node in a static buffer, and return the buffer. */
+/* Print an INTEGER_CST node as decimal in a static buffer, and return
+   the buffer.  This is used only for string conversion.  */
+static char *
+string_convert_int_cst (node)
+     tree node;
+{
+  static char buffer[80];
+
+  unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (node);
+  unsigned HOST_WIDE_INT hi = TREE_INT_CST_HIGH (node);
+  char *p = buffer + sizeof (buffer) - 1;
+  int neg = 0;
+
+  unsigned HOST_WIDE_INT hibit = (((unsigned HOST_WIDE_INT) 1)
+                                 << (HOST_BITS_PER_WIDE_INT - 1));
 
+  *p-- = '\0';
+
+  /* If negative, note the fact and negate the value.  */
+  if ((hi & hibit))
+    {
+      lo = ~lo;
+      hi = ~hi;
+      if (++lo == 0)
+       ++hi;
+      neg = 1;
+    }
+
+  /* Divide by 10 until there are no bits left.  */
+  while (hi || lo)
+    {
+      unsigned HOST_WIDE_INT acc = 0;
+      unsigned HOST_WIDE_INT outhi = 0, outlo = 0;
+      unsigned int i;
+
+      /* Use long division to compute the result and the remainder.  */
+      for (i = 0; i < 2 * HOST_BITS_PER_WIDE_INT; ++i)
+       {
+         /* Shift a bit into accumulator.  */
+         acc <<= 1;
+         if ((hi & hibit))
+           acc |= 1;
+
+         /* Shift the value.  */
+         hi <<= 1;
+         if ((lo & hibit))
+           hi |= 1;
+         lo <<= 1;
+
+         /* Shift the correct bit into the result.  */
+         outhi <<= 1;
+         if ((outlo & hibit))
+           outhi |= 1;
+         outlo <<= 1;
+         if (acc >= 10)
+           {
+             acc -= 10;
+             outlo |= 1;
+           }
+       }
+
+      /* FIXME: ASCII assumption.  */
+      *p-- = '0' + acc;
+
+      hi = outhi;
+      lo = outlo;
+    }
+
+  if (neg)
+    *p-- = '-';
+
+  return p + 1;
+}
+
+/* Print an INTEGER_CST node in a static buffer, and return the
+   buffer.  This is used only for error handling.  */
 char *
 print_int_node (node)
     tree node;
@@ -12471,7 +12649,7 @@ print_int_node (node)
   static char buffer [80];
   if (TREE_CONSTANT_OVERFLOW (node))
     sprintf (buffer, "<overflow>");
-    
+
   if (TREE_INT_CST_HIGH (node) == 0)
     sprintf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED,
             TREE_INT_CST_LOW (node));
@@ -12505,6 +12683,7 @@ patch_assignment (node, wfl_op1)
   tree lhs_type = NULL_TREE, rhs_type, new_rhs = NULL_TREE;
   int error_found = 0;
   int lvalue_from_array = 0;
+  int is_return = 0;
 
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
 
@@ -12513,9 +12692,8 @@ patch_assignment (node, wfl_op1)
     {
       lhs_type = TREE_TYPE (lvalue);
     }
-  /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
-     comment on reason why */
-  else if (TREE_CODE (wfl_op1) == ARRAY_REF)
+  /* Or Lhs can be an array access. */
+  else if (TREE_CODE (lvalue) == ARRAY_REF)
     {
       lhs_type = TREE_TYPE (lvalue);
       lvalue_from_array = 1;
@@ -12525,7 +12703,15 @@ patch_assignment (node, wfl_op1)
     lhs_type = TREE_TYPE (lvalue);
   /* Or a function return slot */
   else if (TREE_CODE (lvalue) == RESULT_DECL)
-    lhs_type = TREE_TYPE (lvalue);
+    {
+      /* If the return type is an integral type, then we create the
+        RESULT_DECL with a promoted type, but we need to do these
+        checks against the unpromoted type to ensure type safety.  So
+        here we look at the real type, not the type of the decl we
+        are modifying.  */
+      lhs_type = TREE_TYPE (TREE_TYPE (current_function_decl));
+      is_return = 1;
+    }
   /* Otherwise, we might want to try to write into an optimized static
      final, this is an of a different nature, reported further on. */
   else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION
@@ -12533,13 +12719,14 @@ patch_assignment (node, wfl_op1)
     {
       lhs_type = TREE_TYPE (lvalue);
     }
-  else 
+  else
     {
       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
       error_found = 1;
     }
 
   rhs_type = TREE_TYPE (rhs);
+
   /* 5.1 Try the assignment conversion for builtin type. */
   new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);
 
@@ -12577,7 +12764,7 @@ patch_assignment (node, wfl_op1)
          wfl = wfl_operator;
          if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))
            strcpy (operation, "assignment");
-         else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)
+         else if (is_return)
            strcpy (operation, "`return'");
          else
            strcpy (operation, "`='");
@@ -12597,91 +12784,48 @@ patch_assignment (node, wfl_op1)
   if (error_found)
     return error_mark_node;
 
+  /* If we're processing a `return' statement, promote the actual type
+     to the promoted type.  */
+  if (is_return)
+    new_rhs = convert (TREE_TYPE (lvalue), new_rhs);
+
   /* 10.10: Array Store Exception runtime check */
   if (!flag_emit_class_files
       && !flag_emit_xref
-      && lvalue_from_array 
+      && lvalue_from_array
       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
     {
-      tree check;
-      tree base = lvalue;
+      tree array, store_check, base, index_expr;
 
-      /* We need to retrieve the right argument for
-         _Jv_CheckArrayStore.  This is somewhat complicated by bounds
-         and null pointer checks, both of which wrap the operand in
-         one layer of COMPOUND_EXPR.  */
-      if (TREE_CODE (lvalue) == COMPOUND_EXPR)
-       base = TREE_OPERAND (lvalue, 0);
-      else
-       {
-          tree op = TREE_OPERAND (base, 0);
-         
-          /* We can have a SAVE_EXPR here when doing String +=.  */
-          if (TREE_CODE (op) == SAVE_EXPR)
-            op = TREE_OPERAND (op, 0);
-         /* We can have a COMPOUND_EXPR here when doing bounds check. */
-         if (TREE_CODE (op) == COMPOUND_EXPR)
-           op = TREE_OPERAND (op, 1);
-         base = TREE_OPERAND (op, 0);
-         /* Strip the last PLUS_EXPR to obtain the base. */
-         if (TREE_CODE (base) == PLUS_EXPR)
-           base = TREE_OPERAND (base, 0);
-       }
-
-      /* Build the invocation of _Jv_CheckArrayStore */
+      /* Save RHS so that it doesn't get re-evaluated by the store check. */
       new_rhs = save_expr (new_rhs);
-      check = build (CALL_EXPR, void_type_node,
-                    build_address_of (soft_checkarraystore_node),
-                    tree_cons (NULL_TREE, base,
-                               build_tree_list (NULL_TREE, new_rhs)),
-                    NULL_TREE);
-      TREE_SIDE_EFFECTS (check) = 1;
-
-      /* We have to decide on an insertion point */
-      if (TREE_CODE (lvalue) == COMPOUND_EXPR)
-       {
-         tree t;
-         if (flag_bounds_check)
-           {
-             t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);
-             TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =
-               build (COMPOUND_EXPR, void_type_node, t, check);
-           }
-         else
-           TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,
-                                             check, TREE_OPERAND (lvalue, 1));
-       }
-      else if (flag_bounds_check)
-       {
-          tree hook = lvalue;
-          tree compound = TREE_OPERAND (lvalue, 0);
-          tree bound_check, new_compound;
 
-          if (TREE_CODE (compound) == SAVE_EXPR)
-            {
-              compound = TREE_OPERAND (compound, 0);
-              hook = TREE_OPERAND (hook, 0);
-            }
-
-          /* Find the array bound check, hook the original array access. */
-          bound_check = TREE_OPERAND (compound, 0);
-          TREE_OPERAND (hook, 0) = TREE_OPERAND (compound, 1);
+      /* Get the INDIRECT_REF. */
+      array = TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0);
+      /* Get the array pointer expr. */
+      array = TREE_OPERAND (array, 0);
+      store_check = build_java_arraystore_check (array, new_rhs);
 
-         /* Make sure the bound check will happen before the store check */
-          new_compound =
-            build (COMPOUND_EXPR, void_type_node, bound_check, check);
+      index_expr = TREE_OPERAND (lvalue, 1);
 
-          /* Re-assemble the augmented array access. */
-          lvalue = build (COMPOUND_EXPR, TREE_TYPE (lvalue),
-                         new_compound, lvalue);
-        }
+      if (TREE_CODE (index_expr) == COMPOUND_EXPR)
+       {
+         /* A COMPOUND_EXPR here is a bounds check. The bounds check must
+            happen before the store check, so prepare to insert the store
+            check within the second operand of the existing COMPOUND_EXPR. */
+         base = index_expr;
+       }
       else
-        lvalue = build (COMPOUND_EXPR, TREE_TYPE (lvalue), check, lvalue);
+        base = lvalue;
+
+      index_expr = TREE_OPERAND (base, 1);
+      TREE_OPERAND (base, 1) = build (COMPOUND_EXPR, TREE_TYPE (index_expr),
+                                     store_check, index_expr);
     }
 
   /* Final locals can be used as case values in switch
      statement. Prepare them for this eventuality. */
-  if (TREE_CODE (lvalue) == VAR_DECL 
+  if (TREE_CODE (lvalue) == VAR_DECL
       && DECL_FINAL (lvalue)
       && TREE_CONSTANT (new_rhs)
       && IDENTIFIER_LOCAL_VALUE (DECL_NAME (lvalue))
@@ -12745,31 +12889,28 @@ try_builtin_assignconv (wfl_op1, lhs_type, rhs)
        new_rhs = rhs;
     }
 
-  /* Zero accepted everywhere */
-  else if (TREE_CODE (rhs) == INTEGER_CST 
-      && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
-      && JPRIMITIVE_TYPE_P (rhs_type))
-    new_rhs = convert (lhs_type, rhs);
-
   /* 5.1.1 Try Identity Conversion,
      5.1.2 Try Widening Primitive Conversion */
   else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
     new_rhs = convert (lhs_type, rhs);
 
-  /* Try a narrowing primitive conversion (5.1.3): 
-       - expression is a constant expression of type int AND
+  /* Try a narrowing primitive conversion (5.1.3):
+       - expression is a constant expression of type byte, short, char,
+         or int, AND
        - variable is byte, short or char AND
-       - The value of the expression is representable in the type of the 
+       - The value of the expression is representable in the type of the
          variable */
-  else if (rhs_type == int_type_node && TREE_CONSTANT (rhs)
+  else if ((rhs_type == byte_type_node || rhs_type == short_type_node
+           || rhs_type == char_type_node || rhs_type == int_type_node)
+           && TREE_CONSTANT (rhs)
           && (lhs_type == byte_type_node || lhs_type == char_type_node
               || lhs_type == short_type_node))
     {
       if (int_fits_type_p (rhs, lhs_type))
         new_rhs = convert (lhs_type, rhs);
       else if (wfl_op1)                /* Might be called with a NULL */
-       parse_warning_context 
-         (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'", 
+       parse_warning_context
+         (wfl_op1, "Constant expression `%s' too wide for narrowing primitive conversion to `%s'",
           print_int_node (rhs), lang_printable_name (lhs_type, 0));
       /* Reported a warning that will turn into an error further
         down, so we don't return */
@@ -12814,7 +12955,7 @@ valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
   /* From here, an integral is widened if its precision is smaller
      than the precision of the LHS or if the LHS is a floating point
      type, or the RHS is a float and the RHS a double. */
-  if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type) 
+  if ((JINTEGRAL_TYPE_P (rhs_type) && JINTEGRAL_TYPE_P (lhs_type)
        && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type)))
       || (JINTEGRAL_TYPE_P (rhs_type) && JFLOAT_TYPE_P (lhs_type))
       || (rhs_type == float_type_node && lhs_type == double_type_node))
@@ -12862,7 +13003,7 @@ valid_ref_assignconv_cast_p (source, dest, cast)
   if (TYPE_CLASS_P (source))
     {
       if (TYPE_CLASS_P (dest))
-       return  (source == dest 
+       return  (source == dest
                 || inherits_from_p (source, dest)
                 || (cast && inherits_from_p (dest, source)));
       if (TYPE_INTERFACE_P (dest))
@@ -12903,16 +13044,16 @@ valid_ref_assignconv_cast_p (source, dest, cast)
              tree source_type;
              tree source_sig;
              tree source_name;
-             for (method_source = TYPE_METHODS (source); method_source; 
+             for (method_source = TYPE_METHODS (source); method_source;
                   method_source = TREE_CHAIN (method_source))
                {
-                 source_sig = 
+                 source_sig =
                    build_java_argument_signature (TREE_TYPE (method_source));
                  source_type = TREE_TYPE (TREE_TYPE (method_source));
                  source_name = DECL_NAME (method_source);
                  for (method_dest = TYPE_METHODS (dest);
                       method_dest; method_dest = TREE_CHAIN (method_dest))
-                   if (source_sig == 
+                   if (source_sig ==
                        build_java_argument_signature (TREE_TYPE (method_dest))
                        && source_name == DECL_NAME (method_dest)
                        && source_type != TREE_TYPE (TREE_TYPE (method_dest)))
@@ -12927,9 +13068,10 @@ valid_ref_assignconv_cast_p (source, dest, cast)
        {
          /* Array */
          return (cast
-                 && (DECL_NAME (TYPE_NAME (source)) == java_lang_cloneable
+                 && (DECL_NAME (TYPE_NAME (source))
+                     == java_lang_cloneable_identifier_node
                      || (DECL_NAME (TYPE_NAME (source))
-                         == java_io_serializable)));
+                         == java_io_serializable_identifier_node)));
        }
     }
   if (TYPE_ARRAY_P (source))
@@ -12939,13 +13081,15 @@ valid_ref_assignconv_cast_p (source, dest, cast)
       /* Can't cast an array to an interface unless the interface is
         java.lang.Cloneable or java.io.Serializable.  */
       if (TYPE_INTERFACE_P (dest))
-       return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable
-               || DECL_NAME (TYPE_NAME (dest)) == java_io_serializable);
+       return (DECL_NAME (TYPE_NAME (dest))
+               == java_lang_cloneable_identifier_node
+               || (DECL_NAME (TYPE_NAME (dest))
+                   == java_io_serializable_identifier_node));
       else                     /* Arrays */
        {
          tree source_element_type = TYPE_ARRAY_ELEMENT (source);
          tree dest_element_type = TYPE_ARRAY_ELEMENT (dest);
-         
+
          /* In case of severe errors, they turn out null */
          if (!dest_element_type || !source_element_type)
            return 0;
@@ -12993,7 +13137,7 @@ do_unary_numeric_promotion (arg)
   return arg;
 }
 
-/* Return a non zero value if SOURCE can be converted into DEST using
+/* Return a nonzero value if SOURCE can be converted into DEST using
    the method invocation conversion rule (5.3).  */
 static int
 valid_method_invocation_conversion_p (dest, source)
@@ -13037,7 +13181,7 @@ operator_string (node)
     sprintf (buffer, "%s%s", S, (COMPOUND_ASSIGN_P (node) ? "=" : ""));        \
     return buffer;                                                     \
   }
-  
+
   static char buffer [10];
   switch (TREE_CODE (node))
     {
@@ -13084,7 +13228,7 @@ java_decl_equiv (var_acc1, var_acc2)
 {
   if (JDECL_P (var_acc1))
     return (var_acc1 == var_acc2);
-  
+
   return (TREE_CODE (var_acc1) == COMPONENT_REF
          && TREE_CODE (var_acc2) == COMPONENT_REF
          && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0)
@@ -13092,7 +13236,7 @@ java_decl_equiv (var_acc1, var_acc2)
          && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1));
 }
 
-/* Return a non zero value if CODE is one of the operators that can be
+/* Return a nonzero value if CODE is one of the operators that can be
    used in conjunction with the `=' operator in a compound assignment.  */
 
 static int
@@ -13126,7 +13270,7 @@ java_refold (t)
 
   /* Now the left branch of the binary operator. */
   b = TREE_OPERAND (TREE_OPERAND (c, 1), 0);
-  if (! (b && TREE_CODE (b) == NOP_EXPR 
+  if (! (b && TREE_CODE (b) == NOP_EXPR
         && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR))
     return t;
 
@@ -13180,7 +13324,7 @@ patch_binop (node, wfl_op1, wfl_op2)
      error situation, unless it's too early to tell (in case we're
      handling a `+', `==', `!=' or `instanceof'.) We want to set op<n>_type
      correctly so the error can be later on reported accurately. */
-  if (! (code == PLUS_EXPR || code == NE_EXPR 
+  if (! (code == PLUS_EXPR || code == NE_EXPR
         || code == EQ_EXPR || code == INSTANCEOF_EXPR))
     {
       tree n;
@@ -13225,7 +13369,7 @@ patch_binop (node, wfl_op1, wfl_op2)
          parse_warning_context (wfl_operator, "Evaluating this expression will result in an arithmetic exception being thrown");
          TREE_CONSTANT (node) = 0;
        }
-         
+
       /* Change the division operator if necessary */
       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
        TREE_SET_CODE (node, TRUNC_DIV_EXPR);
@@ -13248,7 +13392,7 @@ patch_binop (node, wfl_op1, wfl_op2)
          && ! flag_emit_class_files
          && (code == RDIV_EXPR || code == TRUNC_MOD_EXPR))
        return build_java_soft_divmod (TREE_CODE (node), prom_type, op1, op2);
+
       /* This one is more complicated. FLOATs are processed by a
         function call to soft_fmod. Duplicate the value of the
         COMPOUND_ASSIGN_P flag. */
@@ -13270,7 +13414,7 @@ patch_binop (node, wfl_op1, wfl_op2)
         purpose of the a previous usage of the String concatenation
         operator */
 
-      if (TREE_CODE (op1) == STRING_CST 
+      if (TREE_CODE (op1) == STRING_CST
          || TREE_CODE (op2) == STRING_CST
          || JSTRING_TYPE_P (op1_type)
          || JSTRING_TYPE_P (op2_type)
@@ -13310,7 +13454,7 @@ patch_binop (node, wfl_op1, wfl_op2)
                                     lang_printable_name (op2_type, 0));
              else
                parse_error_context (wfl_operator,
-                                    "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral", 
+                                    "Incompatible type for `%s'. Can't convert shift distance from `%s' to integral",
                                     operator_string (node),
                                     lang_printable_name (op2_type, 0));
            }
@@ -13320,27 +13464,32 @@ patch_binop (node, wfl_op1, wfl_op2)
        }
 
       /* Unary numeric promotion (5.6.1) is performed on each operand
-         separatly */
+         separately */
       op1 = do_unary_numeric_promotion (op1);
       op2 = do_unary_numeric_promotion (op2);
 
+      /* If the right hand side is of type `long', first cast it to
+        `int'.  */
+      if (TREE_TYPE (op2) == long_type_node)
+       op2 = build1 (CONVERT_EXPR, int_type_node, op2);
+
       /* The type of the shift expression is the type of the promoted
          type of the left-hand operand */
       prom_type = TREE_TYPE (op1);
 
       /* Shift int only up to 0x1f and long up to 0x3f */
       if (prom_type == int_type_node)
-       op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
+       op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
                           build_int_2 (0x1f, 0)));
       else
-       op2 = fold (build (BIT_AND_EXPR, int_type_node, op2, 
+       op2 = fold (build (BIT_AND_EXPR, int_type_node, op2,
                           build_int_2 (0x3f, 0)));
 
       /* The >>> operator is a >> operating on unsigned quantities */
       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
        {
          tree to_return;
-          tree utype = unsigned_type (prom_type);
+          tree utype = java_unsigned_type (prom_type);
           op1 = convert (utype, op1);
          TREE_SET_CODE (node, RSHIFT_EXPR);
           TREE_OPERAND (node, 0) = op1;
@@ -13360,6 +13509,15 @@ patch_binop (node, wfl_op1, wfl_op2)
 
       TREE_TYPE (node) = boolean_type_node;
 
+      /* OP1_TYPE might be NULL when OP1 is a string constant.  */
+      if ((cn = patch_string (op1)))
+       {
+         op1 = cn;
+         op1_type = TREE_TYPE (op1);
+       }
+      if (op1_type == NULL_TREE)
+       abort ();
+
       if (!(op2_type = resolve_type_during_patch (op2)))
        return error_mark_node;
 
@@ -13398,13 +13556,13 @@ patch_binop (node, wfl_op1, wfl_op2)
        {
          char *t1 = xstrdup (lang_printable_name (op1_type, 0));
          SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
-         parse_error_context 
+         parse_error_context
            (wfl_operator, "Impossible for `%s' to be instance of `%s'",
             t1, lang_printable_name (op2_type, 0));
          free (t1);
          error_found = 1;
        }
-      
+
       break;
 
       /* 15.21 Bitwise and Logical Operators */
@@ -13416,7 +13574,7 @@ patch_binop (node, wfl_op1, wfl_op2)
           expression retain that type */
        prom_type = binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
 
-      else if (TREE_CODE (op1_type) == BOOLEAN_TYPE 
+      else if (TREE_CODE (op1_type) == BOOLEAN_TYPE
               && TREE_CODE (op1_type) == BOOLEAN_TYPE)
        /* The type of the bitwise operator expression is BOOLEAN */
        prom_type = boolean_type_node;
@@ -13438,7 +13596,7 @@ patch_binop (node, wfl_op1, wfl_op2)
       /* 15.23 Conditional-Or Operator */
     case TRUTH_ORIF_EXPR:
       /* Operands must be of BOOLEAN type */
-      if (TREE_CODE (op1_type) != BOOLEAN_TYPE || 
+      if (TREE_CODE (op1_type) != BOOLEAN_TYPE ||
          TREE_CODE (op2_type) != BOOLEAN_TYPE)
        {
          if (TREE_CODE (op1_type) != BOOLEAN_TYPE)
@@ -13488,48 +13646,48 @@ patch_binop (node, wfl_op1, wfl_op2)
     case EQ_EXPR:
     case NE_EXPR:
       /* It's time for us to patch the strings. */
-      if ((cn = patch_string (op1))) 
+      if ((cn = patch_string (op1)))
        {
          op1 = cn;
          op1_type = TREE_TYPE (op1);
        }
-      if ((cn = patch_string (op2))) 
+      if ((cn = patch_string (op2)))
        {
          op2 = cn;
          op2_type = TREE_TYPE (op2);
        }
-      
+
       /* 15.20.1 Numerical Equality Operators == and != */
       /* Binary numeric promotion is performed on the operands */
       if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
        binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
-      
+
       /* 15.20.2 Boolean Equality Operators == and != */
       else if (TREE_CODE (op1_type) == BOOLEAN_TYPE &&
          TREE_CODE (op2_type) == BOOLEAN_TYPE)
        ;                       /* Nothing to do here */
-      
+
       /* 15.20.3 Reference Equality Operators == and != */
       /* Types have to be either references or the null type. If
          they're references, it must be possible to convert either
          type to the other by casting conversion. */
-      else if (op1 == null_pointer_node || op2 == null_pointer_node 
+      else if (op1 == null_pointer_node || op2 == null_pointer_node
               || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
                   && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
-                      || valid_ref_assignconv_cast_p (op2_type, 
+                      || valid_ref_assignconv_cast_p (op2_type,
                                                       op1_type, 1))))
        ;                       /* Nothing to do here */
-         
+
       /* Else we have an error figure what can't be converted into
         what and report the error */
       else
        {
          char *t1;
          t1 = xstrdup (lang_printable_name (op1_type, 0));
-         parse_error_context 
+         parse_error_context
            (wfl_operator,
             "Incompatible type for `%s'. Can't convert `%s' to `%s'",
-            operator_string (node), t1, 
+            operator_string (node), t1,
             lang_printable_name (op2_type, 0));
          free (t1);
          TREE_TYPE (node) = boolean_type_node;
@@ -13549,7 +13707,7 @@ patch_binop (node, wfl_op1, wfl_op2)
   TREE_OPERAND (node, 1) = op2;
   TREE_TYPE (node) = prom_type;
   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
-  
+
   if (flag_emit_xref)
     return node;
 
@@ -13601,9 +13759,9 @@ merge_string_cste (op1, op2, after)
 {
   /* Handle two string constants right away */
   if (TREE_CODE (op2) == STRING_CST)
-    return do_merge_string_cste (op1, TREE_STRING_POINTER (op2), 
+    return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
                                 TREE_STRING_LENGTH (op2), after);
-  
+
   /* Reasonable integer constant can be treated right away */
   if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
     {
@@ -13612,7 +13770,7 @@ merge_string_cste (op1, op2, after)
       static const char *const null_pointer = "null";
       char ch[3];
       const char *string;
-      
+
       if (op2 == boolean_true_node)
        string = boolean_true;
       else if (op2 == boolean_false_node)
@@ -13621,13 +13779,24 @@ merge_string_cste (op1, op2, after)
        string = null_pointer;
       else if (TREE_TYPE (op2) == char_type_node)
        {
-         ch[0] = (char )TREE_INT_CST_LOW (op2);
-         ch[1] = '\0';
+         /* Convert the character into UTF-8.  */
+         unsigned char c = (unsigned char) TREE_INT_CST_LOW (op2);
+         unsigned char *p = (unsigned char *) ch;
+         if (0x01 <= c
+             && c <= 0x7f)
+           *p++ = c;
+         else
+           {
+             *p++ = c >> 6 | 0xc0;
+             *p++ = (c & 0x3f) | 0x80;
+           }
+         *p = '\0';
          string = ch;
        }
       else
-         string = print_int_node (op2);
-      
+       string = string_convert_int_cst (op2);
+
       return do_merge_string_cste (op1, string, strlen (string), after);
     }
   return NULL_TREE;
@@ -13649,11 +13818,11 @@ string_constant_concatenation (op1, op2)
     {
       tree string, rest;
       int invert;
-      
+
       string = (TREE_CODE (op1) == STRING_CST ? op1 : op2);
       rest   = (string == op1 ? op2 : op1);
       invert = (string == op1 ? 0 : 1 );
-      
+
       /* Walk REST, only if it looks reasonable */
       if (TREE_CODE (rest) != STRING_CST
          && !IS_CRAFTED_STRING_BUFFER_P (rest)
@@ -13685,7 +13854,7 @@ build_string_concatenation (op1, op2)
 
   if (flag_emit_xref)
     return build (PLUS_EXPR, string_type_node, op1, op2);
-  
+
   /* Try to do some static optimization */
   if ((result = string_constant_concatenation (op1, op2)))
     return result;
@@ -13706,15 +13875,15 @@ build_string_concatenation (op1, op2)
     op2 = patch_string_cst (op2);
 
   /* If either one of the constant is null and the other non null
-     operand is a String object, return it. */
-  if (JSTRING_TYPE_P (TREE_TYPE (op1)) && !op2)
+     operand is a String constant, return it. */
+  if ((TREE_CODE (op1) == STRING_CST) && !op2)
     return op1;
 
   /* If OP1 isn't already a StringBuffer, create and
      initialize a new one */
   if (!IS_CRAFTED_STRING_BUFFER_P (op1))
     {
-      /* Two solutions here: 
+      /* Two solutions here:
         1) OP1 is a constant string reference, we call new StringBuffer(OP1)
         2) OP1 is something else, we call new StringBuffer().append(OP1).  */
       if (TREE_CONSTANT (op1) && JSTRING_TYPE_P (TREE_TYPE (op1)))
@@ -13825,19 +13994,19 @@ build_incdec (op_token, op_location, op1, is_post_p)
      tree op1;
      int is_post_p;
 {
-  static const enum tree_code lookup [2][2] = 
+  static const enum tree_code lookup [2][2] =
     {
       { PREDECREMENT_EXPR, PREINCREMENT_EXPR, },
       { POSTDECREMENT_EXPR, POSTINCREMENT_EXPR, },
     };
-  tree node = build (lookup [is_post_p][(op_token - DECR_TK)], 
+  tree node = build (lookup [is_post_p][(op_token - DECR_TK)],
                     NULL_TREE, op1, NULL_TREE);
   TREE_SIDE_EFFECTS (node) = 1;
   /* Store the location of the operator, for better error report. The
      string of the operator will be rebuild based on the OP value. */
   EXPR_WFL_LINECOL (node) = op_location;
   return node;
-}     
+}
 
 /* Build an incomplete cast operator, based on the use of the
    CONVERT_EXPR. Note that TREE_TYPE of the constructed node is
@@ -13876,7 +14045,17 @@ patch_incomplete_class_ref (node)
   if (!(ref_type = resolve_type_during_patch (type)))
     return error_mark_node;
 
-  if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type))
+  /* Generate the synthetic static method `class$'.  (Previously we
+     deferred this, causing different method tables to be emitted
+     for native code and bytecode.)  */
+  if (!TYPE_DOT_CLASS (current_class))
+      build_dot_class_method (current_class);
+
+  /* If we're not emitting class files and we know ref_type is a
+     compiled class, build a direct reference.  */
+  if ((! flag_emit_class_files && is_compiled_class (ref_type))
+      || JPRIMITIVE_TYPE_P (ref_type)
+      || TREE_CODE (ref_type) == VOID_TYPE)
     {
       tree dot = build_class_ref (ref_type);
       /* A class referenced by `foo.class' is initialized.  */
@@ -13886,10 +14065,7 @@ patch_incomplete_class_ref (node)
     }
 
   /* If we're emitting class files and we have to deal with non
-     primitive types, we invoke (and consider generating) the
-     synthetic static method `class$'. */
-  if (!TYPE_DOT_CLASS (current_class))
-      build_dot_class_method (current_class);
+     primitive types, we invoke the synthetic static method `class$'.  */
   ref_type = build_dot_class_method_invocation (ref_type);
   return java_complete_tree (ref_type);
 }
@@ -13938,7 +14114,7 @@ patch_unaryop (node, wfl_op)
          decl = DECL_FUNCTION_ACCESS_DECL (decl);
        }
       /* We really should have a JAVA_ARRAY_EXPR to avoid this */
-      else if (!JDECL_P (decl) 
+      else if (!JDECL_P (decl)
          && TREE_CODE (decl) != COMPONENT_REF
          && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
          && TREE_CODE (decl) != INDIRECT_REF
@@ -13949,7 +14125,7 @@ patch_unaryop (node, wfl_op)
          TREE_TYPE (node) = error_mark_node;
          error_found = 1;
        }
-      
+
       /* From now on, we know that op if a variable and that it has a
          valid wfl. We use wfl_op to locate errors related to the
          ++/-- operand. */
@@ -13973,8 +14149,8 @@ patch_unaryop (node, wfl_op)
          else
            {
              value = build_int_2 (1, 0);
-             TREE_TYPE (node) = 
-               binary_numeric_promotion (op_type, 
+             TREE_TYPE (node) =
+               binary_numeric_promotion (op_type,
                                          TREE_TYPE (value), &op, &value);
            }
 
@@ -13982,10 +14158,10 @@ patch_unaryop (node, wfl_op)
          if (outer_field_flag)
            {
              /* We re-generate an access to the field */
-             value = build (PLUS_EXPR, TREE_TYPE (op), 
+             value = build (PLUS_EXPR, TREE_TYPE (op),
                             build_outer_field_access (wfl_op, decl), value);
-                                                   
-             /* And we patch the original access$() into a write 
+
+             /* And we patch the original access$() into a write
                  with plus_op as a rhs */
              return outer_field_access_fix (node, op, value);
            }
@@ -14070,7 +14246,7 @@ patch_unaryop (node, wfl_op)
        }
       break;
     }
-  
+
   if (error_found)
     return error_mark_node;
 
@@ -14096,7 +14272,7 @@ resolve_type_during_patch (type)
       tree type_decl = resolve_and_layout (EXPR_WFL_NODE (type), type);
       if (!type_decl)
        {
-         parse_error_context (type, 
+         parse_error_context (type,
                               "Class `%s' not found in type declaration",
                               IDENTIFIER_POINTER (EXPR_WFL_NODE (type)));
          return NULL_TREE;
@@ -14155,7 +14331,7 @@ patch_cast (node, wfl_op)
 
   /* The remaining legal casts involve conversion between reference
      types. Check for their compile time correctness. */
-  if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type) 
+  if (JREFERENCE_TYPE_P (op_type) && JREFERENCE_TYPE_P (cast_type)
       && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
     {
       TREE_TYPE (node) = promote_type (cast_type);
@@ -14234,7 +14410,7 @@ patch_array_ref (node)
   /* The array reference must be an array */
   if (!TYPE_ARRAY_P (array_type))
     {
-      parse_error_context 
+      parse_error_context
        (wfl_operator,
         "`[]' can only be applied to arrays. It can't be applied to `%s'",
         lang_printable_name (array_type, 0));
@@ -14284,7 +14460,7 @@ build_newarray_node (type, dims, extra_dims)
      int extra_dims;
 {
   tree node =
-    build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims), 
+    build (NEW_ARRAY_EXPR, NULL_TREE, type, nreverse (dims),
           build_int_2 (extra_dims, 0));
   return node;
 }
@@ -14326,9 +14502,9 @@ patch_newarray (node)
       /* Report errors on types here */
       if (dim_error)
        {
-         parse_error_context 
-           (TREE_PURPOSE (cdim), 
-            "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'", 
+         parse_error_context
+           (TREE_PURPOSE (cdim),
+            "Incompatible type for dimension in array creation expression. %s convert `%s' to `int'",
             (valid_cast_to_p (TREE_TYPE (dim), int_type_node) ?
              "Explicit cast needed to" : "Can't"),
             lang_printable_name (TREE_TYPE (dim), 0));
@@ -14377,13 +14553,13 @@ patch_newarray (node)
      (primitive or not) matters. */
   if (ndims == 1)
     return build_new_array (type, TREE_VALUE (dims));
-  
+
   /* Can't reuse what's already written in expr.c because it uses the
      JVM stack representation. Provide a build_multianewarray. FIXME */
   return build (CALL_EXPR, array_type,
                build_address_of (soft_multianewarray_node),
                tree_cons (NULL_TREE, build_class_ref (TREE_TYPE (array_type)),
-                          tree_cons (NULL_TREE, 
+                          tree_cons (NULL_TREE,
                                      build_int_2 (ndims, 0), dims )),
                NULL_TREE);
 }
@@ -14464,7 +14640,7 @@ patch_new_array_init (type, node)
          TREE_PURPOSE (current) = NULL_TREE;
          all_constant = 0;
        }
-      if (elt && TREE_CODE (elt) == TREE_LIST 
+      if (elt && TREE_CODE (elt) == TREE_LIST
          && TREE_VALUE (elt) == error_mark_node)
        error_seen = 1;
     }
@@ -14504,9 +14680,9 @@ array_constructor_check_entry (type, entry)
     value = patched;
   if (value == error_mark_node)
     return 1;
-  
+
   type_value = TREE_TYPE (value);
-  
+
   /* At anytime, try_builtin_assignconv can report a warning on
      constant overflow during narrowing. */
   SET_WFL_OPERATOR (wfl_operator, TREE_PURPOSE (entry), wfl_value);
@@ -14521,12 +14697,12 @@ array_constructor_check_entry (type, entry)
                   "Can't" : "Explicit cast needed to");
       if (!array_type_string)
        array_type_string = xstrdup (lang_printable_name (type, 1));
-      parse_error_context 
+      parse_error_context
        (wfl_operator, "Incompatible type for array. %s convert `%s' to `%s'",
         msg, lang_printable_name (type_value, 1), array_type_string);
       error_seen = 1;
     }
-  
+
   if (new_value)
     TREE_VALUE (entry) = new_value;
 
@@ -14587,7 +14763,7 @@ patch_return (node)
      isn't declared with the keyword `void' */
   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
     error_found = 2;
-  
+
   if (DECL_INSTINIT_P (current_function_decl))
     error_found = 1;
 
@@ -14596,7 +14772,7 @@ patch_return (node)
       if (DECL_INSTINIT_P (current_function_decl))
        parse_error_context (wfl_operator,
                             "`return' inside instance initializer");
-       
+
       else if (DECL_CLINIT_P (current_function_decl))
        parse_error_context (wfl_operator,
                             "`return' inside static initializer");
@@ -14604,14 +14780,14 @@ patch_return (node)
       else if (!DECL_CONSTRUCTOR_P (meth))
        {
          char *t = xstrdup (lang_printable_name (mtype, 0));
-         parse_error_context (wfl_operator, 
+         parse_error_context (wfl_operator,
                               "`return' with%s value from `%s %s'",
-                              (error_found == 1 ? "" : "out"), 
+                              (error_found == 1 ? "" : "out"),
                               t, lang_printable_name (meth, 0));
          free (t);
        }
       else
-       parse_error_context (wfl_operator, 
+       parse_error_context (wfl_operator,
                             "`return' with value from constructor `%s'",
                             lang_printable_name (meth, 0));
       return error_mark_node;
@@ -14625,21 +14801,9 @@ patch_return (node)
       tree exp = java_complete_tree (return_exp);
       tree modify, patched;
 
-      /* If the function returned value and EXP are booleans, EXP has
-      to be converted into the type of DECL_RESULT, which is integer
-      (see complete_start_java_method) */
-      if (TREE_TYPE (exp) == boolean_type_node &&
-         TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
-       exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
-
-      /* `null' can be assigned to a function returning a reference */
-      if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
-         exp == null_pointer_node)
-       exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
-
       if ((patched = patch_string (exp)))
        exp = patched;
-      
+
       modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
       modify = java_complete_tree (modify);
@@ -14689,13 +14853,13 @@ patch_if_else_statement (node)
   if (TREE_TYPE (expression) != boolean_type_node
       && TREE_TYPE (expression) != promoted_boolean_type_node)
     {
-      parse_error_context 
-       (wfl_operator, 
-        "Incompatible type for `if'. Can't convert `%s' to `boolean'", 
+      parse_error_context
+       (wfl_operator,
+        "Incompatible type for `if'. Can't convert `%s' to `boolean'",
         lang_printable_name (TREE_TYPE (expression), 0));
       return error_mark_node;
     }
-  
+
   if (TREE_CODE (expression) == INTEGER_CST)
     {
       if (integer_zerop (expression))
@@ -14741,7 +14905,7 @@ build_labeled_block (location, label)
          parse_error_context (wfl_operator,
             "Declaration of `%s' shadows a previous label declaration",
                               IDENTIFIER_POINTER (label));
-         EXPR_WFL_LINECOL (wfl_operator) = 
+         EXPR_WFL_LINECOL (wfl_operator) =
            EXPR_WFL_LINECOL (IDENTIFIER_LOCAL_VALUE (label_name));
          parse_error_context (wfl_operator,
             "This is the location of the previous declaration of label `%s'",
@@ -14791,11 +14955,11 @@ build_new_loop (loop_body)
        COMPOUND_EXPR           (loop main body)
          EXIT_EXPR             (this order is for while/for loops.
          LABELED_BLOCK_EXPR      the order is reversed for do loops)
-           LABEL_DECL           (a continue occuring here branches at the 
+           LABEL_DECL           (a continue occurring here branches at the
            BODY                         end of this labeled block)
        INCREMENT               (if any)
 
-  REVERSED, if non zero, tells that the loop condition expr comes
+  REVERSED, if nonzero, tells that the loop condition expr comes
   after the body, like in the do-while loop.
 
   To obtain a loop, the loop body structure described above is
@@ -14822,8 +14986,8 @@ build_loop_body (location, condition, reversed)
   body = build_labeled_block (0, continue_identifier_node);
   first = (reversed ? body : condition);
   second = (reversed ? condition : body);
-  return 
-    build (COMPOUND_EXPR, NULL_TREE, 
+  return
+    build (COMPOUND_EXPR, NULL_TREE,
           build (COMPOUND_EXPR, NULL_TREE, first, second), empty_stmt_node);
 }
 
@@ -14865,7 +15029,22 @@ finish_for_loop (location, condition, update, body)
   /* Put the condition and the loop body in place */
   tree loop = finish_loop_body (location, condition, body, 0);
   /* LOOP is the current loop which has been now popped of the loop
-     stack. Install the update block */
+     stack.  Mark the update block as reachable and install it.  We do
+     this because the (current interpretation of the) JLS requires
+     that the update expression be considered reachable even if the
+     for loop's body doesn't complete normally.  */
+  if (update != NULL_TREE && update != empty_stmt_node)
+    {
+      tree up2 = update;
+      if (TREE_CODE (up2) == EXPR_WITH_FILE_LOCATION)
+       up2 = EXPR_WFL_NODE (up2);
+      /* Try to detect constraint violations.  These would be
+        programming errors somewhere.  */
+      if (! IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (up2)))
+         || TREE_CODE (up2) == LOOP_EXPR)
+       abort ();
+      SUPPRESS_UNREACHABLE_ERROR (up2) = 1;
+    }
   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
   return loop;
 }
@@ -14952,7 +15131,7 @@ build_bc_statement (location, is_break, name)
 
   if (name)
     {
-      if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE 
+      if (!(label_block_expr = IDENTIFIER_LOCAL_VALUE
            (merge_qualified_name (label_id, EXPR_WFL_NODE (name)))))
        /* Null means that we don't have a target for this named
           break/continue. In this case, we make the target to be the
@@ -14962,7 +15141,7 @@ build_bc_statement (location, is_break, name)
     }
   /* Unlabeled break/continue will be handled during the
      break/continue patch operation */
-  break_continue 
+  break_continue
     = build (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr, NULL_TREE);
 
   IS_BREAK_STMT_P (break_continue) = is_break;
@@ -14981,7 +15160,7 @@ patch_bc_statement (node)
   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
   tree labeled_block = ctxp->current_labeled_block;
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
+
   /* Having an identifier here means that the target is unknown. */
   if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
     {
@@ -15000,7 +15179,7 @@ patch_bc_statement (node)
                parse_error_context (wfl_operator,
                                     "`continue' must be in loop");
              else
-               parse_error_context 
+               parse_error_context
                  (wfl_operator, "continue label `%s' does not name a loop",
                   IDENTIFIER_POINTER (bc_label));
              return error_mark_node;
@@ -15016,7 +15195,7 @@ patch_bc_statement (node)
        }
     }
   else if (!bc_label)
-    { 
+    {
       for (;; labeled_block = TREE_CHAIN (labeled_block))
        {
          if (labeled_block == NULL_TREE)
@@ -15062,15 +15241,15 @@ patch_exit_expr (node)
   /* The type of expression must be boolean */
   if (TREE_TYPE (expression) != boolean_type_node)
     {
-      parse_error_context 
-       (wfl_operator, 
-    "Incompatible type for loop conditional. Can't convert `%s' to `boolean'", 
+      parse_error_context
+       (wfl_operator,
+    "Incompatible type for loop conditional. Can't convert `%s' to `boolean'",
         lang_printable_name (TREE_TYPE (expression), 0));
       return error_mark_node;
     }
   /* Now we know things are allright, invert the condition, fold and
      return */
-  TREE_OPERAND (node, 0) = 
+  TREE_OPERAND (node, 0) =
     fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, expression));
 
   if (! integer_zerop (TREE_OPERAND (node, 0))
@@ -15134,8 +15313,8 @@ patch_switch_statement (node)
                = EXPR_WFL_LINECOL (TREE_PURPOSE (iter));
              /* The case_label_list is in reverse order, so print the
                 outer label first.  */
-             parse_error_context (wfl_operator, "duplicate case label: `%d'",
-                                  subval);
+             parse_error_context (wfl_operator, "duplicate case label: `"
+                                  HOST_WIDE_INT_PRINT_DEC "'", subval);
              EXPR_WFL_LINECOL (wfl_operator)
                = EXPR_WFL_LINECOL (TREE_PURPOSE (subiter));
              parse_error_context (wfl_operator, "original label is here");
@@ -15156,11 +15335,89 @@ patch_switch_statement (node)
   TREE_TYPE (node) = void_type_node;
   TREE_SIDE_EFFECTS (node) = 1;
   CAN_COMPLETE_NORMALLY (node)
-    = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)) 
+    = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1))
       || ! SWITCH_HAS_DEFAULT (node);
   return node;
 }
 
+/* Assertions.  */
+
+/* Build an assertion expression for `assert CONDITION : VALUE'; VALUE
+   might be NULL_TREE.  */
+static tree
+build_assertion (location, condition, value)
+     int location;
+     tree condition, value;
+{
+  tree node;
+  tree klass = GET_CPC ();
+
+  if (! CLASS_USES_ASSERTIONS (klass))
+    {
+      tree field, classdollar, id, call;
+      tree class_type = TREE_TYPE (klass);
+
+      field = add_field (class_type,
+                        get_identifier ("$assertionsDisabled"),
+                        boolean_type_node,
+                        ACC_PRIVATE | ACC_STATIC | ACC_FINAL);
+      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);
+      FIELD_SYNTHETIC (field) = 1;
+
+      if (!TYPE_DOT_CLASS (class_type))
+       build_dot_class_method (class_type);
+      classdollar = build_dot_class_method_invocation (class_type);
+
+      /* Call CLASS.desiredAssertionStatus().  */
+      id = build_wfl_node (get_identifier ("desiredAssertionStatus"));
+      call = build (CALL_EXPR, NULL_TREE, id, NULL_TREE, NULL_TREE);
+      call = make_qualified_primary (classdollar, call, location);
+      TREE_SIDE_EFFECTS (call) = 1;
+
+      /* Invert to obtain !CLASS.desiredAssertionStatus().  This may
+        seem odd, but we do it to generate code identical to that of
+        the JDK.  */
+      call = build1 (TRUTH_NOT_EXPR, NULL_TREE, call);
+      TREE_SIDE_EFFECTS (call) = 1;
+      DECL_INITIAL (field) = call;
+
+      /* Record the initializer in the initializer statement list.  */
+      call = build (MODIFY_EXPR, NULL_TREE, field, call);
+      TREE_CHAIN (call) = CPC_STATIC_INITIALIZER_STMT (ctxp);
+      SET_CPC_STATIC_INITIALIZER_STMT (ctxp, call);
+      MODIFY_EXPR_FROM_INITIALIZATION_P (call) = 1;
+
+      CLASS_USES_ASSERTIONS (klass) = 1;
+    }
+
+  if (value != NULL_TREE)
+    value = tree_cons (NULL_TREE, value, NULL_TREE);
+
+  node = build_wfl_node (get_identifier ("java"));
+  node = make_qualified_name (node, build_wfl_node (get_identifier ("lang")),
+                             location);
+  node = make_qualified_name (node, build_wfl_node (get_identifier ("AssertionError")),
+                             location);
+
+  node = build (NEW_CLASS_EXPR, NULL_TREE, node, value, NULL_TREE);
+  TREE_SIDE_EFFECTS (node) = 1;
+  /* It is too early to use BUILD_THROW.  */
+  node = build1 (THROW_EXPR, NULL_TREE, node);
+  TREE_SIDE_EFFECTS (node) = 1;
+
+  /* We invert the condition; if we just put NODE as the `else' part
+     then we generate weird-looking bytecode.  */
+  condition = build1 (TRUTH_NOT_EXPR, NULL_TREE, condition);
+  /* Check $assertionsDisabled.  */
+  condition
+    = build (TRUTH_ANDIF_EXPR, NULL_TREE,
+            build1 (TRUTH_NOT_EXPR, NULL_TREE,
+                    build_wfl_node (get_identifier ("$assertionsDisabled"))),
+            condition);
+  node = build_if_else_statement (location, condition, node, NULL_TREE);
+  return node;
+}
+
 /* 14.18 The try/catch statements */
 
 /* Encapsulate TRY_STMTS' in a try catch sequence. The catch clause
@@ -15177,11 +15434,11 @@ encapsulate_with_try_catch (location, type, try_stmts, catch_stmts)
   try_block = build_expr_block (try_stmts, NULL_TREE);
 
   /* Build a catch block: we need a catch clause parameter */
-  catch_clause_param = build_decl (VAR_DECL, 
+  catch_clause_param = build_decl (VAR_DECL,
                                   wpv_id, build_pointer_type (type));
   /* And a block */
   catch_block = build_expr_block (NULL_TREE, catch_clause_param);
-  
+
   /* Initialize the variable and store in the block */
   catch = build (MODIFY_EXPR, NULL_TREE, catch_clause_param,
                 build (JAVA_EXC_OBJ_EXPR, ptr_type_node));
@@ -15252,7 +15509,7 @@ patch_try_statement (node)
         only parameter of the clause statement in of class Throwable
         or a subclass of Throwable, but that was done earlier. The
         catch clause parameter type has also been resolved. */
-      
+
       /* Just make sure that the catch clause parameter type inherits
         from java.lang.Throwable */
       if (!inherits_from_p (carg_type, throwable_type_node))
@@ -15264,7 +15521,7 @@ patch_try_statement (node)
          error_found = 1;
          continue;
        }
-      
+
       /* Partial check for unreachable catch statement: The catch
         clause is reachable iff is no earlier catch block A in
         the try statement such that the type of the catch
@@ -15281,7 +15538,7 @@ patch_try_statement (node)
          if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
            {
              EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (current);
-             parse_error_context 
+             parse_error_context
                (wfl_operator,
                 "`catch' not reached because of the catch clause at line %d",
                 EXPR_WFL_LINENO (sub_current));
@@ -15317,7 +15574,7 @@ patch_try_statement (node)
   POP_EXCEPTIONS ();
 
   /* Verification ends here */
-  if (error_found) 
+  if (error_found)
     return error_mark_node;
 
   TREE_OPERAND (node, 0) = try;
@@ -15368,7 +15625,7 @@ patch_synchronized_statement (node, wfl_op1)
      that the handler that catches all throw exception calls
      _Jv_MonitorExit and then rethrow the exception.
      The synchronized statement is then implemented as:
-     TRY 
+     TRY
        {
          _Jv_MonitorEnter (expression)
         synchronized_block
@@ -15427,20 +15684,20 @@ patch_throw_statement (node, wfl_op1)
 
   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
   /* An instance can't throw a checked exception unless that exception
-     is explicitely declared in the `throws' clause of each
+     is explicitly declared in the `throws' clause of each
      constructor. This doesn't apply to anonymous classes, since they
      don't have declared constructors. */
-  if (!unchecked_ok 
+  if (!unchecked_ok
       && DECL_INSTINIT_P (current_function_decl)
       && !ANONYMOUS_CLASS_P (current_class))
     {
       tree current;
-      for (current = TYPE_METHODS (current_class); current; 
+      for (current = TYPE_METHODS (current_class); current;
           current = TREE_CHAIN (current))
-       if (DECL_CONSTRUCTOR_P (current) 
+       if (DECL_CONSTRUCTOR_P (current)
            && !check_thrown_exceptions_do (TREE_TYPE (expr)))
          {
-           parse_error_context (wfl_operator, "Checked exception `%s' can't be thrown in instance initializer (not all declared constructor are declaring it in their `throws' clause)", 
+           parse_error_context (wfl_operator, "Checked exception `%s' can't be thrown in instance initializer (not all declared constructor are declaring it in their `throws' clause)",
                                 lang_printable_name (TREE_TYPE (expr), 0));
            return error_mark_node;
          }
@@ -15469,7 +15726,7 @@ patch_throw_statement (node, wfl_op1)
       /* We report that the exception can't be throw from a try block
          in all circumstances but when the `throw' is inside a static
          block. */
-      else if (!EXCEPTIONS_P (currently_caught_type_list) 
+      else if (!EXCEPTIONS_P (currently_caught_type_list)
               && !tryblock_throws_ok)
        {
          if (DECL_CLINIT_P (current_function_decl))
@@ -15478,13 +15735,13 @@ patch_throw_statement (node, wfl_op1)
                                 lang_printable_name (type, 0));
          else
            parse_error_context (wfl_operator,
-                   "Checked exception `%s' isn't thrown from a `try' block", 
+                   "Checked exception `%s' isn't thrown from a `try' block",
                                 lang_printable_name (type, 0));
        }
       /* Otherwise, the current method doesn't have the appropriate
          throws declaration */
       else
-       parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)", 
+       parse_error_context (wfl_operator, "Checked exception `%s' doesn't match any of current method's `throws' declaration(s)",
                             lang_printable_name (type, 0));
       return error_mark_node;
     }
@@ -15508,8 +15765,8 @@ check_thrown_exceptions (location, decl)
 {
   tree throws;
   /* For all the unchecked exceptions thrown by DECL */
-  for (throws = DECL_FUNCTION_THROWS (decl); throws; 
-       throws = TREE_CHAIN (throws)) 
+  for (throws = DECL_FUNCTION_THROWS (decl); throws;
+       throws = TREE_CHAIN (throws))
     if (!check_thrown_exceptions_do (TREE_VALUE (throws)))
       {
 #if 1
@@ -15522,10 +15779,10 @@ check_thrown_exceptions (location, decl)
          parse_error_context
             (wfl_operator, "Exception `%s' can't be thrown in initializer",
             lang_printable_name (TREE_VALUE (throws), 0));
-       else 
+       else
          {
-           parse_error_context 
-             (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'", 
+           parse_error_context
+             (wfl_operator, "Exception `%s' must be caught, or it must be declared in the `throws' clause of `%s'",
               lang_printable_name (TREE_VALUE (throws), 0),
               (DECL_INIT_P (current_function_decl) ?
                IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))) :
@@ -15648,7 +15905,7 @@ patch_conditional_expr (node, wfl_cond, wfl_op1)
   /* Second and third can be numeric, boolean (i.e. primitive),
      references or null. Anything else results in an error */
   if (!((JNUMERIC_TYPE_P (t1) && JNUMERIC_TYPE_P (t2))
-       || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node) 
+       || ((JREFERENCE_TYPE_P (t1) || op1 == null_pointer_node)
            && (JREFERENCE_TYPE_P (t2) || op2 == null_pointer_node))
        || (t1 == boolean_type_node && t2 == boolean_type_node)))
     error_found = 1;
@@ -15680,9 +15937,9 @@ patch_conditional_expr (node, wfl_cond, wfl_op1)
 
       /* Otherwise, binary numeric promotion is applied and the
         resulting type is the promoted type of operand 1 and 2 */
-      else 
-       resulting_type = binary_numeric_promotion (t1, t2, 
-                                                  &TREE_OPERAND (node, 1), 
+      else
+       resulting_type = binary_numeric_promotion (t1, t2,
+                                                  &TREE_OPERAND (node, 1),
                                                   &TREE_OPERAND (node, 2));
     }
 
@@ -15763,8 +16020,10 @@ fold_constant_for_init (node, context)
 
   switch (code)
     {
-    case STRING_CST:
     case INTEGER_CST:
+      if (node == null_pointer_node)
+       return NULL_TREE;
+    case STRING_CST:
     case REAL_CST:
       return node;
 
@@ -15781,7 +16040,7 @@ fold_constant_for_init (node, context)
     case BIT_IOR_EXPR:
     case TRUTH_ANDIF_EXPR:
     case TRUTH_ORIF_EXPR:
-    case EQ_EXPR: 
+    case EQ_EXPR:
     case NE_EXPR:
     case GT_EXPR:
     case GE_EXPR:
@@ -15837,6 +16096,8 @@ fold_constant_for_init (node, context)
       /* Guard against infinite recursion. */
       DECL_INITIAL (node) = NULL_TREE;
       val = fold_constant_for_init (val, node);
+      if (val != NULL_TREE && TREE_CODE (val) != STRING_CST)
+       val = try_builtin_assignconv (NULL_TREE, TREE_TYPE (node), val);
       DECL_INITIAL (node) = val;
       return val;
 
@@ -15852,7 +16113,7 @@ fold_constant_for_init (node, context)
          else if (! QUALIFIED_P (name))
            {
              decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
-             if (decl == NULL_TREE 
+             if (decl == NULL_TREE
                  || (! FIELD_STATIC (decl) && ! FIELD_FINAL (decl)))
                return NULL_TREE;
              return fold_constant_for_init (decl, decl);
@@ -15913,45 +16174,12 @@ resolve_qualified_name (name, context)
 }
 #endif
 
-/* Mark P, which is really a `struct parser_ctxt **' for GC.  */
-
-static void
-mark_parser_ctxt (p)
-     void *p;
-{
-  struct parser_ctxt *pc = *((struct parser_ctxt **) p);
-  int i;
-
-  if (!pc)
-    return;
-
-#ifndef JC1_LITE
-  for (i = 0; i < 11; ++i)
-    ggc_mark_tree (pc->modifier_ctx[i]);
-  ggc_mark_tree (pc->class_type);
-  ggc_mark_tree (pc->function_decl);
-  ggc_mark_tree (pc->package);
-  ggc_mark_tree (pc->class_list);
-  ggc_mark_tree (pc->current_parsed_class);
-  ggc_mark_tree (pc->current_parsed_class_un);
-  ggc_mark_tree (pc->non_static_initialized);
-  ggc_mark_tree (pc->static_initialized);
-  ggc_mark_tree (pc->instance_initializers);
-  ggc_mark_tree (pc->import_list);
-  ggc_mark_tree (pc->import_demand_list);
-  ggc_mark_tree (pc->current_loop);
-  ggc_mark_tree (pc->current_labeled_block);
-#endif /* JC1_LITE */
-
-  if (pc->next)
-    mark_parser_ctxt (&pc->next);
-}
-
 void
 init_src_parse ()
 {
-  /* Register roots with the garbage collector.  */
-  ggc_add_tree_root (src_parse_roots, sizeof (src_parse_roots) / sizeof(tree));
+  /* Sanity check; we've been bit by this before.  */
+  if (ARRAY_SIZE (ctxp->modifier_ctx) != MODIFIER_TK - PUBLIC_TK)
+    abort ();
 }
 
 \f
@@ -15961,42 +16189,19 @@ init_src_parse ()
 
 /* Attach to PTR (a block) the declaration found in ENTRY. */
 
-static bool
+static int
 attach_init_test_initialization_flags (entry, ptr)
-     struct hash_entry *entry;
+     PTR *entry;
      PTR ptr;
 {
   tree block = (tree)ptr;
-  struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
-  
-  TREE_CHAIN (ite->init_test_decl) = BLOCK_EXPR_DECLS (block);
-  BLOCK_EXPR_DECLS (block) = ite->init_test_decl;
-  return true;
-}
-
-/* This function is called for each statement calling a static
-   function.  ENTRY is a TREE_LIST whose PURPOSE is the called
-   function and VALUE is a compound whose second operand can be
-   patched with static class initialization flag assignments.  */
-
-static bool
-adjust_init_test_initialization (entry, info)
-     struct hash_entry *entry;
-     PTR info ATTRIBUTE_UNUSED;
-{
-  tree list = (tree)(entry->key);
-  tree called_method = TREE_PURPOSE (list);
-  tree compound = TREE_VALUE (list);
-  tree assignment_compound_list = build_tree_list (called_method, NULL);
-
-  /* For each class definitely initialized in CALLED_METHOD, fill
-     ASSIGNMENT_COMPOUND with assignment to the class initialization flag. */
-  hash_traverse (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
-                emit_test_initialization, assignment_compound_list);
-
-  if (TREE_VALUE (assignment_compound_list))
-    TREE_OPERAND (compound, 1) = TREE_VALUE (assignment_compound_list);
+  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
 
+  if (block != error_mark_node)
+    {
+      TREE_CHAIN (ite->value) = BLOCK_EXPR_DECLS (block);
+      BLOCK_EXPR_DECLS (block) = ite->value;
+    }
   return true;
 }
 
@@ -16006,37 +16211,32 @@ adjust_init_test_initialization (entry, info)
    initialized static class flags if a flag already existed, otherwise
    a new one is created.  */
 
-static bool
-emit_test_initialization (entry, info)
-     struct hash_entry *entry;
+static int
+emit_test_initialization (entry_p, info)
+     PTR *entry_p;
      PTR info;
 {
   tree l = (tree) info;
   tree decl, init;
-
-  struct init_test_hash_entry *ite = (struct init_test_hash_entry *)
-    hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
-                entry->key, FALSE, NULL);
+  tree key = (tree) *entry_p;
+  tree *ite;
+  htab_t cf_ht = DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl);
 
   /* If we haven't found a flag and we're dealing with self registered
      with current_function_decl, then don't do anything. Self is
      always added as definitely initialized but this information is
      valid only if used outside the current function. */
-  if (! ite)
-    {
-      if (current_function_decl != TREE_PURPOSE (l))
-       ite = (struct init_test_hash_entry *)
-         hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
-                      entry->key, TRUE, NULL);
-      else
-       return true;
-    }
+  if (current_function_decl == TREE_PURPOSE (l)
+      && java_treetreehash_find (cf_ht, key) == NULL)
+    return true;
+
+  ite = java_treetreehash_new (cf_ht, key);
 
   /* If we don't have a variable, create one and install it. */
-  if (! ite->init_test_decl)
+  if (*ite == NULL)
     {
       tree block;
-      
+
       decl = build_decl (VAR_DECL, NULL_TREE, boolean_type_node);
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
       LOCAL_CLASS_INITIALIZATION_FLAG (decl) = 1;
@@ -16047,10 +16247,10 @@ emit_test_initialization (entry, info)
       block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));
       TREE_CHAIN (decl) = BLOCK_EXPR_DECLS (block);
       BLOCK_EXPR_DECLS (block) = decl;
-      ite->init_test_decl = decl;
+      *ite = decl;
     }
   else
-    decl = ite->init_test_decl;
+    decl = *ite;
 
   /* Now simply augment the compound that holds all the assignments
      pertaining to this method invocation. */
@@ -16061,3 +16261,6 @@ emit_test_initialization (entry, info)
 
   return true;
 }
+
+#include "gt-java-parse.h"
+#include "gtype-java.h"