[multiple changes]
[platform/upstream/gcc.git] / gcc / java / parse.y
index 874d722..5357003 100644 (file)
@@ -1,6 +1,6 @@
 /* Source code parsing and tree node generation for the GNU compiler
    for the Java(TM) language.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
 This file is part of GNU CC.
@@ -61,6 +61,8 @@ definitions and other extensions.  */
 #include "zipfile.h"
 #include "convert.h"
 #include "buffer.h"
+#include "xref.h"
+#include "except.h"
 
 #ifndef DIR_SEPARATOR
 #define DIR_SEPARATOR '/'
@@ -86,8 +88,9 @@ static tree lookup_java_method2 PROTO ((tree, tree, int));
 static tree method_header PROTO ((int, tree, tree, tree));
 static void fix_method_argument_names PROTO ((tree ,tree));
 static tree method_declarator PROTO ((tree, tree));
-static void parse_warning_context VPROTO ((tree cl, char *msg, ...));
-static void issue_warning_error_from_context PROTO ((tree, char *msg, va_list));
+static void parse_warning_context PVPROTO ((tree cl, const char *msg, ...))
+  ATTRIBUTE_PRINTF_2;
+static void issue_warning_error_from_context PROTO ((tree, const char *msg, va_list));
 static tree parse_jdk1_1_error PROTO ((char *));
 static void complete_class_report_errors PROTO ((jdep *));
 static int process_imports PROTO ((void));
@@ -98,7 +101,6 @@ static int check_pkg_class_access PROTO ((tree, tree));
 static tree resolve_package PROTO ((tree, tree *));
 static tree lookup_package_type PROTO ((char *, int));
 static tree resolve_class PROTO ((tree, tree, tree));
-static tree do_resolve_class PROTO ((tree, tree, tree));
 static void declare_local_variables PROTO ((int, tree, tree));
 static void source_start_java_method PROTO ((tree));
 static void source_end_java_method PROTO ((void));
@@ -118,6 +120,8 @@ static tree resolve_no_layout PROTO ((tree, tree));
 static int invocation_mode PROTO ((tree, int));
 static tree find_applicable_accessible_methods_list PROTO ((int, tree, 
                                                            tree, tree));
+static void search_applicable_methods_list PROTO ((int, tree, tree, tree, 
+                                                  tree *, tree *));
 static tree find_most_specific_methods_list PROTO ((tree));
 static int argument_types_convertible PROTO ((tree, tree));
 static tree patch_invoke PROTO ((tree, tree, tree));
@@ -184,23 +188,22 @@ static tree add_stmt_to_compound PROTO ((tree, tree, tree));
 static tree add_stmt_to_block PROTO ((tree, tree, tree));
 static tree patch_exit_expr PROTO ((tree));
 static tree build_labeled_block PROTO ((int, tree));
-static tree generate_labeled_block PROTO (());
-static tree complete_labeled_statement PROTO ((tree, tree));
+static tree finish_labeled_statement PROTO ((tree, tree));
 static tree build_bc_statement PROTO ((int, int, tree));
 static tree patch_bc_statement PROTO ((tree));
 static tree patch_loop_statement PROTO ((tree));
 static tree build_new_loop PROTO ((tree));
 static tree build_loop_body PROTO ((int, tree, int));
-static tree complete_loop_body PROTO ((int, tree, tree, int));
+static tree finish_loop_body PROTO ((int, tree, tree, int));
 static tree build_debugable_stmt PROTO ((int, tree));
-static tree complete_for_loop PROTO ((int, tree, tree, tree));
+static tree finish_for_loop PROTO ((int, tree, tree, tree));
 static tree patch_switch_statement PROTO ((tree));
 static tree string_constant_concatenation PROTO ((tree, tree));
 static tree build_string_concatenation PROTO ((tree, tree));
 static tree patch_string_cst PROTO ((tree));
 static tree patch_string PROTO ((tree));
-static tree build_jump_to_finally PROTO ((tree, tree, tree, tree));
-static tree build_try_statement PROTO ((int, tree, tree, tree));
+static tree build_try_statement PROTO ((int, tree, tree));
+static tree build_try_finally_statement PROTO ((int, tree, tree));
 static tree patch_try_statement PROTO ((tree));
 static tree patch_synchronized_statement PROTO ((tree, tree));
 static tree patch_throw_statement PROTO ((tree, tree));
@@ -208,7 +211,7 @@ static void check_thrown_exceptions PROTO ((int, tree));
 static int check_thrown_exceptions_do PROTO ((tree));
 static void purge_unchecked_exceptions PROTO ((tree));
 static void check_throws_clauses PROTO ((tree, tree, tree));
-static void complete_method_declaration PROTO ((tree));
+static void finish_method_declaration PROTO ((tree));
 static tree build_super_invocation PROTO (());
 static int verify_constructor_circularity PROTO ((tree, tree));
 static char *constructor_circularity_msg PROTO ((tree, tree));
@@ -235,18 +238,22 @@ static tree patch_new_array_init PROTO ((tree, tree));
 static tree maybe_build_array_element_wfl PROTO ((tree));
 static int array_constructor_check_entry PROTO ((tree, tree));
 static char *purify_type_name PROTO ((char *));
-static tree patch_initialized_static_field PROTO ((tree));
 static tree fold_constant_for_init PROTO ((tree, tree));
+static tree strip_out_static_field_access_decl PROTO ((tree));
+static jdeplist *reverse_jdep_list PROTO ((struct parser_ctxt *));
+static void static_ref_err PROTO ((tree, tree, tree));
 
 /* Number of error found so far. */
 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;
 
 /* The current parser context */
-static struct parser_ctxt *ctxp;
+struct parser_ctxt *ctxp;
 
-/* List of things that were anlyzed for which code will be generated */
+/* List of things that were analyzed for which code will be generated */
 static struct parser_ctxt *ctxp_for_generation = NULL;
 
 /* binop_lookup maps token to tree_code. It is used where binary
@@ -281,6 +288,16 @@ static tree wfl_append = NULL_TREE;
 
 /* The "toString" identifier used for String `+' operator. */
 static tree wfl_to_string = NULL_TREE;
+
+/* The "java.lang" import qualified name.  */
+static tree java_lang_id = NULL_TREE;
+
+/* The "java.lang.Cloneable" qualified name.  */
+static tree java_lang_cloneable = NULL_TREE;
+
+/* Context and flag for static blocks */
+static tree current_static_block = NULL_TREE;
+
 %}
 
 %union {
@@ -293,6 +310,10 @@ static tree wfl_to_string = NULL_TREE;
   int value;
 }
 
+%{
+#include "lex.c"
+%}
+
 %pure_parser
 
 /* Things defined here have to match the order of what's in the
@@ -375,7 +396,7 @@ static tree wfl_to_string = NULL_TREE;
                        variable_initializers constructor_body
                        array_initializer
 
-%type   <node>         class_body block_end
+%type   <node>         class_body block_end constructor_block_end
 %type   <node>         statement statement_without_trailing_substatement
                        labeled_statement if_then_statement label_decl
                        if_then_else_statement while_statement for_statement
@@ -413,7 +434,7 @@ static tree wfl_to_string = NULL_TREE;
 %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
+%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>     CASE_TK DEFAULT_TK TRY_TK CATCH_TK SYNCHRONIZED_TK
@@ -591,10 +612,14 @@ type_import_on_demand_declaration:
        IMPORT_TK name DOT_TK MULT_TK SC_TK
                {
                  tree name = EXPR_WFL_NODE ($2);
-                 tree node = build_tree_list ($2, NULL_TREE);
-                 read_import_dir ($2);
-                 TREE_CHAIN (node) = ctxp->import_demand_list;
-                 ctxp->import_demand_list = node;
+                 /* Don't import java.lang.* twice. */
+                 if (name != java_lang_id)
+                   {
+                     tree node = build_tree_list ($2, NULL_TREE);
+                     read_import_dir ($2);
+                     TREE_CHAIN (node) = ctxp->import_demand_list;
+                     ctxp->import_demand_list = node;
+                   }
                }
 |      IMPORT_TK name DOT_TK error
                {yyerror ("'*' expected"); RECOVER;}
@@ -610,6 +635,10 @@ type_declaration:
                  $$ = $1;
                }
 |      interface_declaration
+               {
+                 maybe_generate_clinit ();
+                 $$ = $1;
+               }
 |      SC_TK
                { $$ = NULL; }
 |      error
@@ -660,7 +689,10 @@ class_declaration:
 |      CLASS_TK error
                {yyerror ("Missing class name"); RECOVER;}
 |       CLASS_TK identifier error
-               {if (!ctxp->class_err) yyerror ("'{' expected"); DRECOVER(class1);}
+               {
+                 if (!ctxp->class_err) yyerror ("'{' expected"); 
+                 DRECOVER(class1);
+               }
 |       modifiers CLASS_TK identifier error
                {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;}
 ;
@@ -703,9 +735,21 @@ interface_type_list:
 
 class_body:
        OCB_TK CCB_TK
-               { $$ = ctxp->current_parsed_class; }
+               { 
+                 /* Store the location of the `}' when doing xrefs */
+                 if (flag_emit_xref)
+                   DECL_END_SOURCE_LINE (ctxp->current_parsed_class) = 
+                     EXPR_WFL_ADD_COL ($2.location, 1);
+                 $$ = ctxp->current_parsed_class;
+               }
 |      OCB_TK class_body_declarations CCB_TK
-               { $$ = ctxp->current_parsed_class; }
+               { 
+                 /* Store the location of the `}' when doing xrefs */
+                 if (flag_emit_xref)
+                   DECL_END_SOURCE_LINE (ctxp->current_parsed_class) = 
+                     EXPR_WFL_ADD_COL ($3.location, 1);
+                 $$ = ctxp->current_parsed_class;
+               }
 ;
 
 class_body_declarations:
@@ -723,6 +767,8 @@ class_body_declaration:
 
 class_member_declaration:
        field_declaration
+|      field_declaration SC_TK
+               { $$ = $1; }
 |      method_declaration
 |      class_declaration       /* Added, JDK1.1 inner classes */
                { $$ = parse_jdk1_1_error ("inner classe declaration"); }
@@ -802,7 +848,7 @@ method_declaration:
                  source_start_java_method (current_function_decl);
                }
        method_body
-               { complete_method_declaration ($3); }
+               { finish_method_declaration ($3); }
 |      method_header error
                {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;}
 ;
@@ -871,7 +917,10 @@ formal_parameter:
                  $$ = build_tree_list ($2, $1);
                }
 |      modifiers type variable_declarator_id /* Added, JDK1.1 final parms */
-               { $$ = parse_jdk1_1_error ("final parameters"); }
+               { 
+                 parse_jdk1_1_error ("final parameters");
+                 $$ = build_tree_list ($3, $2);
+               }
 |      type error
                {yyerror ("Missing identifier"); RECOVER;}
 |      modifiers type error
@@ -909,11 +958,13 @@ method_body:
 static_initializer:
        static block
                {
-                 RULE ("STATIC_INITIALIZER");
+                 TREE_CHAIN ($2) = ctxp->static_initialized;
+                 ctxp->static_initialized = $2;
                }
 |      static block SC_TK      /* Shouldn't be here. FIXME */
                {
-                 RULE ("STATIC_INITIALIZER");
+                 TREE_CHAIN ($2) = ctxp->static_initialized;
+                 ctxp->static_initialized = $2;
                }
 ;
 
@@ -932,7 +983,7 @@ constructor_declaration:
                  source_start_java_method (current_function_decl);
                }
        constructor_body
-               { complete_method_declaration ($3); }
+               { finish_method_declaration ($3); }
 ;
 
 constructor_header:
@@ -953,19 +1004,23 @@ constructor_body:
        /* Unlike regular method, we always need a complete (empty)
           body so we can safely perform all the required code
           addition (super invocation and field initialization) */
-       block_begin block_end
+       block_begin constructor_block_end
                { 
                  BLOCK_EXPR_BODY ($2) = empty_stmt_node;
                  $$ = $2;
                }
-|      block_begin explicit_constructor_invocation block_end
+|      block_begin explicit_constructor_invocation constructor_block_end
                { $$ = $3; }
-|      block_begin block_statements block_end
+|      block_begin block_statements constructor_block_end
                { $$ = $3; }
-|       block_begin explicit_constructor_invocation block_statements block_end
+|       block_begin explicit_constructor_invocation block_statements constructor_block_end
                { $$ = $4; }
 ;
 
+constructor_block_end:
+       block_end
+|      block_end SC_TK
+
 /* Error recovery for that rule moved down expression_statement: rule.  */
 explicit_constructor_invocation:
        this_or_super OP_TK CP_TK SC_TK
@@ -991,15 +1046,13 @@ explicit_constructor_invocation:
 this_or_super:                 /* Added, simplifies error diagnostics */
        THIS_TK
                {
-                 tree wfl = build_wfl_node (this_identifier_node, 
-                                            input_filename, 0, 0);
+                 tree wfl = build_wfl_node (this_identifier_node);
                  EXPR_WFL_LINECOL (wfl) = $1.location;
                  $$ = wfl;
                }
 |      SUPER_TK
                {
-                 tree wfl = build_wfl_node (super_identifier_node,
-                                            input_filename, 0, 0);
+                 tree wfl = build_wfl_node (super_identifier_node);
                  EXPR_WFL_LINECOL (wfl) = $1.location;
                  $$ = wfl;
                }
@@ -1033,9 +1086,9 @@ interface_declaration:
                  $$ = $6;
                }
 |      INTERFACE_TK identifier error
-               {yyerror ("(here)'{' expected"); RECOVER;}
+               {yyerror ("'{' expected"); RECOVER;}
 |      modifiers INTERFACE_TK identifier error
-               {yyerror ("(there)'{' expected"); RECOVER;}
+               {yyerror ("'{' expected"); RECOVER;}
 ;
 
 extends_interfaces:
@@ -1117,7 +1170,13 @@ variable_initializers:
 /* 19.11 Production from 14: Blocks and Statements  */
 block:
        OCB_TK CCB_TK
-               { $$ = empty_stmt_node; }
+               { 
+                 /* 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 ($2.location, 1);
+                 $$ = empty_stmt_node; 
+               }
 |      block_begin block_statements block_end
                { $$ = $3; }
 ;
@@ -1131,6 +1190,10 @@ 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);                  
                  $$ = exit_block ();
                }
 ;
@@ -1166,13 +1229,7 @@ statement:
 |      if_then_else_statement
 |      while_statement
 |      for_statement
-               { 
-                 /* If the for loop is unlabeled, we must return the
-                    block it was defined it. It our last chance to
-                    get a hold on it. */
-                 if (!LOOP_HAS_LABEL_P ($$))
-                   $$ = exit_block ();
-               }
+               { $$ = exit_block (); }
 ;
 
 statement_nsi:
@@ -1181,6 +1238,7 @@ statement_nsi:
 |      if_then_else_statement_nsi
 |      while_statement_nsi
 |      for_statement_nsi
+               { $$ = exit_block (); }
 ;
 
 statement_without_trailing_substatement:
@@ -1215,22 +1273,14 @@ label_decl:
 
 labeled_statement:
        label_decl statement
-               { 
-                 $$ = complete_labeled_statement ($1, $2);
-                 pop_labeled_block ();
-                 POP_LABELED_BLOCK ();
-               }
+               { $$ = finish_labeled_statement ($1, $2); }
 |      identifier error
                {yyerror ("':' expected"); RECOVER;}
 ;
 
 labeled_statement_nsi:
        label_decl statement_nsi
-               { 
-                 $$ = complete_labeled_statement ($1, $2);
-                 pop_labeled_block ();
-                 POP_LABELED_BLOCK ();
-               }
+               { $$ = finish_labeled_statement ($1, $2); }
 ;
 
 /* We concentrate here a bunch of error handling rules that we couldn't write
@@ -1303,7 +1353,10 @@ statement_expression:
 
 if_then_statement:
        IF_TK OP_TK expression CP_TK statement
-       { $$ = build_if_else_statement ($2.location, $3, $5, NULL_TREE); }
+               { 
+                 $$ = build_if_else_statement ($2.location, $3, 
+                                               $5, NULL_TREE);
+               }
 |      IF_TK error
                {yyerror ("'(' expected"); RECOVER;}
 |      IF_TK OP_TK error
@@ -1314,12 +1367,12 @@ if_then_statement:
 
 if_then_else_statement:
        IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
-       { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
+               { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
 ;
 
 if_then_else_statement_nsi:
        IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
-       { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
+               { $$ = build_if_else_statement ($2.location, $3, $5, $7); }
 ;
 
 switch_statement:
@@ -1411,7 +1464,7 @@ while_expression:
 
 while_statement:
        while_expression statement
-               { $$ = complete_loop_body (0, NULL_TREE, $2, 0); }
+               { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
 |      WHILE_TK error
                {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;}
 |      WHILE_TK OP_TK error
@@ -1422,7 +1475,7 @@ while_statement:
 
 while_statement_nsi:
        while_expression statement_nsi
-               { $$ = complete_loop_body (0, NULL_TREE, $2, 0); }
+               { $$ = finish_loop_body (0, NULL_TREE, $2, 0); }
 ;
 
 do_statement_begin:
@@ -1436,15 +1489,15 @@ do_statement_begin:
 
 do_statement: 
        do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
-               { $$ = complete_loop_body ($4.location, $5, $2, 1); }
+               { $$ = finish_loop_body ($4.location, $5, $2, 1); }
 ;
 
 for_statement:
        for_begin SC_TK expression SC_TK for_update CP_TK statement
-               { $$ = complete_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
+               { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7); }
 |      for_begin SC_TK SC_TK for_update CP_TK statement
                { 
-                 $$ = complete_for_loop (0, NULL_TREE, $4, $6);
+                 $$ = 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) = 
                    empty_stmt_node;
@@ -1459,10 +1512,10 @@ for_statement:
 
 for_statement_nsi:
        for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
-               { $$ = complete_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
+               { $$ = finish_for_loop (EXPR_WFL_LINECOL ($3), $3, $5, $7);}
 |      for_begin SC_TK SC_TK for_update CP_TK statement_nsi
                { 
-                 $$ = complete_for_loop (0, NULL_TREE, $4, $6);
+                 $$ = 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) = 
                    empty_stmt_node;
@@ -1600,11 +1653,14 @@ synchronized:
 
 try_statement:
        TRY_TK block catches
-               { $$ = build_try_statement ($1.location, $2, $3, NULL_TREE); }
+               { $$ = build_try_statement ($1.location, $2, $3); }
 |      TRY_TK block finally
-               { $$ = build_try_statement ($1.location, $2, NULL_TREE, $3); }
+               { $$ = build_try_finally_statement ($1.location, $2, $3); }
 |      TRY_TK block catches finally
-               { $$ = build_try_statement ($1.location, $2, $3, $4); }
+               { $$ = build_try_finally_statement 
+                   ($1.location, build_try_statement ($1.location,
+                                                      $2, $3), $4);
+               }
 |      TRY_TK error
                {yyerror ("'{' expected"); DRECOVER (try_statement);}
 ;
@@ -1653,10 +1709,7 @@ catch_clause_parameter:
 
 finally:
        FINALLY_TK block
-               { 
-                 $$ = build (FINALLY_EXPR, NULL_TREE,
-                             create_label_decl (generate_name ()), $2);
-               }
+               { $$ = $2; }
 |      FINALLY_TK error
                {yyerror ("'{' expected"); RECOVER; }
 ;
@@ -1760,9 +1813,9 @@ array_creation_expression:
 |      NEW_TK class_or_interface_type dim_exprs
                { $$ = build_newarray_node ($2, $3, 0); }
 |      NEW_TK primitive_type dim_exprs dims
-               { $$ = build_newarray_node ($2, $3, ctxp->osb_number); }
+               { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
 |      NEW_TK class_or_interface_type dim_exprs dims
-               { $$ = build_newarray_node ($2, $3, ctxp->osb_number); }
+               { $$ = build_newarray_node ($2, $3, CURRENT_OSB (ctxp));}
         /* Added, JDK1.1 anonymous array. Initial documentation rule
            modified */
 |      NEW_TK class_or_interface_type dims array_initializer
@@ -1800,9 +1853,33 @@ dim_expr:
 
 dims:                          
        OSB_TK CSB_TK
-               { ctxp->osb_number = 1; }
+               { 
+                 int allocate = 0;
+                 /* If not initialized, allocate memory for the osb
+                     numbers stack */
+                 if (!ctxp->osb_limit)
+                   {
+                     allocate = ctxp->osb_limit = 32;
+                     ctxp->osb_depth = -1;
+                   }
+                 /* If capacity overflown, reallocate a bigger chuck */
+                 else if (ctxp->osb_depth+1 == ctxp->osb_limit)
+                   allocate = ctxp->osb_limit << 1;
+                 
+                 if (allocate)
+                   {
+                     allocate *= sizeof (int);
+                     if (ctxp->osb_number)
+                       ctxp->osb_number = (int *)xrealloc (ctxp->osb_number,
+                                                           allocate);
+                     else
+                       ctxp->osb_number = (int *)xmalloc (allocate);
+                   }
+                 ctxp->osb_depth++;
+                 CURRENT_OSB (ctxp) = 1;
+               }
 |      dims OSB_TK CSB_TK
-               { ctxp->osb_number++; }
+               { CURRENT_OSB (ctxp)++; }
 |      dims OSB_TK error
                { yyerror ("']' expected"); RECOVER;}
 ;
@@ -1815,8 +1892,7 @@ field_access:
 |      SUPER_TK DOT_TK identifier
                {
                  tree super_wfl = 
-                   build_wfl_node (super_identifier_node, 
-                                   input_filename, 0, 0);
+                   build_wfl_node (super_identifier_node);
                  EXPR_WFL_LINECOL (super_wfl) = $1.location;
                  $$ = make_qualified_name (super_wfl, $3, $2.location);
                }
@@ -1960,8 +2036,9 @@ cast_expression:          /* Error handling here is potentially weak */
        OP_TK primitive_type dims CP_TK unary_expression
                { 
                  tree type = $2;
-                 while (ctxp->osb_number--)
+                 while (CURRENT_OSB (ctxp)--)
                    type = build_java_array_type (type, -1);
+                 ctxp->osb_depth--;
                  $$ = build_cast ($1.location, type, $5); 
                }
 |      OP_TK primitive_type CP_TK unary_expression
@@ -1971,8 +2048,9 @@ cast_expression:          /* Error handling here is potentially weak */
 |      OP_TK name dims CP_TK unary_expression_not_plus_minus
                { 
                  char *ptr;
-                 while (ctxp->osb_number--)
+                 while (CURRENT_OSB (ctxp)--)
                    obstack_1grow (&temporary_obstack, '[');
+                 ctxp->osb_depth--;
                  obstack_grow0 (&temporary_obstack, 
                                 IDENTIFIER_POINTER (EXPR_WFL_NODE ($2)),
                                 IDENTIFIER_LENGTH (EXPR_WFL_NODE ($2)));
@@ -2230,8 +2308,6 @@ constant_expression:
 %%
 \f
 
-#include "lex.c"
-
 /* Flag for the error report routine to issue the error the first time
    it's called (overriding the default behavior which is to drop the
    first invocation and honor the second one, taking advantage of a
@@ -2246,7 +2322,7 @@ java_push_parser_context ()
   struct parser_ctxt *new = 
     (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
 
-  bzero (new, sizeof (struct parser_ctxt));
+  bzero ((PTR) new, sizeof (struct parser_ctxt));
   new->next = ctxp;
   ctxp = new;
   if (ctxp->next)
@@ -2414,7 +2490,7 @@ yyerror (msg)
 static void
 issue_warning_error_from_context (cl, msg, ap)
      tree cl;
-     char *msg;
+     const char *msg;
      va_list ap;
 {
   char *saved, *saved_input_filename;
@@ -2442,18 +2518,18 @@ issue_warning_error_from_context (cl, msg, ap)
 /* Issue an error message at a current source line CL */
 
 void
-parse_error_context VPROTO ((tree cl, char *msg, ...))
+parse_error_context VPROTO ((tree cl, const char *msg, ...))
 {
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
   tree cl;
-  char *msg;
+  const char *msg;
 #endif
   va_list ap;
 
   VA_START (ap, msg);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
   cl = va_arg (ap, tree);
-  msg = va_arg (ap, char *);
+  msg = va_arg (ap, const char *);
 #endif
   issue_warning_error_from_context (cl, msg, ap);
   va_end (ap);
@@ -2462,18 +2538,18 @@ parse_error_context VPROTO ((tree cl, char *msg, ...))
 /* Issue a warning at a current source line CL */
 
 static void
-parse_warning_context VPROTO ((tree cl, char *msg, ...))
+parse_warning_context VPROTO ((tree cl, const char *msg, ...))
 {
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
   tree cl;
-  char *msg;
+  const char *msg;
 #endif
   va_list ap;
 
   VA_START (ap, msg);
-#ifndef __STDC__
+#ifndef ANSI_PROTOTYPES
   cl = va_arg (ap, tree);
-  msg = va_arg (ap, char *);
+  msg = va_arg (ap, const char *);
 #endif
 
   force_error = do_warning = 1;
@@ -2494,25 +2570,30 @@ find_expr_with_wfl (node)
       switch (TREE_CODE (node))
        {
        case BLOCK:
-         return find_expr_with_wfl (BLOCK_EXPR_BODY (node));
+         node = BLOCK_EXPR_BODY (node);
+         continue;
 
        case COMPOUND_EXPR:
          to_return = find_expr_with_wfl (TREE_OPERAND (node, 0));
          if (to_return)
            return to_return;
-         to_return = find_expr_with_wfl (TREE_OPERAND (node, 1));
-         return to_return;
+         node = TREE_OPERAND (node, 1);
+         continue;
 
        case LOOP_EXPR:
-         return find_expr_with_wfl (TREE_OPERAND (node, 0));
+         node = TREE_OPERAND (node, 0);
+         continue;
          
        case LABELED_BLOCK_EXPR:
-         return find_expr_with_wfl (TREE_OPERAND (node, 1));
+         node = TREE_OPERAND (node, 1);
+         continue;
+
        default:
          code = TREE_CODE_CLASS (TREE_CODE (node));
          if (((code == '1') || (code == '2') || (code == 'e'))
              && EXPR_WFL_LINECOL (node))
            return node;
+         return NULL_TREE;
        }
     }
   return NULL_TREE;
@@ -2640,12 +2721,11 @@ build_array_from_name (type, type_wfl, name, ret_name)
   /* If we have, then craft a new type for this variable */
   if (more_dims)
     {
-      name = get_identifier (&more_dims [string]);
+      name = get_identifier (&string [more_dims]);
 
-      /* If type already is a reference on an array, get the base type */
-      if ((TREE_CODE (type) == POINTER_TYPE) && 
-         TYPE_ARRAY_P (TREE_TYPE (type)))
-       type = TREE_TYPE (type);
+      /* If we have a pointer, use its type */
+      if (TREE_CODE (type) == POINTER_TYPE)
+        type = TREE_TYPE (type);
 
       /* Building the first dimension of a primitive type uses this
          function */
@@ -2808,7 +2888,11 @@ maybe_create_class_interface_decl (decl, qualified_name, cl)
   
   /* Take care of the file and line business */
   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
-  DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
+  /* If we're emiting xrefs, store the line/col number information */
+  if (flag_emit_xref)
+    DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
+  else
+    DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
   CLASS_FROM_CURRENTLY_COMPILED_SOURCE_P (TREE_TYPE (decl)) =
     IS_A_COMMAND_LINE_FILENAME_P (EXPR_WFL_FILENAME_NODE (cl));
@@ -2890,7 +2974,7 @@ create_interface (flags, id, super)
   decl = maybe_create_class_interface_decl (decl, q_name, id);
 
   /* Set super info and mark the class a complete */
-  set_super_info (ACC_ABSTRACT | 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;
@@ -2909,7 +2993,7 @@ create_class (flags, id, super, interfaces)
 {
   tree raw_name = EXPR_WFL_NODE (id);
   tree class_id, decl;
-  tree super_decl = NULL, super_decl_type;
+  tree super_decl_type;
 
   class_id = parser_qualified_classname (id);
   decl = IDENTIFIER_CLASS_VALUE (class_id);
@@ -2941,17 +3025,8 @@ create_class (flags, id, super, interfaces)
          return NULL_TREE;
        }
 
-      /* The class is known and exists if there is a decl. Otherwise,
-         postpone the operation and do it later. */
-      super_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (super));
-      if (super_decl)
-       {
-         parser_check_super (super_decl, decl, id);
-         super_decl_type = TREE_TYPE (super_decl);
-       }
-      else
-       super_decl_type = 
-         register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
+      super_decl_type = 
+       register_incomplete_type (JDEP_SUPER, super, decl, NULL_TREE);
     }
   else if (TREE_TYPE (decl) != object_type_node)
     super_decl_type = object_type_node;
@@ -2966,6 +3041,11 @@ create_class (flags, id, super, interfaces)
   CLASS_COMPLETE_P (decl) = 1;
   add_superinterfaces (decl, interfaces);
 
+  /* If doing xref, store the location at which the inherited class
+     (if any) was seen. */
+  if (flag_emit_xref && super)
+    DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
+
   /* Eventually sets the @deprecated tag flag */
   CHECK_DEPRECATED (decl);
 
@@ -3109,7 +3189,10 @@ register_fields (flags, type, variable_list)
 
       /* Set lineno to the line the field was found and create a
          declaration for it. Eventually sets the @deprecated tag flag. */
-      lineno = EXPR_WFL_LINENO (cl);
+      if (flag_emit_xref)
+       lineno = EXPR_WFL_LINECOL (cl);
+      else
+       lineno = EXPR_WFL_LINENO (cl);
       field_decl = add_field (class_type, current_name, real_type, flags);
       CHECK_DEPRECATED (field_decl);
       
@@ -3117,11 +3200,6 @@ register_fields (flags, type, variable_list)
       if (must_chain)
        register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
          
-      /* Default value of a static field is 0 and it is considered
-        initialized. */
-      if (flags & ACC_STATIC)
-       INITIALIZED_P (field_decl) = 1;
-      
       /* If we have an initialization value tied to the field */
       if (init)
        {
@@ -3130,15 +3208,16 @@ register_fields (flags, type, variable_list)
            {
              /* We include the field and its initialization part into
                 a list used to generate <clinit>. After <clinit> is
-                walked, fields initialization will be processed and
-                fields initialized with know constants will be taken
-                out of <clinit> and have ther DECL_INITIAL set
+                walked, field initializations will be processed and
+                fields initialized with known constants will be taken
+                out of <clinit> and have their DECL_INITIAL set
                 appropriately. */
              TREE_CHAIN (init) = ctxp->static_initialized;
              ctxp->static_initialized = init;
              DECL_INITIAL (field_decl) = TREE_OPERAND (init, 1);
-             if (TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
-               TREE_STATIC (TREE_OPERAND (TREE_OPERAND (init, 1), 0)) = 1;
+             if (TREE_OPERAND (init, 1) 
+                 && TREE_CODE (TREE_OPERAND (init, 1)) == NEW_ARRAY_INIT)
+               TREE_STATIC (TREE_OPERAND (init, 1)) = 1;
            }
          /* A non-static field declared with an immediate initialization is
             to be initialized in <init>, if any.  This field is remembered
@@ -3148,7 +3227,6 @@ register_fields (flags, type, variable_list)
              TREE_CHAIN (init) = ctxp->non_static_initialized;
              ctxp->non_static_initialized = init;
            }
-         INITIALIZED_P (field_decl) = 1;
          MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
        }
     }
@@ -3256,7 +3334,8 @@ method_header (flags, type, mdecl, throws)
       ABSTRACT_CHECK (flags, ACC_FINAL, id, "Final");
       ABSTRACT_CHECK (flags, ACC_NATIVE, id, "Native");
       ABSTRACT_CHECK (flags, ACC_SYNCHRONIZED,id, "Synchronized");
-      if (!CLASS_ABSTRACT (TYPE_NAME (this_class)))
+      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'", 
@@ -3290,7 +3369,7 @@ method_header (flags, type, mdecl, throws)
 
   /* Method declared within the scope of an interface are implicitly
      abstract and public. Conflicts with other erroneously provided
-     modifiers are check right after. */
+     modifiers are checked right after. */
 
   if (CLASS_INTERFACE (TYPE_NAME (this_class)))
     {
@@ -3408,6 +3487,11 @@ method_header (flags, type, mdecl, throws)
   /* Eventually set the @deprecated tag flag */
   CHECK_DEPRECATED (meth);
 
+  /* If doing xref, store column and line number information instead
+     of the line number only. */
+  if (flag_emit_xref)
+    DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
+
   return meth;
 }
 
@@ -3432,16 +3516,43 @@ fix_method_argument_names (orig_arg, meth)
 /* Complete the method declaration with METHOD_BODY.  */
 
 static void
-complete_method_declaration (method_body)
+finish_method_declaration (method_body)
      tree method_body;
 {
+  int flags = get_access_flags_from_decl (current_function_decl);
+
+  /* 8.4.5 Method Body */
+  if ((flags & ACC_ABSTRACT || flags & ACC_NATIVE) && method_body)
+    {
+      tree wfl = DECL_NAME (current_function_decl);
+      parse_error_context (wfl, 
+                          "%s method `%s' can't have a body defined",
+                          (METHOD_NATIVE (current_function_decl) ?
+                           "Native" : "Abstract"),
+                          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+      method_body = NULL_TREE;
+    }
+  else if (!(flags & ACC_ABSTRACT) && !(flags & ACC_NATIVE) && !method_body)
+    {
+      tree wfl = DECL_NAME (current_function_decl);
+      parse_error_context (wfl, 
+                          "Non native and non abstract method `%s' must "
+                          "have a body defined",
+                          IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+      method_body = NULL_TREE;
+    }
+
   BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)) = method_body;
   maybe_absorb_scoping_blocks ();
   /* Exit function's body */
   exit_block ();
   /* Merge last line of the function with first line, directly in the
      function decl. It will be used to emit correct debug info. */
-  DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
+  if (!flag_emit_xref)
+    DECL_SOURCE_LINE_MERGE (current_function_decl, ctxp->last_ccb_indent1);
+  /* So we don't have an irrelevant function declaration context for
+     the next static block we'll see. */
+  current_function_decl = NULL_TREE;
 }
 
 /* Build a an error message for constructor circularity errors.  */
@@ -3762,16 +3873,14 @@ obtain_incomplete_type (type_name)
     fatal ("invalid type name - obtain_incomplete_type");
 
   for (ptr = ctxp->incomplete_class; ptr; ptr = TREE_CHAIN (ptr))
-    if (TYPE_NAME (TREE_PURPOSE (ptr)) == name)
+    if (TYPE_NAME (ptr) == name)
       break;
 
   if (!ptr)
     {
-      tree core;
       push_obstacks (&permanent_obstack, &permanent_obstack);
-      BUILD_PTR_FROM_NAME (core, name);
-      layout_type (core);
-      ptr = build_tree_list (core, NULL_TREE);
+      BUILD_PTR_FROM_NAME (ptr, name);
+      layout_type (ptr);
       pop_obstacks ();
       TREE_CHAIN (ptr) = ctxp->incomplete_class;
       ctxp->incomplete_class = ptr;
@@ -4033,8 +4142,22 @@ resolve_class (class_type, decl, cl)
 {
   char *name = IDENTIFIER_POINTER (TYPE_NAME (class_type));
   char *base = name;
-  tree resolved_type, resolved_type_decl;
+  tree resolved_type = TREE_TYPE (class_type);
+  tree resolved_type_decl;
   
+  if (resolved_type != NULL_TREE)
+    {
+      tree resolved_type_decl = TYPE_NAME (resolved_type);
+      if (resolved_type_decl == NULL_TREE
+         || TREE_CODE (resolved_type_decl) == IDENTIFIER_NODE)
+       {
+         resolved_type_decl = build_decl (TYPE_DECL,
+                                          TYPE_NAME (class_type),
+                                          resolved_type);
+       }
+      return resolved_type_decl;
+    }
+
   /* 1- Check to see if we have an array. If true, find what we really
      want to resolve  */
   while (name[0] == '[')
@@ -4065,21 +4188,22 @@ resolve_class (class_type, decl, cl)
       /* Figure how those two things are important for error report. FIXME */
       DECL_SOURCE_LINE (resolved_type_decl) = 0;
       DECL_SOURCE_FILE (resolved_type_decl) = input_filename;
+      TYPE_NAME (class_type) = TYPE_NAME (resolved_type);
     }
+  TREE_TYPE (class_type) = resolved_type;
   return resolved_type_decl;
 }
 
 /* Effectively perform the resolution of class CLASS_TYPE. DECL or CL
    are used to report error messages.  */
 
-static tree
+tree
 do_resolve_class (class_type, decl, cl)
      tree class_type;
      tree decl;
      tree cl;
 {
   tree new_class_decl;
-  tree new_name;
   tree original_name = NULL_TREE;
 
   /* Do not try to replace TYPE_NAME (class_type) by a variable, since
@@ -4324,7 +4448,7 @@ get_printable_method_name (decl)
      tree decl;
 {
   char *to_return;
-  tree name;
+  tree name = NULL_TREE;
 
   if (DECL_CONSTRUCTOR_P (decl))
     {
@@ -4346,8 +4470,7 @@ static int
 reset_method_name (method)
      tree method;
 {
-  if (DECL_NAME (method) != clinit_identifier_node
-      && DECL_NAME (method) != finit_identifier_node)
+  if (!IS_CLINIT (method) && DECL_NAME (method) != finit_identifier_node)
     {
       /* NAME is just the plain name when Object is being defined */
       if (DECL_CONTEXT (method) != object_type_node)
@@ -4395,8 +4518,8 @@ check_method_redefinition (class, method)
   tree redef, name;
   tree cl = DECL_NAME (method);
   tree sig = TYPE_ARGUMENT_SIGNATURE (TREE_TYPE (method));
-  /* decl name of artificial <clinit> and $finit$ doesn't need to be fixed and
-     checked */
+  /* decl name of artificial <clinit> and $finit$ doesn't need to be
+     fixed and checked */
 
   /* Reset the method name before running the check. If it returns 1,
      the method doesn't need to be verified with respect to method
@@ -4454,7 +4577,10 @@ java_check_regular_methods (class_decl)
       /* If we previously found something and its name was saved,
          reinstall it now */
       if (found && saved_found_wfl)
-       DECL_NAME (found) = saved_found_wfl;
+       {
+         DECL_NAME (found) = saved_found_wfl;
+         saved_found_wfl = NULL_TREE;
+       }
 
       /* Check for redefinitions */
       if (check_method_redefinition (class, method))
@@ -4486,8 +4612,13 @@ java_check_regular_methods (class_decl)
       found = lookup_argument_method (super_class, DECL_NAME (method), sig);
 
       /* Nothing overrides or it's a private method. */
-      if (!found || (found && METHOD_PRIVATE (found)))
+      if (!found)
        continue;
+      if (METHOD_PRIVATE (found))
+       {
+         found = NULL_TREE;
+         continue;
+       }
 
       /* If found wasn't verified, it's DECL_NAME won't be set properly. 
         We set it temporarily for the sake of the error report. */
@@ -4501,7 +4632,7 @@ java_check_regular_methods (class_decl)
          char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
                                                 0));
          parse_error_context 
-           (method_wfl, 
+           (method_wfl,
             "Method `%s' was defined with return type `%s' in class `%s'", 
             lang_printable_name (found, 0), t,
             IDENTIFIER_POINTER 
@@ -4509,6 +4640,28 @@ java_check_regular_methods (class_decl)
          free (t);
        }
 
+      aflags = get_access_flags_from_decl (found);
+      /* If the method has default, access in an other package, then
+        issue a warning that the current method doesn't override the
+        one that was found elsewhere. Do not issue this warning when
+        the match was found in java.lang.Object.  */
+      if (DECL_CONTEXT (found) != object_type_node
+         && ((aflags & 0x7) == 0)
+         && !class_in_current_package (DECL_CONTEXT (found))
+         && DECL_NAME (found) != clinit_identifier_node
+         && flag_not_overriding)
+        {
+         parse_warning_context 
+           (method_wfl, "Method `%s' in class `%s' does not "
+            "override the corresponding method in class `%s', which is "
+            "private to a different package",
+            lang_printable_name (found, 0),
+            IDENTIFIER_POINTER (DECL_NAME (class_decl)),
+            IDENTIFIER_POINTER (DECL_NAME 
+                                (TYPE_NAME (DECL_CONTEXT (found)))));
+         continue;
+       }
+
       /* Can't override final. Can't override static. */
       if (METHOD_FINAL (found) || METHOD_STATIC (found))
        {
@@ -4525,6 +4678,7 @@ java_check_regular_methods (class_decl)
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          continue;
        }
+
       /* Static method can't override instance method. */
       if (METHOD_STATIC (method))
        {
@@ -4538,7 +4692,6 @@ java_check_regular_methods (class_decl)
          continue;
        }
 
-      aflags = get_access_flags_from_decl (found);
       /* - Overriding/hiding public must be public
         - Overriding/hiding protected must be protected or public
          - If the overriden or hidden method has default (package)
@@ -4565,22 +4718,6 @@ java_check_regular_methods (class_decl)
         exceptions, if any */
       check_throws_clauses (method, method_wfl, found);
 
-      /* If the method has default access in an other package, then
-        issue a warning that the current method doesn't override the
-        one that was found elsewhere. Do not issue this warning when
-        the match was found in java.lang.Object.  */
-      if (DECL_CONTEXT (found) != object_type_node 
-         && (!aflags || (aflags > ACC_PROTECTED))
-         && !class_in_current_package (DECL_CONTEXT (found))
-         && flag_not_overriding)
-       parse_warning_context 
-         (method_wfl, "Method `%s' in class `%s' does not "
-          "override the corresponding method in class `%s', which is "
-          "private to a different package",
-          lang_printable_name (found, 0),
-          IDENTIFIER_POINTER (DECL_NAME (class_decl)),
-          IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
-
       /* Inheriting multiple methods with the same signature. FIXME */
     }
   
@@ -4915,7 +5052,7 @@ read_import_dir (wfl)
   char *package_name = IDENTIFIER_POINTER (package_id);
   int package_length = IDENTIFIER_LENGTH (package_id);
   DIR *dirp = NULL;
-  JCF jcfr, *jcf, *saved_jcf = current_jcf;
+  JCF *saved_jcf = current_jcf;
 
   int found = 0;
   int k;
@@ -4954,15 +5091,16 @@ read_import_dir (wfl)
                }
              *filename->ptr++ = '/';
 
-             for (; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
+             for (k = 0; k < zipf->count;  k++, zipd = ZIPDIR_NEXT (zipd))
                {
                  char *current_entry = ZIPDIR_FILENAME (zipd);
                  int current_entry_len = zipd->filename_length;
 
-                 if (strncmp (filename->data, current_entry, 
-                              BUFFER_LENGTH (filename)) != 0)
+                 if (current_entry_len >= BUFFER_LENGTH (filename)
+                     && strncmp (filename->data, current_entry, 
+                                 BUFFER_LENGTH (filename)) != 0)
                    continue;
-                 found += note_possible_classname (current_entry,
+                 found |= note_possible_classname (current_entry,
                                                    current_entry_len);
                }
            }
@@ -4986,7 +5124,6 @@ read_import_dir (wfl)
          *filename->ptr++ = '/';
          for (;;)
            {
-             int java_or_class = 0;
              int len; 
              char *d_name;
              struct dirent *direntp = readdir (dirp);
@@ -4996,7 +5133,7 @@ read_import_dir (wfl)
              len = strlen (direntp->d_name);
              buffer_grow (filename, len+1);
              strcpy (filename->ptr, d_name);
-             found += note_possible_classname (filename->data + entry_length,
+             found |= note_possible_classname (filename->data + entry_length,
                                                package_length+len+1);
            }
          if (dirp)
@@ -5038,9 +5175,9 @@ static int
 find_in_imports_on_demand (class_type)
      tree class_type;
 {
-  tree node, import, node_to_use;
+  tree node, import, node_to_use = NULL_TREE;
   int seen_once = -1;
-  tree cl;
+  tree cl = NULL_TREE;
 
   for (import = ctxp->import_demand_list; import; import = TREE_CHAIN (import))
     {
@@ -5157,6 +5294,13 @@ check_pkg_class_access (class_name, cl)
 
   if (!CLASS_PUBLIC (TYPE_NAME (type)))
     {
+      /* Access to a private class within the same package is
+         allowed. */
+      tree l, r;
+      breakdown_qualified (&l, &r, class_name);
+      if (l == ctxp->package)
+       return 0;
+
       parse_error_context 
        (cl, "Can't access %s `%s'. Only public classes and interfaces in "
         "other packages can be accessed",
@@ -5179,13 +5323,13 @@ declare_local_variables (modifier, type, vlist)
   tree type_wfl = NULL_TREE;
   int must_chain = 0;
 
-  /* Push a new block if statement were seen between the last time we
+  /* Push a new block if statements were seen between the last time we
      pushed a block and now. Keep a cound of block to close */
-  if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (current_function_decl)))
+  if (BLOCK_EXPR_BODY (GET_CURRENT_BLOCK (current_function_decl)))
     {
-      tree body = DECL_FUNCTION_BODY (current_function_decl);
+      tree body = GET_CURRENT_BLOCK (current_function_decl);
       tree b = enter_block ();
-      BLOCK_EXPR_ORIGIN(b) = body;
+      BLOCK_EXPR_ORIGIN (b) = body;
     }
 
   if (modifier)
@@ -5247,6 +5391,11 @@ declare_local_variables (modifier, type, vlist)
       decl = build_decl (VAR_DECL, name, real_type);
       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;
@@ -5386,7 +5535,6 @@ expand_start_java_method (fndecl)
       DECL_ARG_TYPE (tem) = type;
       layout_decl (tem, 0);
       pushdecl (tem);
-      INITIALIZED_P (tem) = 1; /* Parms are initialized */
       *ptr = tem;
       ptr = &TREE_CHAIN (tem);
       tem = next;
@@ -5394,7 +5542,6 @@ expand_start_java_method (fndecl)
   *ptr = NULL_TREE;
   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
-  complete_start_java_method (fndecl); 
 }
 
 /* Terminate a function and expand its body.  */
@@ -5403,6 +5550,7 @@ static void
 source_end_java_method ()
 {
   tree fndecl = current_function_decl;
+  int flag_asynchronous_exceptions = asynchronous_exceptions;
 
   java_parser_context_save_global ();
   lineno = ctxp->last_ccb_indent1;
@@ -5410,9 +5558,16 @@ source_end_java_method ()
   /* Set EH language codes */
   java_set_exception_lang_code ();
 
+  /* Turn function bodies with only a NOP expr null, so they don't get
+     generated at all and we won't get warnings when using the -W
+     -Wall flags. */
+  if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) == empty_stmt_node)
+    BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
+
   /* Generate function's code */
   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
-      && ! flag_emit_class_files)
+      && ! flag_emit_class_files
+      && ! flag_emit_xref)
     expand_expr_stmt (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)));
 
   /* pop out of its parameters */
@@ -5421,13 +5576,20 @@ source_end_java_method ()
   BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
 
   /* Generate rtl for function exit.  */
-  if (! flag_emit_class_files)
+  if (! flag_emit_class_files && ! flag_emit_xref)
     {
       lineno = DECL_SOURCE_LINE_LAST (fndecl);
       /* Emit catch-finally clauses */
       emit_handlers ();
       expand_function_end (input_filename, lineno, 0);
 
+      /* FIXME: If the current method contains any exception handlers,
+        force asynchronous_exceptions: this is necessary because signal
+        handlers in libjava may throw exceptions.  This is far from being
+        a perfect solution, but it's better than doing nothing at all.*/
+      if (catch_clauses)
+       asynchronous_exceptions = 1;
+
       /* Run the optimizers and output assembler code for this function. */
       rest_of_compilation (fndecl);
     }
@@ -5435,6 +5597,7 @@ source_end_java_method ()
   current_function_decl = NULL_TREE;
   /*  permanent_allocation (1); */
   java_parser_context_restore_global ();
+  asynchronous_exceptions = flag_asynchronous_exceptions;
 }
 
 /* Record EXPR in the current function block. Complements compound
@@ -5444,7 +5607,7 @@ tree
 java_method_add_stmt (fndecl, expr)
      tree fndecl, expr;
 {
-  return add_stmt_to_block (DECL_FUNCTION_BODY (fndecl), NULL_TREE, expr);
+  return add_stmt_to_block (GET_CURRENT_BLOCK (fndecl), NULL_TREE, expr);
 }
 
 static tree
@@ -5576,54 +5739,83 @@ void
 java_complete_expand_methods ()
 {
   tree current;
+
+  do_not_fold = flag_emit_xref;
   
   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
     {
+      int is_interface;
       tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
       tree decl;
 
       current_class = TREE_TYPE (current);
+      is_interface = CLASS_INTERFACE (TYPE_NAME (current_class));
 
       /* Initialize a new constant pool */
       init_outgoing_cpool ();
 
       /* We want <clinit> (if any) to be processed first. */
       decl = tree_last (TYPE_METHODS (class_type));
-      if (decl && DECL_NAME (decl) == clinit_identifier_node)
+      if (IS_CLINIT (decl))
        {
-         tree list = nreverse (TYPE_METHODS (class_type));
-         list = TREE_CHAIN (list);
-         TREE_CHAIN (decl) = NULL_TREE;
-         TYPE_METHODS (class_type) = chainon (decl, nreverse (list));
-       }
+         tree fbody = DECL_FUNCTION_BODY (decl);
+         tree list;
+         if (fbody != NULL_TREE)
+           {
+             /* First check if we can ignore empty <clinit> */
+             tree block_body = BLOCK_EXPR_BODY (fbody);
 
-      /* Don't process function bodies in interfaces */
-      if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
-       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
-         {
-           current_function_decl = decl;
-           /* Don't generate debug info on line zero when expanding a
-              generated constructor. */
-           if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
-             {
-               /* If we found errors, it's too dangerous to try to generate
-                  and expand a constructor */
-               if (!java_error_count)
-                 {
-                   restore_line_number_status (1);
-                   java_complete_expand_method (decl);
-                   restore_line_number_status (0);
+             current_this = NULL_TREE;
+             current_function_decl = decl;
+             if (block_body != NULL_TREE)
+               {
+                 /* Prevent the use of `this' inside <clinit> */
+                 ctxp->explicit_constructor_p = 1;
+
+                 block_body = java_complete_tree (block_body);
+                 ctxp->explicit_constructor_p = 0;
+                 BLOCK_EXPR_BODY (fbody) = block_body;
+                 if (block_body != NULL_TREE
+                     && TREE_CODE (block_body) == BLOCK
+                     && BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
+                   decl = NULL_TREE;
+               }
+           }
+         list = nreverse (TREE_CHAIN (nreverse (TYPE_METHODS (class_type))));
+         if (decl != NULL_TREE)
+           {
+             TREE_CHAIN (decl) = list;
+             TYPE_METHODS (class_type) = decl;
+           }
+           else
+             TYPE_METHODS (class_type) = list;
+       }
+      
+      for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
+       {
+         current_function_decl = decl;
+         /* Don't generate debug info on line zero when expanding a
+            generated constructor. */
+         if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl))
+           {
+             /* If we found errors, it's too dangerous to try to
+                generate and expand a constructor */
+             if (!java_error_count)
+               {
+                 restore_line_number_status (1);
+                 java_complete_expand_method (decl);
+                 restore_line_number_status (0);
                  }
-             }
-           else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
-             continue;
-           else 
-             java_complete_expand_method (decl);
-         }
+           }
+         else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
+           continue;
+         else 
+           java_complete_expand_method (decl);
+       }
 
       /* Now verify constructor circularity (stop after the first one
          we find) */
-      if (!CLASS_INTERFACE (TYPE_NAME (current_class)))
+      if (!is_interface)
        for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
          if (DECL_CONSTRUCTOR_P (decl) && 
              verify_constructor_circularity (decl, decl))
@@ -5635,7 +5827,9 @@ java_complete_expand_methods ()
        {
          if (flag_emit_class_files)
            write_classfile (current_class);
-         else
+         if (flag_emit_xref)
+           expand_xref (current_class);
+         else if (! flag_syntax_only)
            finish_class (current_class);
        }
     }
@@ -5660,13 +5854,20 @@ java_complete_expand_method (mdecl)
     {
       tree fbody = DECL_FUNCTION_BODY (mdecl);
       tree block_body = BLOCK_EXPR_BODY (fbody);
+      tree exception_copy;
       expand_start_java_method (mdecl);
+      build_result_decl (mdecl);
 
       current_this 
        = (!METHOD_STATIC (mdecl) ? 
           BLOCK_EXPR_DECLS (DECL_FUNCTION_BODY (mdecl)) : NULL_TREE);
 
-      /* Purge the `throws' list of unchecked exceptions */
+      /* Purge the `throws' list of unchecked exceptions. If we're
+        doing xref, save a copy of the list and re-install it
+        later. */
+      if (flag_emit_xref)
+       exception_copy = copy_list (DECL_FUNCTION_THROWS (mdecl));
+
       purge_unchecked_exceptions (mdecl);
 
       /* Install exceptions thrown with `throws' */
@@ -5675,14 +5876,19 @@ java_complete_expand_method (mdecl)
       if (block_body != NULL_TREE)
        {
          block_body = java_complete_tree (block_body);
-         check_for_initialization (block_body);
+         if (!flag_emit_xref)
+           check_for_initialization (block_body);
+         ctxp->explicit_constructor_p = 0;
        }
       BLOCK_EXPR_BODY (fbody) = block_body;
 
       if ((block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
-         && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
+         && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
+         && !flag_emit_xref)
        missing_return_error (current_function_decl);
 
+      complete_start_java_method (mdecl); 
+
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -5697,6 +5903,9 @@ java_complete_expand_method (mdecl)
       POP_EXCEPTIONS();
       if (currently_caught_type_list)
        fatal ("Exception list non empty - java_complete_expand_method");
+
+      if (flag_emit_xref)
+       DECL_FUNCTION_THROWS (mdecl) = exception_copy;
     }
 }
 
@@ -5815,7 +6024,7 @@ java_expand_finals ()
 void
 java_expand_classes ()
 {
-  int save_error_count = java_error_count;
+  int save_error_count = 0;
   java_parse_abort_on_error ();
   if (!(ctxp = ctxp_for_generation))
     return;
@@ -5852,7 +6061,7 @@ make_qualified_primary (primary, right, location)
      different form than a SUPER. Turn THIS into something symbolic */
   if (TREE_CODE (primary) == THIS_EXPR)
     {
-      wfl = build_wfl_node (this_identifier_node, input_filename, 0, 0);
+      wfl = build_wfl_node (this_identifier_node);
       EXPR_WFL_LINECOL (wfl) = EXPR_WFL_LINECOL (primary);
       wfl = make_qualified_name (wfl, right, location);
       PRIMARY_P (wfl) = 1;
@@ -5984,12 +6193,7 @@ resolve_expression_name (id, orig)
                 a static variable. */
              if (!fs && METHOD_STATIC (current_function_decl))
                {
-                 parse_error_context 
-                   (id, "Can't make a static reference to nonstatic variable "
-                    "`%s' in class `%s'",
-                    IDENTIFIER_POINTER (name),
-                    IDENTIFIER_POINTER (DECL_NAME 
-                                        (TYPE_NAME (current_class))));
+                 static_ref_err (id, name, current_class);
                  return error_mark_node;
                }
              /* Instance variables can't appear as an argument of
@@ -6004,9 +6208,9 @@ resolve_expression_name (id, orig)
 
              /* Otherwise build what it takes to access the field */
              decl = build_field_ref ((fs ? NULL_TREE : current_this),
-                                     current_class, name);
-             if (fs && !flag_emit_class_files)
-               decl = build_class_init (current_class, decl);
+                                     DECL_CONTEXT (decl), name);
+             if (fs && !flag_emit_class_files && !flag_emit_xref)
+               decl = build_class_init (DECL_CONTEXT (decl), decl);
              /* We may be asked to save the real field access node */
              if (orig)
                *orig = decl;
@@ -6034,6 +6238,17 @@ resolve_expression_name (id, orig)
   return error_mark_node;
 }
 
+static void
+static_ref_err (wfl, field_id, class_type)
+    tree wfl, field_id, class_type;
+{
+  parse_error_context 
+    (wfl, 
+     "Can't make a static reference to nonstatic variable `%s' in class `%s'",
+     IDENTIFIER_POINTER (field_id), 
+     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))));
+}
+
 /* 15.10.1 Field Acess 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
@@ -6054,7 +6269,7 @@ resolve_field_access (qual_wfl, field_decl, field_type)
 
   /* Resolve the LENGTH field of an array here */
   if (DECL_NAME (decl) == length_identifier_node && TYPE_ARRAY_P (type_found)
-      && ! flag_emit_class_files)
+      && ! flag_emit_class_files && ! flag_emit_xref)
     {
       tree length = build_java_array_length_access (where_found);
       field_ref =
@@ -6062,14 +6277,14 @@ resolve_field_access (qual_wfl, field_decl, field_type)
     }
   /* We might have been trying to resolve field.method(). In which
      case, the resolution is over and decl is the answer */
-  else if (DECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
+  else if (JDECL_P (decl) && IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) == decl)
     field_ref = decl;
-  else if (DECL_P (decl))
+  else if (JDECL_P (decl))
     {
       int static_final_found = 0;
       if (!type_found)
        type_found = DECL_CONTEXT (decl);
-      is_static = DECL_P (decl) && FIELD_STATIC (decl);
+      is_static = JDECL_P (decl) && FIELD_STATIC (decl);
       if (FIELD_FINAL (decl) 
          && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
          && DECL_LANG_SPECIFIC (decl)
@@ -6079,16 +6294,18 @@ resolve_field_access (qual_wfl, field_decl, field_type)
          static_final_found = 1;
        }
       else
-       field_ref = build_field_ref ((is_static ? 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;
-      if (is_static && !static_final_found && !flag_emit_class_files)
+      if (is_static && !static_final_found 
+         && !flag_emit_class_files && !flag_emit_xref)
        {
          field_ref = build_class_init (type_found, field_ref);
          /* If the static field was identified by an expression that
             needs to be generated, make the field access a compound
-            expression whose first part of the evaluation of the
+            expression whose first part is the evaluation of the
             field selector part. */
          if (where_found && TREE_CODE (where_found) != TYPE_DECL 
              && TREE_CODE (where_found) != RECORD_TYPE)
@@ -6109,6 +6326,30 @@ resolve_field_access (qual_wfl, field_decl, field_type)
   return field_ref;
 }
 
+/* If NODE is an access to f static field, strip out the class
+   initialization part and return the field decl, otherwise, return
+   NODE. */
+
+static tree
+strip_out_static_field_access_decl (node)
+    tree node;
+{
+  if (TREE_CODE (node) == COMPOUND_EXPR)
+    {
+      tree op1 = TREE_OPERAND (node, 1);
+      if (TREE_CODE (op1) == COMPOUND_EXPR)
+        {
+          tree call = TREE_OPERAND (op1, 0);
+          if (TREE_CODE (call) == CALL_EXPR
+              && TREE_CODE (TREE_OPERAND (call, 0)) == ADDR_EXPR
+              && TREE_OPERAND (TREE_OPERAND (call, 0), 0)
+              == soft_initclass_node)
+            return TREE_OPERAND (op1, 1);
+        }
+    }
+  return node;
+}
+
 /* 6.5.5.2: Qualified Expression Names */
 
 static int
@@ -6134,7 +6375,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
        case NEW_CLASS_EXPR:
          /* If the access to the function call is a non static field,
             build the code to access it. */
-         if (DECL_P (decl) && !FIELD_STATIC (decl))
+         if (JDECL_P (decl) && !FIELD_STATIC (decl))
            {
              decl = maybe_access_field (decl, *where_found, 
                                         DECL_CONTEXT (decl));
@@ -6168,6 +6409,14 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
            }
          continue;
 
+       case NEW_ARRAY_EXPR:
+         *where_found = decl = java_complete_tree (qual_wfl);
+         if (decl == error_mark_node)
+           return 1;
+         *type_found = type = QUAL_DECL_TYPE (decl);
+         CLASS_LOADED_P (type) = 1;
+         continue;
+
        case CONVERT_EXPR:
          *where_found = decl = java_complete_tree (qual_wfl);
          if (decl == error_mark_node)
@@ -6187,7 +6436,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
        case ARRAY_REF:
          /* If the access to the function call is a non static field,
             build the code to access it. */
-         if (DECL_P (decl) && !FIELD_STATIC (decl))
+         if (JDECL_P (decl) && !FIELD_STATIC (decl))
            {
              decl = maybe_access_field (decl, *where_found, type);
              if (decl == error_mark_node)
@@ -6203,6 +6452,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
        default:
          /* Fix for -Wall Just go to the next statement. Don't
              continue */
+         break;
        }
 
       /* If we fall here, we weren't processing a (static) function call. */
@@ -6292,7 +6542,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
              parse_error_context 
                (qual_wfl, "Can't access %s field `%s.%s' from `%s'",
                 java_accstring_lookup (get_access_flags_from_decl (decl)),
-                IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
+                GET_TYPE_NAME (type),
                 IDENTIFIER_POINTER (DECL_NAME (decl)),
                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
              return 1;
@@ -6316,8 +6566,17 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
              decl = QUAL_RESOLUTION (q);
              if (!type)
                {
-                 if (!FIELD_STATIC (decl))
-                   *where_found = current_this;
+                 if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
+                   {
+                     if (current_this)
+                       *where_found = current_this;
+                     else
+                       {
+                         static_ref_err (qual_wfl, DECL_NAME (decl),
+                                         current_class);
+                         return 1;
+                       }
+                   }
                  else
                    {
                      *where_found = TREE_TYPE (decl);
@@ -6348,15 +6607,18 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                  return 1;
                }
              
-             if (!(field_decl = 
-                   lookup_field_wrapper (type, EXPR_WFL_NODE (qual_wfl))))
+             field_decl = lookup_field_wrapper (type,
+                                                EXPR_WFL_NODE (qual_wfl));
+             if (field_decl == NULL_TREE)
                {
                  parse_error_context 
-                   (qual_wfl, "No variable `%s' defined in class `%s'",
+                   (qual_wfl, "No variable `%s' defined in type `%s'",
                     IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)), 
-                    IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+                    GET_TYPE_NAME (type));
                  return 1;
                }
+             if (field_decl == error_mark_node)
+               return 1;
 
              /* Layout the type of field_decl, since we may need
                  it. Don't do primitive types or loaded classes. The
@@ -6381,7 +6643,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                     "Can't access %s field `%s.%s' from `%s'",
                     java_accstring_lookup 
                       (get_access_flags_from_decl (field_decl)),
-                    IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
+                    GET_TYPE_NAME (type),
                     IDENTIFIER_POINTER (DECL_NAME (field_decl)),
                     IDENTIFIER_POINTER 
                       (DECL_NAME (TYPE_NAME (current_class))));
@@ -6397,11 +6659,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
              if (!from_super && from_type 
                  && !TYPE_INTERFACE_P (type) && !is_static)
                {
-                 parse_error_context 
-                   (qual_wfl, "Can't make a static reference to nonstatic "
-                    "variable `%s' in class `%s'",
-                    IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
-                    IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+                 static_ref_err (qual_wfl, EXPR_WFL_NODE (qual_wfl), type);
                  return 1;
                }
              from_cast = from_super = 0;
@@ -6583,6 +6841,7 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl)
   tree list;
   int is_static_flag = 0;
   int is_super_init = 0;
+  tree this_arg = NULL_TREE;
   
   /* Should be overriden if everything goes well. Otherwise, if
      something fails, it should keep this value. It stop the
@@ -6680,7 +6939,8 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl)
                                       identifier, args);
 
          /* 4- Add the field as an argument */
-         args = tree_cons (NULL_TREE, field, nreverse (args));
+         args = nreverse (args);
+         this_arg = field;
        }
 
       /* IDENTIFIER_WFL will be used to report any problem further */
@@ -6775,8 +7035,8 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl)
         returned by the object allocator. If method is resolved as a
         primary, use the primary otherwise use the current THIS. */
       args = nreverse (args);
-      if (!METHOD_STATIC (list) && TREE_CODE (patch) != NEW_CLASS_EXPR)
-       args = tree_cons (NULL_TREE, primary ? primary : current_this, args);
+      if (TREE_CODE (patch) != NEW_CLASS_EXPR)
+       this_arg = primary ? primary : current_this;
     }
 
   /* Merge point of all resolution schemes. If we have nothing, this
@@ -6801,6 +7061,8 @@ patch_method_invocation (patch, primary, where, is_static, ret_decl)
   check_deprecation (wfl, list);
 
   is_static_flag = METHOD_STATIC (list);
+  if (! METHOD_STATIC (list) && this_arg != NULL_TREE)
+    args = tree_cons (NULL_TREE, this_arg, args);
 
   /* In the context of an explicit constructor invocation, we can't
      invoke any method relying on `this'. Exceptions are: we're
@@ -6885,7 +7147,7 @@ patch_invoke (patch, method, args)
        TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
   
-  if (flag_emit_class_files)
+  if (flag_emit_class_files || flag_emit_xref)
     func = method;
   else
     {
@@ -6931,7 +7193,7 @@ patch_invoke (patch, method, args)
     {
       tree class = DECL_CONTEXT (method);
       tree c1, saved_new, size, new;
-      if (flag_emit_class_files)
+      if (flag_emit_class_files || flag_emit_xref)
        {
          TREE_TYPE (patch) = build_pointer_type (class);
          return patch;
@@ -6996,13 +7258,9 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
   /* Fix the arguments */
   for (node = arg_list; node; node = TREE_CHAIN (node))
     {
-      tree current_arg = TREE_VALUE (node);
-      /* Integer constant 0 passed as itself, not as a type */
-      if (current_arg != integer_zero_node)
-       current_arg = TREE_TYPE (TREE_VALUE (node));
+      tree current_arg = TREE_TYPE (TREE_VALUE (node));
       /* Non primitive type may have to be resolved */
-      if (current_arg != integer_zero_node 
-         && !JPRIMITIVE_TYPE_P (current_arg))
+      if (!JPRIMITIVE_TYPE_P (current_arg))
        resolve_and_layout (current_arg, NULL_TREE);
       /* And promoted */
       if (TREE_CODE (current_arg) == RECORD_TYPE)
@@ -7042,9 +7300,6 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
       candidates = obstack_finish (&temporary_obstack);
     }
   /* Issue the error message */
-  for (node = atl; node; node = TREE_CHAIN (node))
-    if (TREE_VALUE (node) == integer_zero_node)
-      TREE_VALUE (node) = long_type_node;
   method = make_node (FUNCTION_TYPE);
   TYPE_ARG_TYPES (method) = atl;
   signature = build_java_argument_signature (method);
@@ -7067,40 +7322,101 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
      int lc;
      tree class, name, arglist;
 {
-  tree method;
   tree list = NULL_TREE, all_list = NULL_TREE;
 
-  while (class != NULL_TREE)
+  /* Search interfaces */
+  if (CLASS_INTERFACE (TYPE_NAME (class)))
     {
-      for (method = TYPE_METHODS (class);
-          method != NULL_TREE;  method = TREE_CHAIN (method))
+      static tree searched_interfaces = NULL_TREE;
+      static int search_not_done = 0;
+      int i, n;
+      tree basetype_vec = TYPE_BINFO_BASETYPES (class);
+
+      /* Have we searched this interface already? */
+      if (searched_interfaces)
+       {  
+         tree current;  
+         for (current = searched_interfaces; 
+              current; current = TREE_CHAIN (current))
+           if (TREE_VALUE (current) == class)
+             return NULL;
+       }
+      searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
+
+      search_applicable_methods_list 
+       (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
+
+      n = TREE_VEC_LENGTH (basetype_vec);
+      for (i = 0; i < n; i++)
        {
-         if (lc && !DECL_CONSTRUCTOR_P (method))
-           continue;
-         else if (!lc && (DECL_CONSTRUCTOR_P (method)
-                          || (GET_METHOD_NAME (method) != name)))
+         tree t = BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i));
+         tree rlist;
+
+         /* Skip java.lang.Object (we'll search it once later.) */
+         if (t == object_type_node)
            continue;
-         
-         if (argument_types_convertible (method, arglist))
-           {
-             /* Retain accessible methods only */
-             if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
-                                    method, 0))
-               list = tree_cons (NULL_TREE, method, list);
-             else
-             /* Also retain all selected method here */
-               all_list = tree_cons (NULL_TREE, method, list);
-           }
+
+         search_not_done++;
+         rlist = find_applicable_accessible_methods_list (lc,  t, name, 
+                                                          arglist);
+         all_list = chainon (rlist, (list ? list : all_list)); 
+         search_not_done--;
+       }
+
+      /* We're done. Reset the searched interfaces list and finally search
+         java.lang.Object */
+      if (!search_not_done)
+       {  
+         searched_interfaces = NULL_TREE;  
+         search_applicable_methods_list (lc, TYPE_METHODS (object_type_node),
+                                         name, arglist, &list, &all_list);
        }
-      /* When dealing with constructor, stop here, otherwise search
-         other classes */
-      class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
     }
+  /* Search classes */
+  else
+    while (class != NULL_TREE)
+      {
+       search_applicable_methods_list 
+         (lc, TYPE_METHODS (class), name, arglist, &list, &all_list);
+       class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
+      }
+
   /* Either return the list obtained or all selected (but
      inaccessible) methods for better error report. */
   return (!list ? all_list : list);
 }
 
+/* Effectively search for the approriate method in method */
+
+static void 
+search_applicable_methods_list(lc, method, name, arglist, list, all_list)
+     int lc;
+     tree method, name, arglist;
+     tree *list, *all_list;
+{
+  for (; method; method = TREE_CHAIN (method))
+    {
+      /* When dealing with constructor, stop here, otherwise search
+         other classes */
+      if (lc && !DECL_CONSTRUCTOR_P (method))
+       continue;
+      else if (!lc && (DECL_CONSTRUCTOR_P (method) 
+                      || (GET_METHOD_NAME (method) != name)))
+       continue;
+         
+      if (argument_types_convertible (method, arglist))
+       {
+         /* Retain accessible methods only */
+         if (!not_accessible_p (DECL_CONTEXT (current_function_decl), 
+                                method, 0))
+           *list = tree_cons (NULL_TREE, method, *list);
+         else
+           /* Also retain all selected method here */
+           *all_list = tree_cons (NULL_TREE, method, *list);
+       }
+    }
+}    
+
 /* 15.11.2.2 Choose the Most Specific Method */
 
 static tree
@@ -7209,7 +7525,7 @@ qualify_ambiguous_name (id)
      tree id;
 {
   tree qual, qual_wfl, name, decl, ptr_type, saved_current_class;
-  int again, super_found = 0, this_found = 0;
+  int again, super_found = 0, this_found = 0, new_array_found = 0;
 
   /* We first qualify the first element, then derive qualification of
      others based on the first one. If the first element is qualified
@@ -7237,6 +7553,10 @@ qualify_ambiguous_name (id)
            qual_wfl = QUAL_WFL (qual);
          }
        break;
+      case NEW_ARRAY_EXPR:
+       qual = TREE_CHAIN (qual);
+       new_array_found = again = 1;
+       continue;
       case NEW_CLASS_EXPR:
       case CONVERT_EXPR:
        qual_wfl = TREE_OPERAND (qual_wfl, 0);
@@ -7279,9 +7599,11 @@ qualify_ambiguous_name (id)
        /* Do one more interation to set things up */
        super_found = again = 1;
       }
-    /* Loop one more time if we're dealing with ?: or a string constant */
+    /* Loop one more time if we're dealing with ?: or a string
+       constant, or a convert expression */
     if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
-       || TREE_CODE (qual_wfl) == STRING_CST)
+       || TREE_CODE (qual_wfl) == STRING_CST
+       || TREE_CODE (qual_wfl) == CONVERT_EXPR)
       {
        qual = TREE_CHAIN (qual);
        qual_wfl = QUAL_WFL (qual);
@@ -7293,7 +7615,6 @@ qualify_ambiguous_name (id)
      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 && (decl = IDENTIFIER_LOCAL_VALUE (name)))
     {
       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
@@ -7302,11 +7623,13 @@ qualify_ambiguous_name (id)
 
   /* If within the class/interface NAME was found to be used there
      exists a (possibly inherited) field named NAME, then this is an
-     expression name. */
-  else if ((decl = lookup_field_wrapper (ptr_type, name)))
+     expression name. If we saw a NEW_ARRAY_EXPR before and want to
+     address length, it is OK. */
+  else if ((decl = lookup_field_wrapper (ptr_type, name))
+          || (new_array_found && name == length_identifier_node))
     {
       RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
-      QUAL_RESOLUTION (qual) = decl;
+      QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
     }
 
   /* We reclassify NAME as a type name if:
@@ -7396,7 +7719,8 @@ java_complete_tree (node)
 {
   node = java_complete_lhs (node);
   if (TREE_CODE (node) == VAR_DECL && FIELD_STATIC (node)
-      && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE)
+      && FIELD_FINAL (node) && DECL_INITIAL (node) != NULL_TREE
+      && !flag_emit_xref)
     {
       tree value = DECL_INITIAL (node);
       DECL_INITIAL (node) = NULL_TREE;
@@ -7408,6 +7732,22 @@ java_complete_tree (node)
   return node;
 }
 
+static tree
+java_stabilize_reference (node)
+     tree node;
+{
+  if (TREE_CODE (node) == COMPOUND_EXPR)
+    {
+      tree op0 = TREE_OPERAND (node, 0);
+      tree op1 = TREE_OPERAND (node, 1);
+      TREE_OPERAND (node, 0) = save_expr (op0);
+      TREE_OPERAND (node, 1) = java_stabilize_reference (op1);
+      return node;
+    }
+  else
+    return stabilize_reference (node);
+}
+
 /* Patch tree nodes in a function body. When a BLOCK is found, push
    local variable decls if present.
    Same as java_complete_tree, but does not resolve static finals to values. */
@@ -7439,7 +7779,6 @@ java_complete_lhs (node)
        {
          DECL_CONTEXT (cn) = current_function_decl;
          IDENTIFIER_LOCAL_VALUE (DECL_NAME (cn)) = cn;
-         INITIALIZED_P (cn) = 0;
        }
       if (BLOCK_EXPR_BODY (node) == NULL_TREE)
          CAN_COMPLETE_NORMALLY (node) = 1;
@@ -7470,11 +7809,19 @@ java_complete_lhs (node)
          /* Now do the actual complete, without deep recursion for
              long blocks. */
          ptr = &BLOCK_EXPR_BODY (node);
-         while (TREE_CODE (*ptr) == COMPOUND_EXPR)
+         while (TREE_CODE (*ptr) == COMPOUND_EXPR
+                && TREE_OPERAND (*ptr, 1) != empty_stmt_node)
            {
              tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
              tree *next = &TREE_OPERAND (*ptr, 1);
              TREE_OPERAND (*ptr, 0) = cur;
+             if (cur == empty_stmt_node)
+               {
+                 /* Optimization;  makes it easier to detect empty bodies.
+                    Most useful for <clinit> with all-constant initializer. */
+                 *ptr = *next;
+                 continue;
+               }
              if (TREE_CODE (cur) == ERROR_MARK)
                error_seen++;
              else if (! CAN_COMPLETE_NORMALLY (cur))
@@ -7490,8 +7837,7 @@ java_complete_lhs (node)
                        break;
                    }
                  if (TREE_CODE (wfl_op2) != CASE_EXPR
-                     && TREE_CODE (wfl_op2) != DEFAULT_EXPR
-                     && wfl_op2 != empty_stmt_node)
+                     && TREE_CODE (wfl_op2) != DEFAULT_EXPR)
                    unreachable_stmt_error (*ptr);
                }
              ptr = next;
@@ -7524,16 +7870,27 @@ java_complete_lhs (node)
     case TRY_EXPR:
       return patch_try_statement (node);
 
+    case TRY_FINALLY_EXPR:
+      COMPLETE_CHECK_OP_0 (node);
+      COMPLETE_CHECK_OP_1 (node);
+      CAN_COMPLETE_NORMALLY (node)
+       = (CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0))
+          && CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1)));
+      TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 0));
+      return node;
+
     case CLEANUP_POINT_EXPR:
       COMPLETE_CHECK_OP_0 (node);
       TREE_TYPE (node) = void_type_node;
-      CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
+      CAN_COMPLETE_NORMALLY (node) = 
+       CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
       return node;
 
     case WITH_CLEANUP_EXPR:
       COMPLETE_CHECK_OP_0 (node);
       COMPLETE_CHECK_OP_2 (node);
-      CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
+      CAN_COMPLETE_NORMALLY (node) = 
+       CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
       TREE_TYPE (node) = void_type_node;
       return node;
 
@@ -7543,7 +7900,13 @@ java_complete_lhs (node)
        COMPLETE_CHECK_OP_1 (node);
       TREE_TYPE (node) = void_type_node;
       POP_LABELED_BLOCK ();
-      if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
+
+      if (LABELED_BLOCK_BODY (node) == empty_stmt_node)
+       {
+         LABELED_BLOCK_BODY (node) = NULL_TREE;
+         CAN_COMPLETE_NORMALLY (node) = 1;
+       }
+      else if (CAN_COMPLETE_NORMALLY (LABELED_BLOCK_BODY (node)))
        CAN_COMPLETE_NORMALLY (node) = 1;
       return node;
 
@@ -7560,7 +7923,7 @@ java_complete_lhs (node)
       /* First, the case expression must be constant */
       cn = fold (cn);
 
-      if (!TREE_CONSTANT (cn))
+      if (!TREE_CONSTANT (cn) && !flag_emit_xref)
        {
          EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
          parse_error_context (node, "Constant expression required");
@@ -7625,15 +7988,18 @@ java_complete_lhs (node)
        node = patch_switch_statement (node);
 
       if (TREE_OPERAND (node, 0) == error_mark_node)
-       return error_mark_node;
-      TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
-      /* If we returned something different, that's because we
-         inserted a label. Pop the label too. */
-      if (nn != node)
+       nn = error_mark_node;
+      else
        {
-         if (CAN_COMPLETE_NORMALLY (node))
-           CAN_COMPLETE_NORMALLY (nn) = 1;
-         POP_LABELED_BLOCK ();
+         TREE_TYPE (nn) = TREE_TYPE (node) = void_type_node;
+         /* If we returned something different, that's because we
+            inserted a label. Pop the label too. */
+         if (nn != node)
+           {
+             if (CAN_COMPLETE_NORMALLY (node))
+               CAN_COMPLETE_NORMALLY (nn) = 1;
+             POP_LABELED_BLOCK ();
+           }
        }
       POP_LOOP ();
       return nn;
@@ -7672,18 +8038,30 @@ java_complete_lhs (node)
       wfl_op2 = TREE_OPERAND (node, 1);
       TREE_OPERAND (node, 0) = nn = 
        java_complete_tree (TREE_OPERAND (node, 0));
-      if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK
-         && TREE_OPERAND (node, 1) != empty_stmt_node)
+      if (wfl_op2 == empty_stmt_node)
+       CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (nn);
+      else
        {
-         SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
-         parse_error_context (wfl_operator, "Unreachable statement");
+         if (! CAN_COMPLETE_NORMALLY (nn) && TREE_CODE (nn) != ERROR_MARK)
+           {
+             /* An unreachable condition in a do-while statement
+                is *not* (technically) an unreachable statement. */
+             nn = wfl_op2;
+             if (TREE_CODE (nn) == EXPR_WITH_FILE_LOCATION)
+               nn = EXPR_WFL_NODE (nn);
+             if (TREE_CODE (nn) != EXIT_EXPR)
+               {
+                 SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+                 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;
+         CAN_COMPLETE_NORMALLY (node)
+           = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
        }
-      TREE_OPERAND (node, 1) = java_complete_tree (TREE_OPERAND (node, 1));
-      if (TREE_OPERAND (node, 1) == error_mark_node)
-       return error_mark_node;
       TREE_TYPE (node) = TREE_TYPE (TREE_OPERAND (node, 1));
-      CAN_COMPLETE_NORMALLY (node)
-       = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 1));
       break;
 
     case RETURN_EXPR:
@@ -7694,7 +8072,17 @@ java_complete_lhs (node)
       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
          || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
        {
+         tree wfl = node;
          node = resolve_expression_name (node, NULL);
+         if (node == error_mark_node)
+           return node;
+         /* Keep line number information somewhere were it doesn't
+            disrupt the completion process. */
+         if (flag_emit_xref)
+           {
+             EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
+             TREE_OPERAND (node, 1) = wfl;
+           }
          CAN_COMPLETE_NORMALLY (node) = 1;
        }
       else
@@ -7705,9 +8093,14 @@ java_complete_lhs (node)
          body = java_complete_tree (EXPR_WFL_NODE (node));
          lineno = save_lineno;
          EXPR_WFL_NODE (node) = body;
-         TREE_SIDE_EFFECTS (node) = 1;
+         TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
          CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
-         if (EXPR_WFL_NODE (node) == error_mark_node)
+         if (body == empty_stmt_node)
+           {
+             /* Optimization;  makes it easier to detect empty bodies. */
+             return body;
+           }
+         if (body == error_mark_node)
            {
              /* Its important for the evaluation of assignment that
                 this mark on the TREE_TYPE is propagated. */
@@ -7745,7 +8138,8 @@ java_complete_lhs (node)
       /* They complete the array creation expression, if no errors
          were found. */
       CAN_COMPLETE_NORMALLY (node) = 1;
-      return (flag ? error_mark_node : patch_newarray (node));
+      return (flag ? error_mark_node
+             : force_evaluation_order (patch_newarray (node)));
 
     case NEW_CLASS_EXPR:
     case CALL_EXPR:
@@ -7769,56 +8163,64 @@ java_complete_lhs (node)
              tree_cons (wfl, decl, 
                         DECL_CONSTRUCTOR_CALLS (current_function_decl));
          CAN_COMPLETE_NORMALLY (node) = 1;
-         return node;
+         return force_evaluation_order (node);
        }
 
     case MODIFY_EXPR:
       /* 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 = fold_constant_for_init (nn, nn);
+         if (value != NULL_TREE)
+           {
+             tree type = TREE_TYPE (value);
+             if (JPRIMITIVE_TYPE_P (type) || type == string_ptr_type_node)
+               return empty_stmt_node;
+           }
+         DECL_INITIAL (nn) = NULL_TREE;
+       }
       wfl_op2 = TREE_OPERAND (node, 1);
-      TREE_OPERAND (node, 0) = java_complete_lhs (wfl_op1);
+
       if (TREE_OPERAND (node, 0) == error_mark_node)
        return error_mark_node;
 
       if (COMPOUND_ASSIGN_P (wfl_op2))
        {
-         tree lvalue;
-         tree other = 
-           java_complete_tree (TREE_OPERAND (wfl_op2, 0));
+         tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); 
 
          /* Hand stablize the lhs on both places */
-         lvalue = stabilize_reference (other); 
          TREE_OPERAND (node, 0) = lvalue;
          TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue;
+
+         /* Now complete the RHS. We write it back later on. */
+         nn = java_complete_tree (TREE_OPERAND (node, 1));
+
+         if ((cn = patch_string (nn)))
+           nn = cn;
+
+         /* 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), 
+                                              TREE_TYPE (lvalue), nn));
        }
 
       /* If we're about to patch a NEW_ARRAY_INIT, we call a special
         function to complete this RHS */
-      if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
+      else if (TREE_CODE (wfl_op2) == NEW_ARRAY_INIT)
        nn = patch_new_array_init (TREE_TYPE (TREE_OPERAND (node, 0)),
                                   TREE_OPERAND (node, 1));
+      /* Otherwise we simply complete the RHS */
       else
        nn = java_complete_tree (TREE_OPERAND (node, 1));
 
-      /* There are cases where the type of RHS is fixed. In those
-        cases, if the evaluation of the RHS fails, we further the
-        evaluation of the assignment to detect more errors. */
       if (nn == error_mark_node)
-       {
-         /* It's hopeless, but we can further things on to discover
-            an error during the assignment. In any cases, the
-            assignment operation fails. */
-         if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
-             && TREE_CODE (TREE_OPERAND (node, 1)) != NEW_ARRAY_INIT
-             && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
-           patch_assignment (node, wfl_op1, wfl_op2);
-
-         /* Now, we still mark the lhs as initialized */
-         if (DECL_P (TREE_OPERAND (node, 0)))
-           INITIALIZED_P (TREE_OPERAND (node, 0)) = 1;
+       return error_mark_node;
 
-         return error_mark_node;
-       }
+      /* Write back the RHS as we evaluated it. */
       TREE_OPERAND (node, 1) = nn;
 
       /* In case we're handling = with a String as a RHS, we need to
@@ -7828,16 +8230,6 @@ java_complete_lhs (node)
        TREE_OPERAND (node, 1) = nn;
       node = patch_assignment (node, wfl_op1, wfl_op2);
       CAN_COMPLETE_NORMALLY (node) = 1;
-
-      /* Before returning the node, in the context of a static field
-         assignment in <clinit>, we may want to carray further
-         optimizations. (VAR_DECL means it's a static field. See
-         add_field. */
-      if (DECL_NAME (current_function_decl) == clinit_identifier_node
-         && MODIFY_EXPR_FROM_INITIALIZATION_P (node)
-         && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL)
-       node = patch_initialized_static_field (node);
-
       return node;
 
     case MULT_EXPR:
@@ -7867,22 +8259,33 @@ java_complete_lhs (node)
       CAN_COMPLETE_NORMALLY (node) = 1;
       /* Don't complete string nodes if dealing with the PLUS operand. */
       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op1))
-       {
-         TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
-         if (TREE_OPERAND (node, 0) == error_mark_node)
-           return error_mark_node;
-       }
+        {
+          nn = java_complete_tree (wfl_op1);
+          if (nn == error_mark_node)
+            return error_mark_node;
+          if ((cn = patch_string (nn)))
+            nn = cn;
+          TREE_OPERAND (node, 0) = nn;
+        }
       if (TREE_CODE (node) != PLUS_EXPR || !JSTRING_P (wfl_op2))
-       {
-         TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
-         if (TREE_OPERAND (node, 1) == error_mark_node)
-           return error_mark_node;
-       }
-      return patch_binop (node, wfl_op1, wfl_op2);
+        {
+          nn = java_complete_tree (wfl_op2);
+          if (nn == error_mark_node)
+            return error_mark_node;
+          if ((cn = patch_string (nn)))
+            nn = cn;
+          TREE_OPERAND (node, 1) = nn;
+        }
+      return force_evaluation_order (patch_binop (node, wfl_op1, wfl_op2));
 
     case INSTANCEOF_EXPR:
       wfl_op1 = TREE_OPERAND (node, 0);
       COMPLETE_CHECK_OP_0 (node);
+      if (flag_emit_xref)
+       {
+         TREE_TYPE (node) = boolean_type_node;
+         return node;
+       }
       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
 
     case UNARY_PLUS_EXPR:
@@ -7912,14 +8315,14 @@ java_complete_lhs (node)
       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
       if (TREE_OPERAND (node, 0) == error_mark_node)
        return error_mark_node;
-      if (!flag_emit_class_files)
+      if (!flag_emit_class_files && !flag_emit_xref)
        TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
       /* The same applies to wfl_op2 */
       wfl_op2 = TREE_OPERAND (node, 1);
       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
       if (TREE_OPERAND (node, 1) == error_mark_node)
        return error_mark_node;
-      if (!flag_emit_class_files)
+      if (!flag_emit_class_files && !flag_emit_xref)
        TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
       return patch_array_ref (node);
 
@@ -8069,7 +8472,12 @@ enter_a_block (b)
 {
   tree fndecl = current_function_decl; 
 
-  if (!DECL_FUNCTION_BODY (fndecl))
+  if (!fndecl) {
+    BLOCK_SUPERCONTEXT (b) = current_static_block;
+    current_static_block = b;
+  }
+
+  else if (!DECL_FUNCTION_BODY (fndecl))
     {
       BLOCK_SUPERCONTEXT (b) = fndecl;
       DECL_FUNCTION_BODY (fndecl) = b;
@@ -8089,11 +8497,20 @@ enter_a_block (b)
 static tree
 exit_block ()
 {
-  tree b = DECL_FUNCTION_BODY (current_function_decl);
-
-  if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
-    DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
+  tree b;
+  if (current_function_decl)
+    {
+      b = DECL_FUNCTION_BODY (current_function_decl);
+      if (BLOCK_SUPERCONTEXT (b) != current_function_decl)
+       DECL_FUNCTION_BODY (current_function_decl) = BLOCK_SUPERCONTEXT (b);
+    }
+  else
+    {
+      b = current_static_block;
 
+      if (BLOCK_SUPERCONTEXT (b))
+       current_static_block = BLOCK_SUPERCONTEXT (b);
+    }
   return b;
 }
 
@@ -8105,7 +8522,7 @@ static tree
 lookup_name_in_blocks (name)
      tree name;
 {
-  tree b = DECL_FUNCTION_BODY (current_function_decl);
+  tree b = GET_CURRENT_BLOCK (current_function_decl);
 
   while (b != current_function_decl)
     {
@@ -8127,7 +8544,7 @@ lookup_name_in_blocks (name)
 static void
 maybe_absorb_scoping_blocks ()
 {
-  while (BLOCK_EXPR_ORIGIN (DECL_FUNCTION_BODY (current_function_decl)))
+  while (BLOCK_EXPR_ORIGIN (GET_CURRENT_BLOCK (current_function_decl)))
     {
       tree b = exit_block ();
       java_method_add_stmt (current_function_decl, b);
@@ -8150,8 +8567,7 @@ build_super_invocation ()
     return empty_stmt_node;
   else
     {
-      tree super_wfl = build_wfl_node (super_identifier_node, 
-                                      input_filename, 0, 0);
+      tree super_wfl = build_wfl_node (super_identifier_node);
       return build_method_invocation (super_wfl, NULL_TREE);
     }
 }
@@ -8167,8 +8583,7 @@ build_this_super_qualified_invocation (use_this, name, args, lloc, rloc)
 {
   tree invok;
   tree wfl = 
-    build_wfl_node ((use_this ? this_identifier_node : super_identifier_node),
-                   input_filename, 0, 0);
+    build_wfl_node (use_this ? this_identifier_node : super_identifier_node);
   EXPR_WFL_LINECOL (wfl) = lloc;
   invok = build_method_invocation (name, args);
   return make_qualified_primary (wfl, invok, rloc);
@@ -8248,14 +8663,15 @@ print_int_node (node)
   return buffer;
 }
 
-/* Return 1 if you an assignment of a FINAL is attempted */
+/* Return 1 if an assignment to a FINAL is attempted in a non suitable
+   context.  */
 
 static int
 check_final_assignment (lvalue, wfl)
      tree lvalue, wfl;
 {
-  if (DECL_P (lvalue) && FIELD_FINAL (lvalue) &&
-      DECL_NAME (current_function_decl) != clinit_identifier_node)
+  if (JDECL_P (lvalue) 
+      && FIELD_FINAL (lvalue) && !IS_CLINIT (current_function_decl))
     {
       parse_error_context 
         (wfl, "Can't assign a value to the final variable `%s'",
@@ -8311,9 +8727,8 @@ patch_assignment (node, wfl_op1, wfl_op2)
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
 
   /* Lhs can be a named variable */
-  if (DECL_P (lvalue))
+  if (JDECL_P (lvalue))
     {
-      INITIALIZED_P (lvalue) = 1;
       lhs_type = TREE_TYPE (lvalue);
     }
   /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +
@@ -8332,13 +8747,17 @@ patch_assignment (node, wfl_op1, wfl_op2)
   /* 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
-          && resolve_expression_name (wfl_op1, &llvalue)
-          && check_final_assignment (llvalue, wfl_op1))
+          && resolve_expression_name (wfl_op1, &llvalue))
     {
-      error_found = 1;
-      /* What we should do instead is resetting the all the flags
-         previously set, exchange lvalue for llvalue and continue. */
-      return error_mark_node;
+      if (check_final_assignment (llvalue, wfl_op1))
+       {
+         /* What we should do instead is resetting the all the flags
+            previously set, exchange lvalue for llvalue and continue. */
+         error_found = 1;
+         return error_mark_node;
+       }
+      else 
+       lhs_type = TREE_TYPE (lvalue);
     }
   else 
     {
@@ -8406,43 +8825,64 @@ patch_assignment (node, wfl_op1, wfl_op2)
   if (error_found)
     return error_mark_node;
 
-  /* If we built a compound expression as the result of a reference
-     assignment into an array element, return it here. */
-  if (TREE_CODE (node) == COMPOUND_EXPR)
-    return node;
-
-  TREE_OPERAND (node, 0) = lvalue;
-  TREE_OPERAND (node, 1) = new_rhs;
-  TREE_TYPE (node) = lhs_type;
-  return node;
-}
+  /* 10.10: Array Store Exception runtime check */
+  if (!flag_emit_class_files
+      && !flag_emit_xref
+      && lvalue_from_array 
+      && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type))
+      && !CLASS_FINAL (TYPE_NAME (GET_SKIP_TYPE (rhs_type))))
+    {
+      tree check;
+      tree base = lvalue;
 
-/* Optimize static (final) field initialized upon declaration.
-     - If the field is static final and is assigned to a primitive
-       constant type, then set its DECL_INITIAL to the value.
-     - More to come.  */
+      /* We need to retrieve the right argument for _Jv_CheckArrayStore */
+      if (TREE_CODE (lvalue) == COMPOUND_EXPR)
+       base = TREE_OPERAND (lvalue, 0);
+      else
+       {
+         if (flag_bounds_check)
+           base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);
+         else
+           base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
+       }
 
-static tree
-patch_initialized_static_field (node)
-     tree node;
-{
-  tree field = TREE_OPERAND (node, 0);
-  tree value = TREE_OPERAND (node, 1);
+      /* Build the invocation of _Jv_CheckArrayStore */
+      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;
 
-  if (DECL_INITIAL (field) != NULL_TREE)
-    {
-      tree type = TREE_TYPE (value);
-      if (FIELD_FINAL (field) && TREE_CONSTANT (value)
-         && (JPRIMITIVE_TYPE_P (type)
-             || (flag_emit_class_files
-                 && TREE_CODE (type) == POINTER_TYPE
-                 && TREE_TYPE (type) == string_type_node)))
+      /* 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 
        {
-         DECL_INITIAL (field) = value;
-         return empty_stmt_node;
+         /* Make sure the bound check will happen before the store check */
+         if (flag_bounds_check)
+           TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =
+             build (COMPOUND_EXPR, void_type_node,
+                    TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);
+         else
+           lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);
        }
-      DECL_INITIAL (field) = NULL_TREE;
     }
+
+  TREE_OPERAND (node, 0) = lvalue;
+  TREE_OPERAND (node, 1) = new_rhs;
+  TREE_TYPE (node) = lhs_type;
   return node;
 }
 
@@ -8528,24 +8968,17 @@ static int
 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
      tree lhs_type, rhs_type;
 {
-  int all_primitive;
-
+  /* 5.1.1: This is the identity conversion part. */
   if (lhs_type == rhs_type)
     return 1;
 
-  /* Sometimes, instead of passing a type, we pass integer_zero_node
-     so we know that an integral type can accomodate it */
-  if (JINTEGRAL_TYPE_P (lhs_type) && (rhs_type == integer_zero_node))
-    return 1;
-
-  all_primitive = 
-    JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
-
-  if (!all_primitive)
+  /* Reject non primitive types */
+  if (!JPRIMITIVE_TYPE_P (lhs_type) || !JPRIMITIVE_TYPE_P (rhs_type))
     return 0;
 
-  /* byte, even if it's smaller than a char can't be converted into a
-     char. Short can't too, but the < test below takes care of that */
+  /* 5.1.2: widening primitive conversion. byte, even if it's smaller
+     than a char can't be converted into a char. Short can't too, but
+     the < test below takes care of that */
   if (lhs_type == char_type_node && rhs_type == byte_type_node)
     return 0;
 
@@ -8559,13 +8992,13 @@ valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
          || rhs_type == promoted_boolean_type_node))
     return 1;
 
-  if (JINTEGRAL_TYPE_P (rhs_type)
-      && ((TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_type))
-         || (JFLOAT_TYPE_P (lhs_type) &&
-             TYPE_PRECISION (rhs_type) == TYPE_PRECISION (lhs_type))))
-    return 1;
-  else if (JFLOAT_TYPE_P (rhs_type)
-          && (TYPE_PRECISION (rhs_type) < TYPE_PRECISION (lhs_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) 
+       && (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))
     return 1;
 
   return 0;
@@ -8583,6 +9016,9 @@ valid_ref_assignconv_cast_p (source, dest, cast)
      tree dest;
      int cast;
 {
+  /* SOURCE or DEST might be null if not from a declared entity. */
+  if (!source || !dest)
+    return 0;
   if (JNULLP_TYPE_P (source))
     return 1;
   if (TREE_CODE (source) == POINTER_TYPE)
@@ -8660,8 +9096,10 @@ valid_ref_assignconv_cast_p (source, dest, cast)
     {
       if (TYPE_CLASS_P (dest))
        return dest == object_type_node;
+      /* Can't cast an array to an interface unless the interface is
+        java.lang.Cloneable */
       if (TYPE_INTERFACE_P (dest))
-       return 0;               /* Install test on Clonable. FIXME */
+       return (DECL_NAME (TYPE_NAME (dest)) == java_lang_cloneable ? 1 : 0);
       else                     /* Arrays */
        {
          tree source_element_type = TYPE_ARRAY_ELEMENT (source);
@@ -8714,16 +9152,17 @@ do_unary_numeric_promotion (arg)
   return arg;
 }
 
+/* Return a non zero 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)
      tree dest, source;
 {
-  return (((JPRIMITIVE_TYPE_P (source) || (source == integer_zero_node))
-           && JPRIMITIVE_TYPE_P (dest)
-           && valid_builtin_assignconv_identity_widening_p (dest, source))
-          || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
-              && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
-              && valid_ref_assignconv_cast_p (source, dest, 0)));
+  return ((JPRIMITIVE_TYPE_P (source) && JPRIMITIVE_TYPE_P (dest)
+          && valid_builtin_assignconv_identity_widening_p (dest, source))
+         || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
+             && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
+             && valid_ref_assignconv_cast_p (source, dest, 0)));
 }
 
 /* Build an incomplete binop expression. */
@@ -8812,7 +9251,7 @@ patch_binop (node, wfl_op1, wfl_op2)
   tree op2 = TREE_OPERAND (node, 1);
   tree op1_type = TREE_TYPE (op1);
   tree op2_type = TREE_TYPE (op2);
-  tree prom_type;
+  tree prom_type = NULL_TREE;
   int code = TREE_CODE (node);
 
   /* If 1, tell the routine that we have to return error_mark_node
@@ -8841,10 +9280,18 @@ patch_binop (node, wfl_op1, wfl_op2)
       /* Change the division operator if necessary */
       if (code == RDIV_EXPR && TREE_CODE (prom_type) == INTEGER_TYPE)
        TREE_SET_CODE (node, TRUNC_DIV_EXPR);
-      /* This one is more complicated. FLOATs are processed by a function
-        call to soft_fmod. */
+
+      /* This one is more complicated. FLOATs are processed by a
+        function call to soft_fmod. Duplicate the value of the
+        COMPOUND_ASSIGN_P flag. */
       if (code == TRUNC_MOD_EXPR)
-       return build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
+       {
+         tree mod = build_java_binop (TRUNC_MOD_EXPR, prom_type, op1, op2);
+         COMPOUND_ASSIGN_P (mod) = COMPOUND_ASSIGN_P (node);
+         TREE_SIDE_EFFECTS (mod)
+           = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+         return mod;
+       }
       break;
 
     /* 15.17 Additive Operators */
@@ -8919,8 +9366,19 @@ patch_binop (node, wfl_op1, wfl_op2)
       /* The >>> operator is a >> operating on unsigned quantities */
       if (code == URSHIFT_EXPR && ! flag_emit_class_files)
        {
-         op1 = convert (unsigned_type (prom_type), op1);
+         tree to_return;
+          tree utype = unsigned_type (prom_type);
+          op1 = convert (utype, op1);
          TREE_SET_CODE (node, RSHIFT_EXPR);
+          TREE_OPERAND (node, 0) = op1;
+          TREE_OPERAND (node, 1) = op2;
+          TREE_TYPE (node) = utype;
+         to_return = convert (prom_type, node);
+         /* Copy the original value of the COMPOUND_ASSIGN_P flag */
+         COMPOUND_ASSIGN_P (to_return) = COMPOUND_ASSIGN_P (node);
+         TREE_SIDE_EFFECTS (to_return)
+           = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+         return to_return;
        }
       break;
 
@@ -8954,6 +9412,7 @@ patch_binop (node, wfl_op1, wfl_op2)
          else if (flag_emit_class_files)
            {
              TREE_OPERAND (node, 1) = op2_type;
+             TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1);
              return node;
            }
          /* Otherwise we have to invoke instance of to figure it out */
@@ -8967,7 +9426,7 @@ patch_binop (node, wfl_op1, wfl_op2)
                        build_tree_list (NULL_TREE,
                                         build_class_ref (op2_type))),
                       NULL_TREE);
-             TREE_SIDE_EFFECTS (call) = 1;
+             TREE_SIDE_EFFECTS (call) = TREE_SIDE_EFFECTS (op1);
              return call;
            }
        }
@@ -9104,7 +9563,19 @@ patch_binop (node, wfl_op1, wfl_op2)
   TREE_OPERAND (node, 0) = op1;
   TREE_OPERAND (node, 1) = op2;
   TREE_TYPE (node) = prom_type;
-  return fold (node);
+  TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
+  
+  if (flag_emit_xref)
+    return node;
+
+  /* fold does not respect side-effect order as required for Java but not C.
+   * Also, it sometimes create SAVE_EXPRs which are bad when emitting
+   * bytecode.
+   */
+  if (flag_emit_class_files ? (TREE_CONSTANT (op1) && TREE_CONSTANT (op2))
+      : ! TREE_SIDE_EFFECTS (node))
+    node = fold (node);
+  return node;
 }
 
 /* Concatenate the STRING_CST CSTE and STRING. When AFTER is a non
@@ -9223,25 +9694,42 @@ build_string_concatenation (op1, op2)
      tree op1, op2;
 {
   tree result;
+  int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (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;
 
-  /* If operands are string constant, turn then into object references */
+  /* Discard empty strings on either side of the expression */
+  if (TREE_CODE (op1) == STRING_CST && TREE_STRING_LENGTH (op1) == 0)
+    {
+      op1 = op2;
+      op2 = NULL_TREE;
+    }
+  else if (TREE_CODE (op2) == STRING_CST && TREE_STRING_LENGTH (op2) == 0)
+    op2 = NULL_TREE;
 
+  /* If operands are string constant, turn then into object references */
   if (TREE_CODE (op1) == STRING_CST)
     op1 = patch_string_cst (op1);
-  if (TREE_CODE (op2) == STRING_CST)
+  if (op2 && TREE_CODE (op2) == STRING_CST)
     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)
+    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: 
         1) OP1 is a string reference, we call new StringBuffer(OP1)
-        2) Op2 is something else, we call new StringBuffer().append(OP1). */
+        2) OP1 is something else, we call new StringBuffer().append(OP1). */
       if (JSTRING_TYPE_P (TREE_TYPE (op1)))
        op1 = BUILD_STRING_BUFFER (op1);
       else
@@ -9251,13 +9739,19 @@ build_string_concatenation (op1, op2)
        }
     }
 
-  /* No longer the last node holding a crafted StringBuffer */
-  IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
-  /* Create a node for `{new...,xxx}.append (op2)' */
-  op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
+  if (op2)
+    {
+      /* OP1 is no longer the last node holding a crafted StringBuffer */
+      IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
+      /* Create a node for `{new...,xxx}.append (op2)' */
+      if (op2)
+       op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
+    }
+
   /* Mark the last node holding a crafted StringBuffer */
   IS_CRAFTED_STRING_BUFFER_P (op1) = 1;
-  
+
+  TREE_SIDE_EFFECTS (op1) = side_effects;
   return op1;
 }
 
@@ -9302,7 +9796,7 @@ patch_string_cst (node)
       location = alloc_name_constant (CONSTANT_String, node);
       node = build_ref_from_constant_pool (location);
     }
-  TREE_TYPE (node) = promote_type (string_type_node);
+  TREE_TYPE (node) = string_ptr_type_node;
   TREE_CONSTANT (node) = 1;
   return node;
 }
@@ -9383,7 +9877,7 @@ patch_unaryop (node, wfl_op)
 {
   tree op = TREE_OPERAND (node, 0);
   tree op_type = TREE_TYPE (op);
-  tree prom_type, value;
+  tree prom_type = NULL_TREE, value, decl;
   int code = TREE_CODE (node);
   int error_found = 0;
 
@@ -9399,9 +9893,15 @@ patch_unaryop (node, wfl_op)
     case PREINCREMENT_EXPR:
       /* 15.14.2 Prefix Decrement Operator -- */
     case PREDECREMENT_EXPR:
-      if (!DECL_P (op) && !((TREE_CODE (op) == INDIRECT_REF 
-                            || TREE_CODE (op) == COMPONENT_REF) 
-                           && JPRIMITIVE_TYPE_P (TREE_TYPE (op))))
+      decl = strip_out_static_field_access_decl (op);
+      /* We really should have a JAVA_ARRAY_EXPR to avoid this */
+      if (!JDECL_P (decl) 
+         && TREE_CODE (decl) != COMPONENT_REF
+         && !(flag_emit_class_files && TREE_CODE (decl) == ARRAY_REF)
+         && TREE_CODE (decl) != INDIRECT_REF
+         && !(TREE_CODE (decl) == COMPOUND_EXPR
+              && TREE_OPERAND (decl, 1)
+              && (TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF)))
        {
          tree lvalue;
          /* Before screaming, check that we're not in fact trying to
@@ -9505,7 +10005,11 @@ patch_unaryop (node, wfl_op)
          error_found = 1;
        }
       else
-       return fold (value);
+       {
+         value = fold (value);
+         TREE_SIDE_EFFECTS (value) = TREE_SIDE_EFFECTS (op);
+         return value;
+       }
       break;
     }
   
@@ -9517,6 +10021,7 @@ patch_unaryop (node, wfl_op)
      CONVERT_EXPR, {POST,PRE}{INCR,DECR}EMENT_EXPR. */
   TREE_OPERAND (node, 0) = fold (op);
   TREE_TYPE (node) = prom_type;
+  TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op);
   return fold (node);
 }
 
@@ -9571,12 +10076,21 @@ patch_cast (node, wfl_operator)
       if (cast_type == op_type)
        return node;
 
+      /* float and double type are converted to the original type main
+        variant and then to the target type. */
+      if (JFLOAT_TYPE_P (op_type) && TREE_CODE (cast_type) == CHAR_TYPE)
+       op = convert (integer_type_node, op);
+
       /* Try widening/narowwing convertion. Potentially, things need
         to be worked out in gcc so we implement the extreme cases
         correctly. fold_convert() needs to be fixed. */
       return convert (cast_type, op);
     }
 
+  /* It's also valid to cast a boolean into a boolean */
+  if (op_type == boolean_type_node && cast_type == boolean_type_node)
+    return node;
+
   /* null can be casted to references */
   if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
     return build_null_of_type (cast_type);
@@ -9584,7 +10098,7 @@ patch_cast (node, wfl_operator)
   /* 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) 
-      && valid_ref_assignconv_cast_p (cast_type, op_type, 1))
+      && valid_ref_assignconv_cast_p (op_type, cast_type, 1))
     {
       TREE_TYPE (node) = promote_type (cast_type);
       /* Now, the case can be determined correct at compile time if
@@ -9690,13 +10204,22 @@ patch_array_ref (node)
 
   array_type = TYPE_ARRAY_ELEMENT (array_type);
 
-  if (flag_emit_class_files)
+  if (flag_emit_class_files || flag_emit_xref)
     {
       TREE_OPERAND (node, 0) = array;
       TREE_OPERAND (node, 1) = index;
     }
   else
-    node = build_java_arrayaccess (array, array_type, index);
+    {
+      /* The save_expr is for correct evaluation order.  It would be cleaner
+        to use force_evaluation_order (see comment there), but that is
+        difficult when we also have to deal with bounds checking. */
+      if (TREE_SIDE_EFFECTS (index))
+       array = save_expr (array);
+      node = build_java_arrayaccess (array, array_type, index);
+      if (TREE_SIDE_EFFECTS (index))
+       node = build (COMPOUND_EXPR, array_type, array, node);
+    }
   TREE_TYPE (node) = array_type;
   return node;
 }
@@ -9840,7 +10363,7 @@ build_new_array_init (location, values)
 {
   tree constructor = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, values);
   tree to_return = build1 (NEW_ARRAY_INIT, NULL_TREE, constructor);
-  EXPR_WFL_LINECOL (to_return) = EXPR_WFL_LINECOL (constructor) = location;
+  EXPR_WFL_LINECOL (to_return) = location;
   return to_return;
 }
 
@@ -9877,7 +10400,10 @@ patch_new_array_init (type, node)
       if (elt == NULL_TREE || TREE_CODE (elt) != NEW_ARRAY_INIT)
        {
          error_seen |= array_constructor_check_entry (element_type, current);
-         if (! TREE_CONSTANT (TREE_VALUE (current)))
+         elt = TREE_VALUE (current);
+         /* When compiling to native code, STRING_CST is converted to
+            INDIRECT_REF, but still with a TREE_CONSTANT flag. */
+         if (! TREE_CONSTANT (elt) || TREE_CODE (elt) == INDIRECT_REF)
            all_constant = 0;
        }
       else
@@ -9965,7 +10491,7 @@ static tree
 build_this (location)
      int location;
 {
-  tree node = build_wfl_node (this_identifier_node, input_filename, 0, 0);
+  tree node = build_wfl_node (this_identifier_node);
   TREE_SET_CODE (node, THIS_EXPR);
   EXPR_WFL_LINECOL (node) = location;
   return node;
@@ -10003,6 +10529,10 @@ patch_return (node)
   if (return_exp && (mtype == void_type_node || DECL_CONSTRUCTOR_P (meth)))
     error_found = 1;
 
+  /* It's invalid to use a return statement in a static block */
+  if (IS_CLINIT (current_function_decl))
+    error_found = 1;
+
   /* It's invalid to have a no return value within a function that
      isn't declared with the keyword `void' */
   if (!return_exp && (mtype != void_type_node && !DECL_CONSTRUCTOR_P (meth)))
@@ -10010,7 +10540,11 @@ patch_return (node)
 
   if (error_found)
     {
-      if (!DECL_CONSTRUCTOR_P (meth))
+      if (IS_CLINIT (current_function_decl))
+       parse_error_context (wfl_operator,
+                            "`return' inside static initializer.");
+
+      else if (!DECL_CONSTRUCTOR_P (meth))
        {
          char *t = strdup (lang_printable_name (mtype, 0));
          parse_error_context (wfl_operator, 
@@ -10114,30 +10648,35 @@ patch_if_else_statement (node)
 
 /* Action taken when a lableled statement is parsed. a new
    LABELED_BLOCK_EXPR is created. No statement is attached to the
-   label, yet.  */
+   label, yet.  LABEL can be NULL_TREE for artificially-generated blocks. */
 
 static tree
 build_labeled_block (location, label)
      int location;
      tree label;
 {
-  tree label_name = merge_qualified_name (label_id, label);
+  tree label_name ;
   tree label_decl, node;
-
-  /* Issue an error if we try to reuse a label that was previously
-     declared */
-  if (IDENTIFIER_LOCAL_VALUE (label_name))
+  if (label == NULL_TREE || label == continue_identifier_node)
+    label_name = label;
+  else
     {
-      EXPR_WFL_LINECOL (wfl_operator) = location;
-      parse_error_context (wfl_operator, "Declaration of `%s' shadows "
-                            "a previous label declaration",
-                            IDENTIFIER_POINTER (label));
-      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'",
-                          IDENTIFIER_POINTER (label));
-      java_error_count--;
+      label_name = merge_qualified_name (label_id, label);
+      /* Issue an error if we try to reuse a label that was previously
+        declared */
+      if (IDENTIFIER_LOCAL_VALUE (label_name))
+       {
+         EXPR_WFL_LINECOL (wfl_operator) = location;
+         parse_error_context (wfl_operator, "Declaration of `%s' shadows "
+                              "a previous label declaration",
+                              IDENTIFIER_POINTER (label));
+         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'",
+                              IDENTIFIER_POINTER (label));
+         java_error_count--;
+       }
     }
 
   label_decl = create_label_decl (label_name);
@@ -10147,35 +10686,17 @@ build_labeled_block (location, label)
   return node;
 }
 
-/* Generate a label crafting a unique name for it. This is used to
-   implicitely label loops that aren't the body part of labeled
-   statement.  */
-
-static tree
-generate_labeled_block ()
-{
-  return build_labeled_block (0, generate_name ());
-}
-
 /* A labeled statement LBE is attached a statement.  */
 
 static tree
-complete_labeled_statement (lbe, statement)
+finish_labeled_statement (lbe, statement)
      tree lbe;                 /* Labeled block expr */
      tree statement;
 {
   /* In anyways, tie the loop to its statement */
   LABELED_BLOCK_BODY (lbe) = statement;
-
-  /* Ok, if statement is a for loop, we have to attach the labeled
-     statement to the block the for loop belongs to and return the
-     block instead */
-  if (TREE_CODE (statement) == LOOP_EXPR && IS_FOR_LOOP_P (statement))
-    {
-      java_method_add_stmt (current_function_decl, lbe);
-      return exit_block ();
-    }
-
+  pop_labeled_block ();
+  POP_LABELED_BLOCK ();
   return lbe;
 }
 
@@ -10199,7 +10720,7 @@ 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           (continue occurding here branche at the 
+           LABEL_DECL           (a continue occuring here branches at the 
            BODY                         end of this labeled block)
        INCREMENT               (if any)
 
@@ -10227,7 +10748,7 @@ build_loop_body (location, condition, reversed)
   condition = build_debugable_stmt (location, condition);
   TREE_SIDE_EFFECTS (condition) = 1;
 
-  body = generate_labeled_block ();
+  body = build_labeled_block (0, continue_identifier_node);
   first = (reversed ? body : condition);
   second = (reversed ? condition : body);
   return 
@@ -10240,7 +10761,7 @@ build_loop_body (location, condition, reversed)
    loop list.  */
 
 static tree
-complete_loop_body (location, condition, body, reversed)
+finish_loop_body (location, condition, body, reversed)
      int location;
      tree condition, body;
      int reversed;
@@ -10262,16 +10783,16 @@ complete_loop_body (location, condition, body, reversed)
   return to_return;
 }
 
-/* Tailored version of complete_loop_body for FOR loops, when FOR
+/* Tailored version of finish_loop_body for FOR loops, when FOR
    loops feature the condition part */
 
 static tree
-complete_for_loop (location, condition, update, body)
+finish_for_loop (location, condition, update, body)
     int location;
     tree condition, update, body;
 {
   /* Put the condition and the loop body in place */
-  tree loop = complete_loop_body (location, condition, body, 0);
+  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 */
   LOOP_EXPR_BODY_UPDATE_BLOCK (LOOP_EXPR_BODY (loop)) = update;
@@ -10279,28 +10800,40 @@ complete_for_loop (location, condition, update, body)
 }
 
 /* If the loop isn't surrounded by a labeled statement, create one and
-   insert LOOP as it's body.  */
+   insert LOOP as its body.  */
 
 static tree
 patch_loop_statement (loop)
      tree loop;
 {
-  tree loop_label, to_return_as_loop;
-
-  if (LOOP_HAS_LABEL_P (loop))
-    {
-      loop_label = ctxp->current_labeled_block;
-      to_return_as_loop = loop;
-    }
-  else
+  tree loop_label;
+  tree block = ctxp->current_labeled_block;
+  TREE_TYPE (loop) = void_type_node;
+  if (block != NULL_TREE)
     {
-      loop_label = generate_labeled_block ();
-      LABELED_BLOCK_BODY (loop_label) = loop;
-      PUSH_LABELED_BLOCK (loop_label);
-      to_return_as_loop = loop_label;
+      tree block_body = LABELED_BLOCK_BODY (block);
+      if (IS_FOR_LOOP_P (loop))
+       {
+         if (TREE_CODE (block_body) == BLOCK)
+           {
+             block_body = BLOCK_EXPR_BODY (block_body);
+             if (block_body == loop
+                 || (TREE_CODE (block_body) == COMPOUND_EXPR
+                     && TREE_OPERAND (block_body, 1) == loop))
+               return loop;
+           }
+       }
+      else
+       {
+         if (block_body == loop)
+           return loop;
+       }
     }
-  TREE_TYPE (to_return_as_loop) = void_type_node;
-  return to_return_as_loop;
+  loop_label = build_labeled_block (0, NULL_TREE);
+  LABELED_BLOCK_BODY (loop_label) = loop;
+  PUSH_LABELED_BLOCK (loop_label);
+  loop = loop_label;
+  return loop;
 }
 
 /* 14.13, 14.14: break and continue Statements */
@@ -10344,85 +10877,63 @@ patch_bc_statement (node)
      tree node;
 {
   tree bc_label = EXIT_BLOCK_LABELED_BLOCK (node), target_stmt;
-  int is_unlabeled = 0;
+  tree labeled_block = ctxp->current_labeled_block;
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
  
-  /* Not having a target means that the break/continue statement is
-     unlabeled. We try to find a decent label for it */
-  if (!bc_label)
-    {
-      is_unlabeled = 1;
-      /* There should be a loop/switch to branch to */
-      if (ctxp->current_loop)
-       {
-         if (TREE_CODE (ctxp->current_loop) == LOOP_EXPR)
-           {
-             /* At that stage, we're in the loop body, which is
-                encapsulated around a LABELED_BLOCK_EXPR. So searching
-                the current loop label requires us to consider the
-                labeled block before the current one. */
-             if (!LOOP_HAS_LABEL_SKIP_P (ctxp->current_loop))
-               fatal ("unlabeled loop has no installed label -- "
-                      "patch_bc_statement");
-             bc_label = TREE_CHAIN (ctxp->current_labeled_block);
-           }
-         /* For a SWITCH statement, this is the current one */
-         else
-           bc_label = ctxp->current_labeled_block;
-       }
-      /* Not having a loop to break/continue to is an error */
-      else
-       {
-         parse_error_context (wfl_operator, "`%s' must be in loop%s",
-                              (IS_BREAK_STMT_P (node) ? "break" : "continue"),
-                              (IS_BREAK_STMT_P (node) ? " or switch" : ""));
-         return error_mark_node;
-       }
-    }
   /* Having an identifier here means that the target is unknown. */
-  else if (TREE_CODE (bc_label) == IDENTIFIER_NODE)
+  if (bc_label != NULL_TREE && TREE_CODE (bc_label) == IDENTIFIER_NODE)
     {
       parse_error_context (wfl_operator, "No label definition found for `%s'",
                           IDENTIFIER_POINTER (bc_label));
       return error_mark_node;
     }
-
-  /* Find the statement we're targeting. */
-  target_stmt = LABELED_BLOCK_BODY (bc_label);
-
-  /* 14.13 The break Statement */
-  if (IS_BREAK_STMT_P (node))
+  if (! IS_BREAK_STMT_P (node))
     {
-      /* Named break are always fine, as far as they have a target
-         (already verified). Anonymous break need to target
-         while/do/for/switch */
-      if (is_unlabeled &&
-         !(TREE_CODE (target_stmt) == LOOP_EXPR        /* do/while/for */
-           || TREE_CODE (target_stmt) == SWITCH_EXPR)) /* switch FIXME */
+      /* It's a continue statement. */
+      for (;; labeled_block = TREE_CHAIN (labeled_block))
        {
-         parse_error_context (wfl_operator, 
-                              "`break' must be in loop or switch");
-         return error_mark_node;
+         if (labeled_block == NULL_TREE)
+           {
+             if (bc_label == NULL_TREE)
+               parse_error_context (wfl_operator,
+                                    "`continue' must be in loop");
+             else
+               parse_error_context 
+                 (wfl_operator, "continue label `%s' does not name a loop",
+                  IDENTIFIER_POINTER (bc_label));
+             return error_mark_node;
+           }
+         if ((DECL_NAME (LABELED_BLOCK_LABEL (labeled_block))
+              == continue_identifier_node)
+             && (bc_label == NULL_TREE
+                 || TREE_CHAIN (labeled_block) == bc_label))
+           {
+             bc_label = labeled_block;
+             break;
+           }
        }
-      /* If previously unlabeled, install the new found label */
-      if (is_unlabeled)
-       EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
     }
-  /* 14.14 The continue Statement */
-  /* The continue statement must always target a loop */
-  else 
-    {
-      if (TREE_CODE (target_stmt) != LOOP_EXPR) /* do/while/for */
+  else if (!bc_label)
+    { 
+      for (;; labeled_block = TREE_CHAIN (labeled_block))
        {
-         parse_error_context (wfl_operator, "`continue' must be in loop");
-         return error_mark_node;
+         if (labeled_block == NULL_TREE)
+           {
+             parse_error_context (wfl_operator,
+                                    "`break' must be in loop or switch");
+             return error_mark_node;
+           }
+         target_stmt = LABELED_BLOCK_BODY (labeled_block);
+         if (TREE_CODE (target_stmt) == SWITCH_EXPR
+             || TREE_CODE (target_stmt) == LOOP_EXPR)
+           {
+             bc_label = labeled_block;
+             break;
+           }
        }
-      /* Everything looks good. We can fix the `continue' jump to go
-         at the place in the loop were the continue is. The continue
-        is the current labeled block, by construction. */
-      EXIT_BLOCK_LABELED_BLOCK (node) = bc_label = ctxp->current_labeled_block;
     }
 
+  EXIT_BLOCK_LABELED_BLOCK (node) = bc_label;
   CAN_COMPLETE_NORMALLY (bc_label) = 1;
 
   /* Our break/continue don't return values. */
@@ -10515,123 +11026,24 @@ patch_switch_statement (node)
 
 /* 14.18 The try statement */
 
-/* Wrap BLOCK around a LABELED_BLOCK, set DECL to the newly generated
-   exit labeld and issue a jump to FINALLY_LABEL:
-     
-   LABELED_BLOCK
-     BLOCK
-       <orignal_statments>
-       DECL = &LABEL_DECL
-       GOTO_EXPR
-         FINALLY_LABEL
-     LABEL_DECL */
-
 static tree
-build_jump_to_finally (block, decl, finally_label, type)
-     tree block, decl, finally_label, type;
+build_try_statement (location, try_block, catches)
+     int location;
+     tree try_block, catches;
 {
-  tree stmt;
-  tree new_block = build (LABELED_BLOCK_EXPR, type,
-                         create_label_decl (generate_name ()), block);
-
-  stmt = build (MODIFY_EXPR, void_type_node, decl,
-               build_address_of (LABELED_BLOCK_LABEL (new_block)));
-  TREE_SIDE_EFFECTS (stmt) = 1;
-  CAN_COMPLETE_NORMALLY (stmt) = 1;
-  add_stmt_to_block (block, type, stmt);
-  stmt = build (GOTO_EXPR, void_type_node, finally_label);
-  TREE_SIDE_EFFECTS (stmt) = 1;
-  add_stmt_to_block (block, type, stmt);
-  return new_block;
+  tree node = build (TRY_EXPR, NULL_TREE, try_block, catches);
+  EXPR_WFL_LINECOL (node) = location;
+  return node;
 }
 
 static tree
-build_try_statement (location, try_block, catches, finally)
+build_try_finally_statement (location, try_block, finally)
      int location;
-     tree try_block, catches, finally;
-{
-  tree node, rff;
-
-  if (finally && ! flag_emit_class_files)
-    {
-      /* This block defines a scope for the entire try[-catch]-finally
-        sequence. It hold a local variable used to return from the
-        finally using a computed goto. We call it
-        return_from_finally (RFF). */
-      rff = build_decl (VAR_DECL, generate_name (), return_address_type_node);
-
-      /* Modification of the try block. */
-      try_block = build_jump_to_finally (try_block, rff, 
-                                        FINALLY_EXPR_LABEL (finally), 
-                                        NULL_TREE);
-
-      /* To the finally block: add the computed goto */
-      add_stmt_to_block (FINALLY_EXPR_BLOCK (finally), NULL_TREE,
-                        build (GOTO_EXPR, void_type_node, rff));
-
-      /* Modification of each catch blocks, if any */
-      if (catches)
-       {
-         tree catch, catch_decl, catch_block, stmt;
-
-         for (catch = catches; catch; catch = TREE_CHAIN (catch))
-           TREE_OPERAND (catch, 0) = 
-             build_jump_to_finally (TREE_OPERAND (catch, 0), rff,
-                                    FINALLY_EXPR_LABEL (finally),
-                                    NULL_TREE);
-
-         /* Plus, at the end of the list, we add the catch clause that
-            will catch an uncaught exception, call finally and rethrow it:
-              BLOCK
-                void *exception_parameter; (catch_decl)
-                LABELED_BLOCK
-                  BLOCK
-                    exception_parameter = _Jv_exception_info ();
-                    RFF = &LABEL_DECL;
-                    goto finally;
-                LABEL_DECL;
-                CALL_EXPR
-                  Jv_ReThrow
-                  exception_parameter */
-         catch_decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
-         BUILD_ASSIGN_EXCEPTION_INFO (stmt, catch_decl);
-         catch_block = build_expr_block (stmt, NULL_TREE);
-         catch_block = build_jump_to_finally (catch_block, rff, 
-                                              FINALLY_EXPR_LABEL (finally), 
-                                              void_type_node);
-         BUILD_THROW (stmt, catch_decl);
-         catch_block = build_expr_block (catch_block, catch_decl);
-         add_stmt_to_block (catch_block, void_type_node, stmt);
-
-         /* Link the new handler to the existing list as the first
-            entry. It will be the last one to be generated. */
-         catch = build1 (CATCH_EXPR, void_type_node, catch_block);
-         TREE_CHAIN (catch) = catches;
-         catches = catch;
-       }
-    }
-
-  node = build (TRY_EXPR, NULL_TREE, try_block, catches, finally);
-  EXPR_WFL_LINECOL (node) = location;
-  
-  /* If we have a finally, surround this whole thing by a block where
-     the RFF local variable is defined. */
-
-  return (finally && ! flag_emit_class_files ? build_expr_block (node, rff)
-         : node);
-}
-
-/* Get the catch clause block from an element of the catch clause
-   list. If depends on whether a finally clause exists or node (in
-   which case the original catch clause was surrounded by a
-   LABELED_BLOCK_EXPR. */
-
-tree
-java_get_catch_block (node, finally_present_p)
-     tree node;
-     int finally_present_p;
+     tree try_block, finally;
 {
-  return (CATCH_EXPR_GET_EXPR (TREE_OPERAND (node, 0), finally_present_p));
+  tree node = build (TRY_FINALLY_EXPR, NULL_TREE, try_block, finally);
+  EXPR_WFL_LINECOL (node) = location;
+  return node;
 }
 
 static tree
@@ -10642,8 +11054,6 @@ patch_try_statement (node)
   tree try = TREE_OPERAND (node, 0);
   /* Exception handlers are considered in left to right order */
   tree catch = nreverse (TREE_OPERAND (node, 1));
-  tree finally = TREE_OPERAND (node, 2);
-  int finally_p = (finally ? 1 : 0);
   tree current, caught_type_list = NULL_TREE;
 
   /* Check catch clauses, if any. Every time we find an error, we try
@@ -10656,29 +11066,14 @@ patch_try_statement (node)
       tree sub_current, catch_block, catch_clause;
       int unreachable;
 
-      /* Always detect the last catch clause if a finally is
-         present. This is the catch-all handler and it just needs to
-         be walked. */
-      if (!TREE_CHAIN (current) && finally)
-       {
-         TREE_OPERAND (current, 0) = 
-           java_complete_tree (TREE_OPERAND (current, 0));
-         continue;
-       }
-
       /* At this point, the structure of the catch clause is
-         LABELED_BLOCK_EXPR    (if we have a finally)
           CATCH_EXPR           (catch node)
             BLOCK              (with the decl of the parameter)
                COMPOUND_EXPR
                  MODIFY_EXPR   (assignment of the catch parameter)
                 BLOCK          (catch clause block)
-           LABEL_DECL          (where to return after finally (if any))
-
-        Since the structure of the catch clause depends on the
-        presence of a finally, we use a function call to get to the
-        cath clause */
-      catch_clause = java_get_catch_block (current, finally_p);
+       */
+      catch_clause = TREE_OPERAND (current, 0);
       carg_decl = BLOCK_EXPR_DECLS (catch_clause);
       carg_type = TREE_TYPE (TREE_TYPE (carg_decl));
 
@@ -10712,7 +11107,7 @@ patch_try_statement (node)
           sub_current != current; sub_current = TREE_CHAIN (sub_current))
        {
          tree sub_catch_clause, decl;
-         sub_catch_clause = java_get_catch_block (sub_current, finally_p);
+         sub_catch_clause = TREE_OPERAND (sub_current, 0);
          decl = BLOCK_EXPR_DECLS (sub_catch_clause);
 
          if (inherits_from_p (carg_type, TREE_TYPE (TREE_TYPE (decl))))
@@ -10752,24 +11147,12 @@ patch_try_statement (node)
     CAN_COMPLETE_NORMALLY (node) = 1;
   POP_EXCEPTIONS ();
 
-  /* Process finally */
-  if (finally)
-    {
-      current = java_complete_tree (FINALLY_EXPR_BLOCK (finally));
-      FINALLY_EXPR_BLOCK (finally) = current;
-      if (current == error_mark_node)
-       error_found = 1;
-      if (! CAN_COMPLETE_NORMALLY (current))
-       CAN_COMPLETE_NORMALLY (node) = 0;
-    }
-
   /* Verification ends here */
   if (error_found) 
     return error_mark_node;
 
   TREE_OPERAND (node, 0) = try;
   TREE_OPERAND (node, 1) = catch;
-  TREE_OPERAND (node, 2) = finally;
   TREE_TYPE (node) = void_type_node;
   return node;
 }
@@ -10783,7 +11166,7 @@ patch_synchronized_statement (node, wfl_op1)
   tree expr = java_complete_tree (TREE_OPERAND (node, 0));
   tree block = TREE_OPERAND (node, 1);
 
-  tree enter, exit, finally, expr_decl;
+  tree enter, exit, expr_decl, assignment;
 
   if (expr == error_mark_node)
     {
@@ -10801,6 +11184,14 @@ patch_synchronized_statement (node, wfl_op1)
       return error_mark_node;
     }
 
+  if (flag_emit_xref)
+    {
+      TREE_OPERAND (node, 0) = expr;
+      TREE_OPERAND (node, 1) = java_complete_tree (block);
+      CAN_COMPLETE_NORMALLY (node) = 1;
+      return node;
+    }
+
   /* Generate a try-finally for the synchronized statement, except
      that the handler that catches all throw exception calls
      _Jv_MonitorExit and then rethrow the exception.
@@ -10823,13 +11214,13 @@ patch_synchronized_statement (node, wfl_op1)
   BUILD_MONITOR_EXIT (exit, expr_decl);
   CAN_COMPLETE_NORMALLY (enter) = 1;
   CAN_COMPLETE_NORMALLY (exit) = 1;
+  assignment = build (MODIFY_EXPR, NULL_TREE, expr_decl, expr);
+  TREE_SIDE_EFFECTS (assignment) = 1;
   node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
                 build (COMPOUND_EXPR, NULL_TREE,
                        build (WITH_CLEANUP_EXPR, NULL_TREE,
                               build (COMPOUND_EXPR, NULL_TREE,
-                                     build (MODIFY_EXPR, NULL_TREE,
-                                            expr_decl, expr),
-                                     enter),
+                                     assignment, enter),
                               NULL_TREE, exit),
                        block));
   node = build_expr_block (node, expr_decl);
@@ -10874,8 +11265,7 @@ patch_throw_statement (node, wfl_op1)
      throws clause the declaration. */
   SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
   if (!unchecked_ok)
-    tryblock_throws_ok = 
-      check_thrown_exceptions_do (TREE_TYPE (expr));
+    tryblock_throws_ok = check_thrown_exceptions_do (TREE_TYPE (expr));
   if (!(unchecked_ok || tryblock_throws_ok))
     {
       /* If there is a surrounding try block that has no matching
@@ -10889,11 +11279,22 @@ patch_throw_statement (node, wfl_op1)
                             lang_printable_name (type, 0));
       /* If we have no surrounding try statement and the method doesn't have
         any throws, report it now. FIXME */
+
+      /* 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) 
               && !tryblock_throws_ok)
-       parse_error_context (wfl_operator, "Checked exception `%s' isn't "
-                            "thrown from a `try' block", 
-                            lang_printable_name (type, 0));
+       {
+         if (IS_CLINIT (current_function_decl))
+           parse_error_context (wfl_operator, "Checked exception `%s' can't "
+                                "be thrown in initializer",
+                                lang_printable_name (type, 0));
+         else
+           parse_error_context (wfl_operator, "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
@@ -10904,13 +11305,12 @@ patch_throw_statement (node, wfl_op1)
       return error_mark_node;
     }
 
-  /* If a throw statement is contained in a static initializer, then a
-     compile-time check ensures that either its value is always an
-     unchecked exception or its value is always caught by some try
-     statement that contains it. FIXME, static initializer. */
-  
-  if (! flag_emit_class_files)
+  if (! flag_emit_class_files && ! flag_emit_xref)
     BUILD_THROW (node, expr);
+
+  /* If doing xrefs, keep the location where the `throw' was seen. */
+  if (flag_emit_xref)
+    EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
   return node;
 }
 
@@ -11116,7 +11516,7 @@ fold_constant_for_init (node, context)
 
   if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
     return node;
-  if (TREE_TYPE (node) != NULL_TREE)
+  if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL)
     return NULL_TREE;
 
   switch (code)
@@ -11188,7 +11588,7 @@ fold_constant_for_init (node, context)
       val = DECL_INITIAL (node);
       /* Guard against infinite recursion. */
       DECL_INITIAL (node) = NULL_TREE;
-      val = fold_constant_for_init (val, DECL_CONTEXT (node));
+      val = fold_constant_for_init (val, node);
       DECL_INITIAL (node) = val;
       return val;
 
@@ -11204,7 +11604,7 @@ fold_constant_for_init (node, context)
          else if (! QUALIFIED_P (name))
            {
              decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
-             if (! FIELD_STATIC (decl))
+             if (decl == NULL_TREE || ! FIELD_STATIC (decl))
                return NULL_TREE;
              return fold_constant_for_init (decl, decl);
            }