Tue Nov 10 12:34:03 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
authorapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Nov 1998 18:04:25 +0000 (18:04 +0000)
committerapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Nov 1998 18:04:25 +0000 (18:04 +0000)
* class.c (is_compiled_class): Call safe_layout_class for class
  compiled from source.
* conver.h (convert_to_integer, convert_to_real,
  convert_to_pointer): Added prototypes.
* decl.c (init_decl_processing): Non longer push the decls of
  `methodtable', `constants', `Class', `Field', `dispatchTable'
  `jexception' and `Method'.
* expr.c (build_invokeinterface): New function.
(expand_invoke): static variable CLASS_IDENT now in
  build_invokeinterface. Use build_invokeinterface.
(expand_java_field_op): Moved code to inline
  java.lang.PRIMTYPE.TYPE into a function.
(build_primtype_type_ref): New function.
* java-tree.def (INSTANCEOF_EXPR): New tree code.
* java-tree.h (CLASS_METHOD_CHECKED_P, METHOD_DEPRECATED,
  FIELD_DEPRECATED, CLASS_DEPRECATED): New flag macros.
(DECL_CONSTRUCTOR_P): Fixed typo in comment.
(DECL_LOCAL_STATIC_VALUE): New macro.
(build_invokeinterface, build_primtype_type_ref): New function
  prototypes.
(java_parse_abort_on_error): Macro rewritten.
* jcf-parse.c (current_method): Add comment to declaration.
(parse_zip_file_entries, process_zip_dir, void parse_source_file):
  Function prototypes fixed.
(jcf_parse_source): push/pop parser context. save/restore global.
(parse_source_file): Fixed leading comment. Now take a
  IDENTIFIER_NODE as an argument. Doesn't check methods, layout
  classes and pop the parser context anymore.
(yyparse): Push parser context, save globals, parse the source
  file, restore globals and pop the parser context when processing a
  source file.
* jcf.h (VERBOSE_SKELETON): Replaces SOURCE_FRONTEND_DEBUG define.
* lex.c (java_parse_doc_section): New function.
(java_lex): Call java_parse_doc_section when appropriate. Build an
  operator around INSTANCEOF_TK.
* lex.h (java_lineterminator, java_sprint_unicode,
  java_unicode_2_utf8, java_lex_error, java_store_unicode):
  Prototypes rewritten.
(java_parse_escape_sequence, java_letter_or_digit_p,
  java_parse_doc_section, java_parse_end_comment, java_get_unicode,
  java_read_unicode, java_store_unicode, java_read_char,
  java_allocate_new_line, java_unget_unicode, java_sneak_unicode):
  Added function prototypes.
* parse.h (VERBOSE_SKELETON): Replaces SOURCE_FRONTEND_DEBUG
  define.
(JNULLP_TYPE_P, CHECK_METHODS, CHECK_DEPRECATED, REGISTER_IMPORT):
  New macros
(struct parser_ctxt): New fields: deprecated,
  current_parsed_class_un, gclass_list.
(fix_method_argument_names, issue_warning_error_from_context,
  resolve_package, lookup_package_type): New function prototypes.
(resolve_expression_name): Fixed function prototype.
(find_applicable_accessible_methods_list): Fixed indentation, added
extra argument in prototype.
(check_final_assignment, build_null_of_type, check_deprecation,
  check_method_redefinition, reset_method_name,
  java_check_regular_methods, java_check_abstract_methods,
  maybe_build_primttype_type_ref): New function prototype.
* parse.y (conver.h): Include.
(INSTANCEOF_TK): Tagged <operator>.
(single_type_import_declaration): Use REGISTER_IMPORT macro.
(relational_expression:): Build binop for instanceof.
(java_push_parser_context): Remember ctxp->gclass_list across
  contexts.
(java_pop_parser_context): Simply return if no context
  exists. Remember gclass_list across contexts.
(issue_warning_error_from_context): New function.
(parse_error_context): Don't setup ctxp->elc here. Call
  issue_warning_error_from_context instead.
(parse_warning_context): Likewise.
(maybe_create_class_interface_decl): Removed DECL_ARTIFICIAL
  setup. Link new class/interface to ctxp->gclass_list.
(add_superinterfaces): Register interface as incomplete if not
  loaded.
(create_class): Remember class unqualified name in
  ctxp->current_parsed_class_un. Check class deprecation.
(register_fields): Check field deprecation. Remember static final
  field value in DECL_LOCAL_STATIC_VALUE. Changed comment in part
  processing INIT.
(method_header): New local variable ORIG_ARG. Use unqualified
  current class name for check on constructor errors. Promote return
  type if of record type. Argument list fix moved in
  fix_method_argument_names, called here. Check method deprecation.
(fix_method_argument_names): New function.
(method_declarator): Promote record typed arguments.
(safe_layout_class): Check class methods before layout.
(java_complete_class): Compute field layout when patched.
(do_resolve_class): Try to load class after having it renamed
  after the package name.
(get_printable_method_name): Use DECL_CONTEXT.
(reset_method_name): New function.
(check_method_redefinition): Use reset_method_name.
(java_check_regular_methods): New local variable
  SAVED_FOUND_WFL. Temporarily reinstall overriding/hiding method
  names for error report. Check for compile-time error when method
  found has default (package) access.
(java_check_abstract_methods): Now takes an interface DECL node as
  an argument. Also reinstall real name on unchecked
  overriding/hiding methods for error report.
(java_check_methods): Fixed leading comment. Get classes to verify
  from ctxp->gclass_list. Use CHECK_METHODS macro and set
  CLASS_METHOD_CHECKED_P on class verification.
(lookup_java_method2): Get real method name if necessary.
(find_in_imports): Don't check package class access here.
(resolve_package, lookup_package_type): New functions.
(java_layout_classes): Fixed leading comment. Take classes to be
  laid out from ctxp->gclass_list.
(java_complete_expand_methods): Don't expand native and abstract
  methods.
(java_expand_classes): New function.
(resolve_expression_name): Use additional argument ORIG.  Retrieve
  values of static final field of primitive types.
(resolve_field_access): Handles static final field of promotive
  type.
(resolve_qualified_expression_name): Handle STRING_CST as
  primaries and package name resolution. Check deprecation on found
  decls. Set where_found and type_found on non static field resolved
  during qualification. Layout non primitive field decl types.
(check_deprecation): New function.
(maybe_access_field): Simplified.
(patch_method_invocation_stmt): Local variable CLASS_TYPE
  removed. Reverse method's argument when primary is a type. Don't
  use CLASS_TYPE to report problems, use IDENTIFIER_WFL
  instead. Include abstract class in the list of class searchable
  for constructors. Use DECL_CONTEXT of found method for access
  checks. Check method deprecation.
(patch_invoke): Pay extra care to NEW_CLASS_EXPR type call when
  converting arguments. Handle INVOKE_INTERFACE.
(lookup_method_invoke): Search constructor using existing
  infrastructure (don't rely on lookup_java_constructor anymore).
(find_applicable_accessible_methods_list): Extra argument flag
  LC. Now include constructor in the search.
(qualify_ambiguous_name): Conditional expression are primaries.
(not_initialized_as_it_should_p): static final are always
  initialized.
(java_complete_tree): Pass extra NULL argument to
  resolve_expression_name. Stricter test to carry on patching
  assignments. New case for INSTANCEOF_EXPR.
(complete_function_arguments): Inline PRIMTYPE.TYPE read access.
(check_final_assignment, maybe_build_primttype_type_ref): New
  functions.
(patch_assignment): Detect resolved static finals and carry normal
  assignment error check on them. Inline PRIMTYPE.TYPE read access.
(try_builtin_assignconv): Access constant 0 on all primitive
  types.
(valid_builtin_assignconv_identity_widening_p): Accept identical
  types. Accept all promoted type on int type.
(valid_ref_assignconv_cast_p): Accept a null pointer to be
  assigned to a reference.
(valid_method_invocation_conversion_p): Accept to check null
  pointers.
(build_binop): Merge declaration and initialization of local
  variable BINOP.
(patch_binop): New case for INSTANCEOF_EXPR. NE_EXPR to accept all
  numeric types. Improved validity test for qualify operators on
  references.
(patch_unaryop): Broadened rejection test for PREDECREMENT_EXPR
  and PREINCREMENT_EXPR. Also detect resolved static finals of a
  primitive type and issue the appropriate error message.
(resolve_type_during_patch): Mark class loaded when resolved.
(patch_cast): Allow null to be cased to reference types.
(build_null_of_type): New function.
(patch_array_ref): Handle array on references correctly.
(patch_return): Removed unused local variable MODIFY. Force
  boolean to be returned as integers. Allows null to be returned by
  a function returning a reference.
* typeck.c (convert_to_integer, convert_to_real,
  convert_to_pointer): Prototypes moved to convert.h
(lookup_argument_method): Use method real name, if necessary.
This improves method checking, gets rid of a cross file type
dependency bug and does a more robust job at laying out classes when
necessary. It unifies the regular methods and constructors lookup. It
implements the `instanceof' operator and interface method
invocations. It also fixes random bugs.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23599 138bc75d-0d04-0410-961f-82ee72b054a4

18 files changed:
gcc/java/ChangeLog
gcc/java/class.c
gcc/java/convert.h
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.def
gcc/java/java-tree.h
gcc/java/jcf-parse.c
gcc/java/jcf-write.c
gcc/java/jcf.h
gcc/java/lang-options.h
gcc/java/lex.c
gcc/java/lex.h
gcc/java/mangle.c
gcc/java/parse.c
gcc/java/parse.h
gcc/java/parse.y
gcc/java/typeck.c

index c19f23f..c225fdf 100644 (file)
@@ -1,3 +1,175 @@
+Tue Nov 10 12:34:03 1998  Alexandre Petit-Bianco  <apbianco@cygnus.com>
+
+       * class.c (is_compiled_class): Call safe_layout_class for class
+       compiled from source.
+       * conver.h (convert_to_integer, convert_to_real,
+       convert_to_pointer): Added prototypes.
+       * decl.c (init_decl_processing): Non longer push the decls of
+       `methodtable', `constants', `Class', `Field', `dispatchTable'
+       `jexception' and `Method'.
+       * expr.c (build_invokeinterface): New function.
+       (expand_invoke): static variable CLASS_IDENT now in
+       build_invokeinterface. Use build_invokeinterface.
+       (expand_java_field_op): Moved code to inline
+       java.lang.PRIMTYPE.TYPE into a function.
+       (build_primtype_type_ref): New function.
+       * java-tree.def (INSTANCEOF_EXPR): New tree code.
+       * java-tree.h (CLASS_METHOD_CHECKED_P, METHOD_DEPRECATED,
+       FIELD_DEPRECATED, CLASS_DEPRECATED): New flag macros.
+       (DECL_CONSTRUCTOR_P): Fixed typo in comment.
+       (DECL_LOCAL_STATIC_VALUE): New macro.
+       (build_invokeinterface, build_primtype_type_ref): New function
+       prototypes.
+       (java_parse_abort_on_error): Macro rewritten.
+       * jcf-parse.c (current_method): Add comment to declaration.
+       (parse_zip_file_entries, process_zip_dir, void parse_source_file):
+       Function prototypes fixed.
+       (jcf_parse_source): push/pop parser context. save/restore global.
+       (parse_source_file): Fixed leading comment. Now take a
+       IDENTIFIER_NODE as an argument. Doesn't check methods, layout
+       classes and pop the parser context anymore.
+       (yyparse): Push parser context, save globals, parse the source
+       file, restore globals and pop the parser context when processing a
+       source file.
+       * jcf.h (VERBOSE_SKELETON): Replaces SOURCE_FRONTEND_DEBUG define.
+       * lex.c (java_parse_doc_section): New function.
+       (java_lex): Call java_parse_doc_section when appropriate. Build an
+       operator around INSTANCEOF_TK.
+       * lex.h (java_lineterminator, java_sprint_unicode,
+       java_unicode_2_utf8, java_lex_error, java_store_unicode):
+       Prototypes rewritten.
+       (java_parse_escape_sequence, java_letter_or_digit_p,
+       java_parse_doc_section, java_parse_end_comment, java_get_unicode,
+       java_read_unicode, java_store_unicode, java_read_char,
+       java_allocate_new_line, java_unget_unicode, java_sneak_unicode):
+       Added function prototypes.
+       * parse.h (VERBOSE_SKELETON): Replaces SOURCE_FRONTEND_DEBUG
+       define.
+       (JNULLP_TYPE_P, CHECK_METHODS, CHECK_DEPRECATED, REGISTER_IMPORT):
+       New macros
+       (struct parser_ctxt): New fields: deprecated,
+       current_parsed_class_un, gclass_list.
+       (fix_method_argument_names, issue_warning_error_from_context,
+       resolve_package, lookup_package_type): New function prototypes.
+       (resolve_expression_name): Fixed function prototype.
+       (find_applicable_accessible_methods_list): Fixed indentation, added
+       extra argument in prototype.
+       (check_final_assignment, build_null_of_type, check_deprecation,
+       check_method_redefinition, reset_method_name,
+       java_check_regular_methods, java_check_abstract_methods,
+       maybe_build_primttype_type_ref): New function prototype.
+       * parse.y (conver.h): Include.
+       (INSTANCEOF_TK): Tagged <operator>.
+       (single_type_import_declaration): Use REGISTER_IMPORT macro.
+       (relational_expression:): Build binop for instanceof.
+       (java_push_parser_context): Remember ctxp->gclass_list across
+       contexts.
+       (java_pop_parser_context): Simply return if no context
+       exists. Remember gclass_list across contexts.
+       (issue_warning_error_from_context): New function.
+       (parse_error_context): Don't setup ctxp->elc here. Call
+       issue_warning_error_from_context instead.
+       (parse_warning_context): Likewise.
+       (maybe_create_class_interface_decl): Removed DECL_ARTIFICIAL
+       setup. Link new class/interface to ctxp->gclass_list.
+       (add_superinterfaces): Register interface as incomplete if not
+       loaded.
+       (create_class): Remember class unqualified name in
+       ctxp->current_parsed_class_un. Check class deprecation.
+       (register_fields): Check field deprecation. Remember static final
+       field value in DECL_LOCAL_STATIC_VALUE. Changed comment in part
+       processing INIT.
+       (method_header): New local variable ORIG_ARG. Use unqualified
+       current class name for check on constructor errors. Promote return
+       type if of record type. Argument list fix moved in
+       fix_method_argument_names, called here. Check method deprecation.
+       (fix_method_argument_names): New function.
+       (method_declarator): Promote record typed arguments.
+       (safe_layout_class): Check class methods before layout.
+       (java_complete_class): Compute field layout when patched.
+       (do_resolve_class): Try to load class after having it renamed
+       after the package name.
+       (get_printable_method_name): Use DECL_CONTEXT.
+       (reset_method_name): New function.
+       (check_method_redefinition): Use reset_method_name.
+       (java_check_regular_methods): New local variable
+       SAVED_FOUND_WFL. Temporarily reinstall overriding/hiding method
+       names for error report. Check for compile-time error when method
+       found has default (package) access.
+       (java_check_abstract_methods): Now takes an interface DECL node as
+       an argument. Also reinstall real name on unchecked
+       overriding/hiding methods for error report.
+       (java_check_methods): Fixed leading comment. Get classes to verify
+       from ctxp->gclass_list. Use CHECK_METHODS macro and set
+       CLASS_METHOD_CHECKED_P on class verification.
+       (lookup_java_method2): Get real method name if necessary.
+       (find_in_imports): Don't check package class access here.
+       (resolve_package, lookup_package_type): New functions.
+       (java_layout_classes): Fixed leading comment. Take classes to be
+       laid out from ctxp->gclass_list.
+       (java_complete_expand_methods): Don't expand native and abstract
+       methods.
+       (java_expand_classes): New function.
+       (resolve_expression_name): Use additional argument ORIG.  Retrieve
+       values of static final field of primitive types.
+       (resolve_field_access): Handles static final field of promotive
+       type.
+       (resolve_qualified_expression_name): Handle STRING_CST as
+       primaries and package name resolution. Check deprecation on found
+       decls. Set where_found and type_found on non static field resolved
+       during qualification. Layout non primitive field decl types.
+       (check_deprecation): New function.
+       (maybe_access_field): Simplified.
+       (patch_method_invocation_stmt): Local variable CLASS_TYPE
+       removed. Reverse method's argument when primary is a type. Don't
+       use CLASS_TYPE to report problems, use IDENTIFIER_WFL
+       instead. Include abstract class in the list of class searchable
+       for constructors. Use DECL_CONTEXT of found method for access
+       checks. Check method deprecation.
+       (patch_invoke): Pay extra care to NEW_CLASS_EXPR type call when
+       converting arguments. Handle INVOKE_INTERFACE.
+       (lookup_method_invoke): Search constructor using existing
+       infrastructure (don't rely on lookup_java_constructor anymore).
+       (find_applicable_accessible_methods_list): Extra argument flag
+       LC. Now include constructor in the search.
+       (qualify_ambiguous_name): Conditional expression are primaries.
+       (not_initialized_as_it_should_p): static final are always
+       initialized.
+       (java_complete_tree): Pass extra NULL argument to
+       resolve_expression_name. Stricter test to carry on patching
+       assignments. New case for INSTANCEOF_EXPR.
+       (complete_function_arguments): Inline PRIMTYPE.TYPE read access.
+       (check_final_assignment, maybe_build_primttype_type_ref): New
+       functions.
+       (patch_assignment): Detect resolved static finals and carry normal
+       assignment error check on them. Inline PRIMTYPE.TYPE read access.
+       (try_builtin_assignconv): Access constant 0 on all primitive
+       types.
+       (valid_builtin_assignconv_identity_widening_p): Accept identical
+       types. Accept all promoted type on int type.
+       (valid_ref_assignconv_cast_p): Accept a null pointer to be
+       assigned to a reference.
+       (valid_method_invocation_conversion_p): Accept to check null
+       pointers.
+       (build_binop): Merge declaration and initialization of local
+       variable BINOP.
+       (patch_binop): New case for INSTANCEOF_EXPR. NE_EXPR to accept all
+       numeric types. Improved validity test for qualify operators on
+       references.
+       (patch_unaryop): Broadened rejection test for PREDECREMENT_EXPR
+       and PREINCREMENT_EXPR. Also detect resolved static finals of a
+       primitive type and issue the appropriate error message.
+       (resolve_type_during_patch): Mark class loaded when resolved.
+       (patch_cast): Allow null to be cased to reference types.
+       (build_null_of_type): New function.
+       (patch_array_ref): Handle array on references correctly.
+       (patch_return): Removed unused local variable MODIFY. Force
+       boolean to be returned as integers. Allows null to be returned by
+       a function returning a reference.
+       * typeck.c (convert_to_integer, convert_to_real,
+       convert_to_pointer): Prototypes moved to convert.h
+       (lookup_argument_method): Use method real name, if necessary.
+
 1998-10-30  Tom Tromey  <tromey@cygnus.com>
 
        * class.c (build_class_ref): Changed name of primitive classes to
index 4a2d8fa..47e9f5c 100644 (file)
@@ -1153,7 +1153,12 @@ is_compiled_class (class)
   if (flag_assume_compiled)
     {
       if (!CLASS_LOADED_P (class))
-       load_class (class, 1);
+       {
+         if (CLASS_FROM_SOURCE_P (class))
+           safe_layout_class (class);
+         else
+           load_class (class, 1);
+       }
       return 1;
     }
 
index 1e1373e..a627bc2 100644 (file)
@@ -1,3 +1,4 @@
+
 /* Definition of conversion functions.
    Copyright (C) 1993 Free Software Foundation, Inc.
 
@@ -22,3 +23,6 @@ Boston, MA 02111-1307, USA.  */
 
 extern tree convert_to_boolean PROTO ((tree, tree));
 extern tree convert_to_char    PROTO ((tree, tree));
+extern tree convert_to_integer PROTO ((tree type, tree expr));
+extern tree convert_to_real PROTO ((tree type, tree expr));
+extern tree convert_to_pointer PROTO ((tree type, tree expr));
index 6c44d15..0831a37 100644 (file)
@@ -527,8 +527,7 @@ init_decl_processing ()
 
   methodtable_type = make_node (RECORD_TYPE);
   layout_type (methodtable_type);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("methodtable"),
-                       methodtable_type));
+  build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type);
   methodtable_ptr_type = build_pointer_type (methodtable_type);
 
   TYPE_identifier_node = get_identifier ("TYPE");
@@ -554,8 +553,7 @@ init_decl_processing ()
   PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node);
   PUSH_FIELD (constants_type_node, field, "data", ptr_type_node);
   FINISH_RECORD (constants_type_node);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("constants"),
-                       constants_type_node));
+  build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node);
 
   access_flags_type_node = unsigned_short_type_node;
 
@@ -606,7 +604,7 @@ init_decl_processing ()
     FIELD_PRIVATE (t) = 1;
   push_super_field (class_type_node, object_type_node);
   FINISH_RECORD (class_type_node);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node));
+  build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node);
 
   field_info_union_node = make_node (UNION_TYPE);
   PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node);
@@ -623,7 +621,7 @@ init_decl_processing ()
   PUSH_FIELD (field_type_node, field, "info", field_info_union_node);
   FINISH_RECORD (field_type_node);
   CLASS_LOADED_P (field_type_node) = 1;
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node));
+  build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node);
 
   one_elt_array_domain_type = build_index_type (integer_one_node);
   nativecode_ptr_array_type_node
@@ -632,7 +630,7 @@ init_decl_processing ()
   PUSH_FIELD (dtable_type, field, "class", class_ptr_type);
   PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node);
   FINISH_RECORD (dtable_type);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type));
+  build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type);
 
 #define jint_type int_type_node
 #define jint_ptr_type ptr_type_node
@@ -643,7 +641,7 @@ init_decl_processing ()
   PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node);
   PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type);
   FINISH_RECORD (jexception_type);
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node));
+  build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node);
   jexception_ptr_type = build_pointer_type (jexception_type);
 
   lineNumberEntry_type = make_node (RECORD_TYPE);
@@ -665,7 +663,7 @@ init_decl_processing ()
   PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node);
   FINISH_RECORD (method_type_node);
   CLASS_LOADED_P (method_type_node) = 1;
-  pushdecl (build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node));
+  build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node);
 
   t = tree_cons (NULL_TREE, class_ptr_type,
                 build_tree_list (NULL_TREE, int_type_node));
index 5759b6b..37c5122 100644 (file)
@@ -1431,6 +1431,32 @@ build_invokevirtual (dtable, method)
   return func;
 }
 
+tree
+build_invokeinterface (dtable, method_name, method_signature)
+     tree dtable, method_name, method_signature;
+{
+  static tree class_ident = NULL_TREE;
+  tree lookup_arg;
+
+  /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will
+     ensure that the selected method exists, is public and not
+     abstract nor static.  */
+           
+  if (class_ident == NULL_TREE)
+    class_ident = get_identifier ("class");
+  
+  dtable = build1 (INDIRECT_REF, dtable_type, dtable);
+  dtable = build (COMPONENT_REF, class_ptr_type, dtable,
+                 lookup_field (&dtable_type, class_ident));
+  lookup_arg = build_tree_list (NULL_TREE, build_utf8_ref (method_signature));
+  lookup_arg = tree_cons (NULL_TREE, dtable,
+                         tree_cons (NULL_TREE, build_utf8_ref (method_name),
+                                    lookup_arg));
+  return build (CALL_EXPR, ptr_type_node, 
+               build_address_of (soft_lookupinterfacemethod_node),
+               lookup_arg, NULL_TREE);
+}
+  
 /* Expand one of the invoke_* opcodes.
    OCPODE is the specific opcode.
    METHOD_REF_INDEX is an index into the constant pool.
@@ -1449,8 +1475,6 @@ expand_invoke (opcode, method_ref_index, nargs)
   char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));
   tree call, func, method, arg_list, method_type;
 
-  static tree class_ident = NULL_TREE;
-
   if (! CLASS_LOADED_P (self_type))
     {
       load_class (self_type, 1);
@@ -1522,30 +1546,7 @@ expand_invoke (opcode, method_ref_index, nargs)
       if (opcode == OPCODE_invokevirtual)
        func = build_invokevirtual (dtable, method);
       else
-       {
-         /* We expand invokeinterface here.
-            _Jv_LookupInterfaceMethod() will ensure that the selected
-            method exists, is public and not abstract nor static.  */
-           
-         tree lookup_arg;
-
-         if (class_ident == NULL_TREE)
-           class_ident = get_identifier ("class");
-
-         dtable = build1 (INDIRECT_REF, dtable_type, dtable);
-         dtable = build (COMPONENT_REF, class_ptr_type, dtable,
-                         lookup_field (&dtable_type, class_ident));
-         lookup_arg = build_tree_list (NULL_TREE,
-                                       build_utf8_ref (method_signature));
-         lookup_arg = tree_cons (NULL_TREE, dtable,
-                                 tree_cons (NULL_TREE,
-                                            build_utf8_ref (method_name),
-                                            lookup_arg));
-         func = build (CALL_EXPR,
-                       ptr_type_node,
-                       build_address_of (soft_lookupinterfacemethod_node),
-                       lookup_arg, NULL_TREE);
-       }
+       func = build_invokeinterface (dtable, method_name, method_signature);
     }
   func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
   call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
@@ -1615,29 +1616,10 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
       && field_type == class_ptr_type
       && strncmp (self_name, "java.lang.", 10) == 0)
     {
-      char *class_name = self_name+10;
-      tree typ;
-      if (strcmp(class_name, "Byte") == 0)
-       typ = byte_type_node;
-      else if (strcmp(class_name, "Short") == 0)
-       typ = short_type_node;
-      else if (strcmp(class_name, "Integer") == 0)
-       typ = int_type_node;
-      else if (strcmp(class_name, "Long") == 0)
-       typ = long_type_node;
-      else if (strcmp(class_name, "Float") == 0)
-       typ = float_type_node;
-      else if (strcmp(class_name, "Boolean") == 0)
-       typ = boolean_type_node;
-      else if (strcmp(class_name, "Char") == 0)
-       typ = char_type_node;
-      else if (strcmp(class_name, "Void") == 0)
-       typ = void_type_node;
-      else
-       typ = NULL_TREE;
-      if (typ != NULL_TREE)
+      tree typ = build_primtype_type_ref (self_name);
+      if (typ)
        {
-         push_value (build_class_ref (typ));
+         push_value (typ);
          return;
        }
     }
@@ -1672,6 +1654,36 @@ expand_java_field_op (is_static, is_putting, field_ref_index)
     push_value (field_ref);
 }
 
+tree
+build_primtype_type_ref (self_name)
+    char *self_name;
+{
+  char *class_name = self_name+10;
+  tree typ;
+  if (strncmp(class_name, "Byte", 4) == 0)
+    typ = byte_type_node;
+  else if (strncmp(class_name, "Short", 5) == 0)
+    typ = short_type_node;
+  else if (strncmp(class_name, "Integer", 7) == 0)
+    typ = int_type_node;
+  else if (strncmp(class_name, "Long", 4) == 0)
+    typ = long_type_node;
+  else if (strncmp(class_name, "Float", 5) == 0)
+    typ = float_type_node;
+  else if (strncmp(class_name, "Boolean", 7) == 0)
+    typ = boolean_type_node;
+  else if (strncmp(class_name, "Char", 4) == 0)
+    typ = char_type_node;
+  else if (strncmp(class_name, "Void", 4) == 0)
+    typ = void_type_node;
+  else
+    typ = NULL_TREE;
+  if (typ != NULL_TREE)
+    return build_class_ref (typ);
+  else
+    return NULL_TREE;
+}
+
 void
 load_type_state (label)
      tree label;
index 5bd63c4..b367066 100644 (file)
@@ -70,3 +70,10 @@ DEFTREECODE (THROW_EXPR, "throw", '1', 1)
    Operand 1 is the then-value
    Operand 2 is the else-value.  */
 DEFTREECODE (CONDITIONAL_EXPR, "?:", 'e', 3)
+
+/* instanceof operator.
+   Operand 0 is the expression that is getting tested
+   Operand 1 is the class used for the test.  */
+DEFTREECODE (INSTANCEOF_EXPR, "instanceof", 'e', 2)
+
+
index 711e441..d80c6c9 100644 (file)
@@ -56,6 +56,7 @@ struct JCF;
       IS_CRAFTED_STRING_BUFFER_P (in CALL_EXPR)
 
    Usage of TYPE_LANG_FLAG_?:
+   0: CLASS_METHOD_CHECKED_P (in RECORD_TYPE)
    1: TYPE_ARRAY_P (in RECORD_TYPE).
    2: CLASS_LOADED_P (in RECORD_TYPE).
    3: CLASS_FROM_SOURCE_P (in RECORD_TYPE).
@@ -64,6 +65,9 @@ struct JCF;
    6: CLASS_HAS_FINIT_P (in RECORD_TYPE)
 
    Usage of DECL_LANG_FLAG_?:
+   0: METHOD_DEPRECATED (in FUNCTION_DECL).
+      FIELD_DEPRECATED (in FIELD_DECL).
+      CLASS_DEPRECATED (in TYPE_DECL).
    1: METHOD_PUBLIC (in FUNCTION_DECL).
       FIELD_PUBLIC (in FIELD_DECL).
       CLASS_PUBLIC (in TYPE_DECL).
@@ -85,7 +89,7 @@ struct JCF;
       LABEL_CHANGED (in LABEL_DECL)
       CLASS_SUPER (in TYPE_DECL, ACC_SUPER flag)
       INITIALIZED_P (in FIELD_DECL, VAR_DECL, PARM_DECL)
-   7: DECL_CONSTRUCTOR_P (in FUNCTION_DECL)
+   7: DECL_CONSTRUCTOR_P (in FUNCTION_DECL).
 */
 
 /* True if the class whose TYPE_BINFO this is has a superclass.
@@ -396,6 +400,9 @@ struct lang_identifier
    slot_number in decl_map. */
 #define DECL_LOCAL_SLOT_CHAIN(NODE) \
   (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->slot_chain)
+/* For a static field seen from the parser, it holds its associated
+   value, the one returned when the field is looked up. */
+#define DECL_LOCAL_STATIC_VALUE(NODE) DECL_LOCAL_SLOT_CHAIN (NODE)
 
 /* DECL_LANG_SPECIFIC for FUNCTION_DECLs. */
 struct lang_decl
@@ -501,6 +508,7 @@ extern tree lookup_name PROTO ((tree));
 extern tree build_known_method_ref PROTO ((tree, tree, tree, tree, tree));
 extern tree build_class_init PROTO ((tree, tree));
 extern tree build_invokevirtual PROTO ((tree, tree));
+extern tree build_invokeinterface PROTO ((tree, tree, tree));
 extern tree invoke_build_dtable PROTO ((int, tree));
 extern tree build_field_ref PROTO ((tree, tree, tree));
 extern void pushdecl_force_head PROTO ((tree));
@@ -533,6 +541,7 @@ extern int alloc_name_constant PROTO ((int, tree));
 extern void emit_register_classes PROTO (());
 extern void lang_init_source PROTO ((int));
 extern void write_classfile PROTO ((tree));
+extern tree build_primtype_type_ref PROTO ((char *));
 
 /* Access flags etc for a method (a FUNCTION_DECL): */
 
@@ -570,6 +579,13 @@ extern void write_classfile PROTO ((tree));
 #define CLASS_ABSTRACT(DECL) DECL_LANG_FLAG_5 (DECL)
 #define CLASS_SUPER(DECL) DECL_LANG_FLAG_6 (DECL)
 
+/* @deprecated marker flag on methods, fields and classes */
+
+#define METHOD_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+#define FIELD_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+#define CLASS_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+#define DECL_DEPRECATED(DECL) DECL_LANG_FLAG_0 (DECL)
+
 /* The number of virtual methods in this class's dispatch table.
  Does not include initial two dummy entries (one points to the
  Class object, and the other is for G++ -fvtable-thunks compatibility). */
@@ -657,6 +673,9 @@ extern tree *type_map;
 /* FIXME this use of TREE_TYPE conflicts with something or other. */
 #define TYPE_ARRAY_ELEMENT(ATYPE) TREE_TYPE(ATYPE)
 
+/* True if methods in class TYPE have been checked.  */
+#define CLASS_METHOD_CHECKED_P(TYPE) TYPE_LANG_FLAG_0 (TYPE)
+
 /* True if class TYPE has been loaded. */
 #define CLASS_LOADED_P(TYPE) TYPE_LANG_FLAG_2 (TYPE)
 
@@ -795,13 +814,12 @@ extern tree *type_map;
 
 /* Make the current function where this macro is invoked report error
    messages and and return, if any */
-#define java_parse_abort_on_error()            \
-  {                                            \
-     extern int java_error_count;              \
-     if (java_error_count)                     \
-       {                                       \
-         java_report_errors ();                        \
-        java_pop_parser_context (0);           \
-        return;                                \
-       }                                       \
+#define java_parse_abort_on_error()                                    \
+  {                                                                    \
+     extern int java_error_count;                                      \
+     if (java_error_count)                                             \
+       {                                                               \
+         java_report_errors ();                                                \
+        return;                                                        \
+       }                                                               \
    }
index 0761362..df4881d 100644 (file)
@@ -64,15 +64,14 @@ tree main_class = NULL_TREE;
 /* The FIELD_DECL for the current field. */
 static tree current_field = NULL_TREE;
 
+/* The METHOD_DECL for the current method.  */
 static tree current_method = NULL_TREE;
 
+/* Declarations of some functions used here.  */
 static tree give_name_to_class PROTO ((JCF *jcf, int index));
-
-void parse_zip_file_entries (void);
-void process_zip_dir();
-
-/* Source file compilation declarations */
-static void parse_source_file ();
+void parse_zip_file_entries PROTO (());
+void process_zip_dir PROTO (());
+static void parse_source_file PROTO ((tree));
 
 /* Handle "SourceFile" attribute. */
 
@@ -506,14 +505,17 @@ int
 jcf_parse_source (jcf)
      JCF *jcf;
 {
-  tree filename = get_identifier (input_filename);
-  java_parser_context_save_global ();
+  tree file;
 
+  java_parser_context_save_global ();
+  java_push_parser_context ();
   input_filename = current_jcf->filename;
+  file = get_identifier (input_filename);
   if (!(finput = fopen (input_filename, "r")))
     fatal ("input file `%s' just disappeared - jcf_parse_source",
           input_filename);
-  parse_source_file (IS_A_COMMAND_LINE_FILENAME_P (filename));
+  parse_source_file (file);
+  java_pop_parser_context (IS_A_COMMAND_LINE_FILENAME_P (file));
   java_parser_context_restore_global ();
 }
 
@@ -658,22 +660,16 @@ parse_class_file ()
   lineno = save_lineno;
 }
 
-/* Parse a source file, as pointed by the current JCF. If PARSE_ONLY
-   is non zero, we're not parsing a file found on the command line and
-   we skip things related to code generation. */
+/* Parse a source file, as pointed by the current value of INPUT_FILENAME. */
 
 static void
-parse_source_file (parse_only)
-     int parse_only;
+parse_source_file (file)
+     tree file;
 {
-  int remember_for_generation;
-  tree filename = get_identifier (input_filename);
-
   /* Mark the file as parsed */
-  HAS_BEEN_ALREADY_PARSED_P (filename) = 1;
+  HAS_BEEN_ALREADY_PARSED_P (file) = 1;
 
   lang_init_source (1);                    /* Error msgs have no method prototypes */
-  java_push_parser_context ();
   java_init_lex ();                /* Initialize the parser */
   java_parse_abort_on_error ();
   java_parse ();                   /* Parse and build partial tree nodes. */
@@ -682,17 +678,6 @@ parse_source_file (parse_only)
   java_parse_abort_on_error ();
   java_check_circular_reference (); /* Check on circular references */
   java_parse_abort_on_error ();
-  java_check_methods ();            /* Check the methods */
-  java_parse_abort_on_error ();
-  java_layout_classes ();
-  java_parse_abort_on_error ();
-
-  /* If only parsing, make sure that the currently parsed file isn't
-     also present in the argument list. If it's the case, remember
-     that we should generate it. */
-  remember_for_generation = !parse_only 
-    || IS_A_COMMAND_LINE_FILENAME_P (filename);
-  java_pop_parser_context (remember_for_generation);
 }
 
 int
@@ -775,7 +760,11 @@ yyparse ()
          parse_class_file ();
          break;
        case JCF_SOURCE:
-         parse_source_file (0);        /* Parse and generate */
+         java_push_parser_context ();
+         java_parser_context_save_global ();
+         parse_source_file (name);
+         java_parser_context_restore_global ();
+         java_pop_parser_context (1);
          break;
        }
     }
index bf0c16d..5d092c6 100644 (file)
@@ -706,7 +706,6 @@ emit_iinc (var, value, state)
 static void
 emit_load_or_store (var, opcode, state)
      tree var;
-     int opcode;
      struct jcf_partial *state;
 {
   tree type = TREE_TYPE (var);
index 3f98814..1b8aff2 100644 (file)
@@ -248,7 +248,7 @@ extern int jcf_unexpected_eof PROTO ((JCF*, int));
 /* Debug macros, for the front end */
 
 extern int quiet_flag;
-#ifdef SOURCE_FRONTEND_DEBUG
+#ifdef VERBOSE_SKELETON
 #undef SOURCE_FRONTEND_DEBUG
 #define SOURCE_FRONTEND_DEBUG(X)                               \
   {if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
index 0f0f74b..4610193 100644 (file)
@@ -22,11 +22,14 @@ Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 
-DEFINE_LANG_NAME ("Java")
-     
 /* This is the contribution to the `lang_options' array in gcc.c for
    java.  */
 
+/* CYGNUS LOCAL - the format of this file has been changed to
+   allow cc1 to implement --help.  nickc/--help */
+
+DEFINE_LANG_NAME ("Java")
+     
   { "-fbounds-check", "" },
   { "-fno-bounds-check", "Disable automatic array bounds checking" },
   { "-fassume-compiled", "Make is_compiled_class return 1"},
index 504c841..0a632f1 100644 (file)
@@ -368,6 +368,62 @@ java_parse_end_comment ()
     }
 }
 
+/* Parse the documentation section. Keywords must be at the beginning
+   of a documentation comment line (ignoring white space and any `*'
+   character). Parsed keyword(s): @DEPRECATED.  */
+
+static int
+java_parse_doc_section (c)
+     unicode_t c;
+{
+  int valid_tag = 0, seen_star;
+
+  while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
+    {
+      switch (c)
+       {
+       case '*':
+         seen_star = 1;
+         break;
+       case '\n': /* ULT */
+         valid_tag = 1;
+         break;
+       default:
+         seen_star = 0;
+       }
+      c = java_get_unicode();
+    }
+  
+  if (c == UEOF)
+    java_lex_error ("Comment not terminated at end of input", 0);
+  
+  if (seen_star && (c == '/'))
+    return 1;                  /* Goto step1 in caller */
+
+  /* We're parsing @deprecated */
+  if (valid_tag && (c == '@'))
+    {
+      char tag [10];
+      int  tag_index = 0;
+
+      while (tag_index < 10 && c != UEOF && c != ' ' && c != '\n')
+       {
+         c = java_get_unicode ();
+         tag [tag_index++] = c;
+       }
+      
+      if (c == UEOF)
+       java_lex_error ("Comment not terminated at end of input", 0);
+      
+      java_unget_unicode ();
+      tag [tag_index] = '\0';
+
+      if (!strcmp (tag, "deprecated"))
+       ctxp->deprecated = 1;
+    }
+  return 0;
+}
+
 /* This function to be used only by JAVA_ID_CHAR_P (), otherwise it
    will return a wrong result.  */
 static int
@@ -494,62 +550,8 @@ java_lex (java_lval)
            {
              if ((c = java_get_unicode ()) == '/')
                goto step1;     /* Empy documentation comment  */
-
-             else
-               /* Parsing the documentation section. We're looking
-                for the @depracated pseudo keyword.  the @deprecated
-                tag must be at the beginning of a doc comment line
-                (ignoring white space and any * character)  */
-
-               { 
-                 int valid_tag = 0, seen_star;
-
-                 while (JAVA_WHITE_SPACE_P (c) || (c == '*') || c == '\n')
-                   {
-                     switch (c)
-                       {
-                       case '*':
-                         seen_star = 1;
-                         break;
-                       case '\n': /* ULT */
-                         valid_tag = 1;
-                         break;
-                       default:
-                         seen_star = 0;
-                       }
-                     c = java_get_unicode();
-                   }
-                 
-                 if (c == UEOF)
-                   java_lex_error 
-                     ("Comment not terminated at end of input", 0);
-
-                 if (seen_star && (c == '/'))
-                   goto step1; /* End of documentation */
-
-                 if (valid_tag && (c == '@'))
-                   {
-                     char deprecated [10];
-                     int  deprecated_index = 0;
-
-                     for (deprecated_index = 0, c = java_get_unicode (); 
-                          deprecated_index < 10 && c != UEOF;
-                          c = java_get_unicode ())
-                       deprecated [deprecated_index++] = c;
-
-                     if (c == UEOF)
-                       java_lex_error 
-                         ("Comment not terminated at end of input", 0);
-                     
-                     java_unget_unicode ();
-                     deprecated [deprecated_index] = '\0';
-                     if (!strcmp (deprecated, "deprecated"))
-                       {
-                         /* Set global flag to be checked by class. FIXME  */
-                         warning ("deprecated implementation found");
-                       }
-                   }
-               }
+             else if (java_parse_doc_section (c))
+               goto step1;
            }
          else
            java_unget_unicode ();
@@ -1206,6 +1208,7 @@ java_lex (java_lval)
            case TRY_TK:
            case CATCH_TK:
            case THROW_TK:
+           case INSTANCEOF_TK:
              BUILD_OPERATOR (kw->token);
 
            default:
index b8dc5c2..621cfa6 100644 (file)
@@ -35,13 +35,6 @@ extern int   lineno;
 /* A Unicode character, as read from the input file  */
 typedef unsigned short unicode_t;
 
-/* Function declaration  */
-static int java_lineterminator ();
-static char *java_sprint_unicode ();
-static void java_unicode_2_utf8 ();
-static void java_lex_error ();
-static void java_store_unicode ();
-
 /* Debug macro to print-out what we match  */
 #ifdef JAVA_LEX_DEBUG
 #ifdef JAVA_LEX_DEBUG_CHAR
@@ -511,4 +504,23 @@ static tree build_wfl_node ();
 #define JAVA_READ_BUFFER 256
 #define UEOF (unicode_t)0xffff
 
+/* Function declaration  */
+static int java_lineterminator PROTO ((unicode_t));
+static char *java_sprint_unicode PROTO ((struct java_line *, int));
+static void java_unicode_2_utf8 PROTO ((unicode_t));
+static void java_lex_error PROTO ((char *, int));
+static int java_is_eol PROTO ((FILE *, int));
+static void java_store_unicode PROTO ((struct java_line *, unicode_t, int));
+static unicode_t java_parse_escape_sequence PROTO (());
+static int java_letter_or_digit_p PROTO ((unicode_t));
+static int java_parse_doc_section PROTO ((unicode_t));
+static void java_parse_end_comment PROTO (());
+static unicode_t java_get_unicode PROTO (());
+static unicode_t java_read_unicode PROTO ((int, int *));
+static void java_store_unicode PROTO ((struct java_line *, unicode_t, int));
+static unicode_t java_read_char PROTO (());
+static void java_allocate_new_line PROTO (());
+static void java_unget_unicode PROTO (());
+static unicode_t java_sneak_unicode PROTO (());
+
 #endif
index dff9ddf..08f587a 100644 (file)
@@ -70,7 +70,6 @@ void
 emit_unicode_mangled_name (obstack, name, len)
      struct obstack *obstack;
      char *name;
-     int len;
 {
   unsigned char *ptr;
   unsigned char *limit = (unsigned char *)name + len;
index 2775f3c..8646523 100644 (file)
 #include "lex.h"
 #include "parse.h"
 #include "zipfile.h"
+#include "convert.h"
 
 /* Number of error found so far. */
 int java_error_count; 
@@ -188,7 +189,7 @@ static tree wfl_append = NULL_TREE;
 /* The "toString" identifier used for String `+' operator. */
 static tree wfl_to_string = NULL_TREE;
 
-#line 116 "./parse.y"
+#line 117 "./parse.y"
 typedef union {
   tree node;
   int sub_token;
@@ -492,56 +493,56 @@ static const short yyrhs[] = {   123,
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   270,   276,   278,   279,   280,   281,   282,   286,   288,   291,
-   293,   294,   297,   299,   302,   306,   310,   314,   320,   322,
-   324,   326,   331,   333,   336,   340,   345,   350,   352,   353,
-   354,   355,   356,   357,   358,   361,   366,   372,   374,   377,
-   380,   382,   386,   388,   391,   421,   423,   427,   440,   442,
-   446,   453,   454,   456,   466,   471,   486,   490,   493,   496,
-   499,   501,   503,   505,   509,   511,   513,   515,   519,   521,
-   523,   530,   536,   541,   545,   548,   552,   554,   557,   559,
-   560,   561,   565,   567,   568,   570,   575,   578,   588,   591,
-   593,   597,   600,   607,   613,   621,   623,   625,   627,   629,
-   633,   635,   640,   647,   648,   652,   655,   657,   659,   661,
-   663,   665,   667,   669,   676,   679,   681,   686,   688,   692,
-   697,   702,   706,   711,   713,   715,   722,   724,   726,   730,
-   733,   735,   739,   741,   742,   747,   752,   758,   766,   773,
-   776,   779,   783,   786,   790,   799,   801,   803,   808,   815,
-   823,   825,   829,   837,   848,   852,   855,   858,   861,   864,
-   867,   870,   873,   875,   879,   885,   890,   892,   896,   899,
-   903,   905,   908,   910,   911,   913,   917,   921,   927,   932,
-   937,   941,   945,   951,   953,   954,   959,   962,   966,   971,
-   979,   981,   984,   986,   988,   992,   996,   999,  1003,  1005,
-  1006,  1007,  1008,  1009,  1019,  1021,  1022,  1023,  1024,  1027,
-  1029,  1030,  1031,  1032,  1033,  1034,  1035,  1036,  1037,  1038,
-  1041,  1046,  1057,  1064,  1068,  1079,  1089,  1095,  1101,  1107,
-  1109,  1115,  1117,  1123,  1125,  1127,  1129,  1131,  1135,  1137,
-  1138,  1139,  1140,  1141,  1142,  1145,  1148,  1150,  1152,  1156,
-  1161,  1166,  1174,  1180,  1182,  1184,  1188,  1191,  1193,  1195,
-  1204,  1206,  1213,  1218,  1227,  1229,  1236,  1242,  1247,  1249,
-  1251,  1255,  1263,  1266,  1268,  1270,  1274,  1279,  1288,  1293,
-  1296,  1303,  1305,  1307,  1311,  1314,  1323,  1330,  1332,  1336,
-  1349,  1351,  1357,  1363,  1367,  1369,  1373,  1376,  1378,  1382,
-  1385,  1387,  1389,  1393,  1396,  1398,  1400,  1404,  1407,  1409,
-  1411,  1415,  1421,  1423,  1427,  1434,  1436,  1438,  1440,  1444,
-  1452,  1455,  1457,  1459,  1463,  1465,  1472,  1480,  1497,  1499,
-  1501,  1505,  1511,  1516,  1518,  1521,  1523,  1525,  1527,  1528,
-  1529,  1530,  1534,  1536,  1538,  1543,  1545,  1547,  1549,  1551,
-  1555,  1558,  1563,  1565,  1570,  1571,  1572,  1573,  1574,  1576,
-  1578,  1580,  1582,  1584,  1588,  1590,  1593,  1599,  1604,  1608,
-  1611,  1613,  1615,  1619,  1621,  1623,  1625,  1629,  1632,  1636,
-  1642,  1644,  1652,  1655,  1657,  1661,  1664,  1672,  1676,  1679,
-  1681,  1692,  1703,  1708,  1717,  1719,  1723,  1726,  1728,  1733,
-  1738,  1743,  1750,  1752,  1753,  1754,  1757,  1762,  1767,  1769,
-  1770,  1772,  1774,  1775,  1777,  1781,  1784,  1788,  1791,  1795,
-  1797,  1799,  1801,  1802,  1804,  1808,  1816,  1818,  1820,  1832,
-  1834,  1840,  1842,  1844,  1848,  1850,  1855,  1860,  1865,  1867,
-  1869,  1873,  1875,  1880,  1885,  1887,  1891,  1893,  1898,  1903,
-  1908,  1910,  1912,  1916,  1918,  1923,  1928,  1933,  1938,  1939,
-  1941,  1943,  1945,  1947,  1951,  1953,  1958,  1963,  1965,  1969,
-  1971,  1976,  1980,  1982,  1987,  1991,  1993,  1998,  2002,  2004,
-  2009,  2013,  2015,  2020,  2024,  2026,  2031,  2037,  2039,  2043,
-  2045,  2048,  2051,  2059,  2061,  2062,  2065,  2067,  2070,  2074
+   271,   277,   279,   280,   281,   282,   283,   287,   289,   292,
+   294,   295,   298,   300,   303,   307,   311,   315,   321,   323,
+   325,   327,   332,   334,   337,   341,   346,   351,   353,   354,
+   355,   356,   357,   358,   359,   362,   367,   373,   375,   378,
+   381,   383,   387,   389,   392,   419,   421,   425,   438,   440,
+   444,   451,   452,   454,   464,   469,   484,   488,   491,   494,
+   497,   499,   501,   503,   507,   509,   511,   513,   517,   519,
+   521,   528,   534,   539,   543,   546,   550,   552,   555,   557,
+   558,   559,   563,   565,   566,   568,   573,   576,   586,   589,
+   591,   595,   598,   605,   611,   619,   621,   623,   625,   627,
+   631,   633,   638,   645,   646,   650,   653,   655,   657,   659,
+   661,   663,   665,   667,   674,   677,   679,   684,   686,   690,
+   695,   700,   704,   709,   711,   713,   720,   722,   724,   728,
+   731,   733,   737,   739,   740,   745,   750,   756,   764,   771,
+   774,   777,   781,   784,   788,   797,   799,   801,   806,   813,
+   821,   823,   827,   835,   846,   850,   853,   856,   859,   862,
+   865,   868,   871,   873,   877,   883,   888,   890,   894,   897,
+   901,   903,   906,   908,   909,   911,   915,   919,   925,   930,
+   935,   939,   943,   949,   951,   952,   957,   960,   964,   969,
+   977,   979,   982,   984,   986,   990,   994,   997,  1001,  1003,
+  1004,  1005,  1006,  1007,  1017,  1019,  1020,  1021,  1022,  1025,
+  1027,  1028,  1029,  1030,  1031,  1032,  1033,  1034,  1035,  1036,
+  1039,  1044,  1055,  1062,  1066,  1077,  1087,  1093,  1099,  1105,
+  1107,  1113,  1115,  1121,  1123,  1125,  1127,  1129,  1133,  1135,
+  1136,  1137,  1138,  1139,  1140,  1143,  1146,  1148,  1150,  1154,
+  1159,  1164,  1172,  1178,  1180,  1182,  1186,  1189,  1191,  1193,
+  1202,  1204,  1211,  1216,  1225,  1227,  1234,  1240,  1245,  1247,
+  1249,  1253,  1261,  1264,  1266,  1268,  1272,  1277,  1286,  1291,
+  1294,  1301,  1303,  1305,  1309,  1312,  1321,  1328,  1330,  1334,
+  1347,  1349,  1355,  1361,  1365,  1367,  1371,  1374,  1376,  1380,
+  1383,  1385,  1387,  1391,  1394,  1396,  1398,  1402,  1405,  1407,
+  1409,  1413,  1419,  1421,  1425,  1432,  1434,  1436,  1438,  1442,
+  1450,  1453,  1455,  1457,  1461,  1463,  1470,  1478,  1495,  1497,
+  1499,  1503,  1509,  1514,  1516,  1519,  1521,  1523,  1525,  1526,
+  1527,  1528,  1532,  1534,  1536,  1541,  1543,  1545,  1547,  1549,
+  1553,  1556,  1561,  1563,  1568,  1569,  1570,  1571,  1572,  1574,
+  1576,  1578,  1580,  1582,  1586,  1588,  1591,  1597,  1602,  1606,
+  1609,  1611,  1613,  1617,  1619,  1621,  1623,  1627,  1630,  1634,
+  1640,  1642,  1650,  1653,  1655,  1659,  1662,  1670,  1674,  1677,
+  1679,  1690,  1701,  1706,  1715,  1717,  1721,  1724,  1726,  1731,
+  1736,  1741,  1748,  1750,  1751,  1752,  1755,  1760,  1765,  1767,
+  1768,  1770,  1772,  1773,  1775,  1779,  1782,  1786,  1789,  1793,
+  1795,  1797,  1799,  1800,  1802,  1806,  1814,  1816,  1818,  1830,
+  1832,  1838,  1840,  1842,  1846,  1848,  1853,  1858,  1863,  1865,
+  1867,  1871,  1873,  1878,  1883,  1885,  1889,  1891,  1896,  1901,
+  1906,  1908,  1910,  1914,  1916,  1921,  1926,  1931,  1936,  1938,
+  1940,  1942,  1944,  1946,  1950,  1952,  1957,  1962,  1964,  1968,
+  1970,  1975,  1979,  1981,  1986,  1990,  1992,  1997,  2001,  2003,
+  2008,  2012,  2014,  2019,  2023,  2025,  2030,  2036,  2038,  2042,
+  2044,  2047,  2050,  2058,  2060,  2061,  2064,  2066,  2069,  2073
 };
 #endif
 
@@ -2531,66 +2532,66 @@ yyreduce:
   switch (yyn) {
 
 case 1:
-#line 272 "./parse.y"
+#line 273 "./parse.y"
 {;
     break;}
 case 18:
-#line 316 "./parse.y"
+#line 317 "./parse.y"
 { 
                  yyval.node = build_java_array_type (yyvsp[-2].node, -1);
                  CLASS_LOADED_P (yyval.node) = 1;
                ;
     break;}
 case 19:
-#line 321 "./parse.y"
+#line 322 "./parse.y"
 { yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
     break;}
 case 20:
-#line 323 "./parse.y"
+#line 324 "./parse.y"
 { yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
     break;}
 case 21:
-#line 325 "./parse.y"
+#line 326 "./parse.y"
 {RULE ("']' expected"); RECOVER;;
     break;}
 case 22:
-#line 327 "./parse.y"
+#line 328 "./parse.y"
 {RULE ("']' expected"); RECOVER;;
     break;}
 case 26:
-#line 342 "./parse.y"
+#line 343 "./parse.y"
 { yyval.node = make_qualified_name (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
     break;}
 case 28:
-#line 351 "./parse.y"
+#line 352 "./parse.y"
 {yyval.node = NULL;;
     break;}
 case 36:
-#line 363 "./parse.y"
+#line 364 "./parse.y"
 {
                  yyval.node = NULL;
                ;
     break;}
 case 37:
-#line 367 "./parse.y"
+#line 368 "./parse.y"
 {
                  yyval.node = NULL;
                ;
     break;}
 case 40:
-#line 379 "./parse.y"
+#line 380 "./parse.y"
 { ctxp->package = EXPR_WFL_NODE (yyvsp[-1].node); ;
     break;}
 case 41:
-#line 381 "./parse.y"
+#line 382 "./parse.y"
 {yyerror ("Missing name"); RECOVER;;
     break;}
 case 42:
-#line 383 "./parse.y"
+#line 384 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 45:
-#line 393 "./parse.y"
+#line 394 "./parse.y"
 {
                  tree name = EXPR_WFL_NODE (yyvsp[-1].node), node, last_name;
                  int   i = IDENTIFIER_LENGTH (name)-1;
@@ -2610,26 +2611,23 @@ case 45:
                          (yyvsp[-1].node, "Ambiguous class: `%s' and `%s'",
                           IDENTIFIER_POINTER (name), 
                           IDENTIFIER_POINTER (err));
+                     else
+                       REGISTER_IMPORT (yyvsp[-1].node, last_name)
                    }
                  else
-                   {
-                     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name) = 1;
-                     node = build_tree_list (yyvsp[-1].node, last_name);
-                     TREE_CHAIN (node) = ctxp->import_list;
-                     ctxp->import_list = node;
-                   }
+                   REGISTER_IMPORT (yyvsp[-1].node, last_name);
                ;
     break;}
 case 46:
-#line 422 "./parse.y"
+#line 420 "./parse.y"
 {yyerror ("Missing name"); RECOVER;;
     break;}
 case 47:
-#line 424 "./parse.y"
+#line 422 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 48:
-#line 429 "./parse.y"
+#line 427 "./parse.y"
 {
                  tree name = EXPR_WFL_NODE (yyvsp[-3].node);
                  tree node = build_tree_list (yyvsp[-3].node, NULL_TREE);
@@ -2643,15 +2641,15 @@ case 48:
                ;
     break;}
 case 49:
-#line 441 "./parse.y"
+#line 439 "./parse.y"
 {yyerror ("'*' expected"); RECOVER;;
     break;}
 case 50:
-#line 443 "./parse.y"
+#line 441 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 51:
-#line 448 "./parse.y"
+#line 446 "./parse.y"
 {
                  maybe_generate_clinit ();
                  maybe_generate_finit ();
@@ -2659,24 +2657,24 @@ case 51:
                ;
     break;}
 case 53:
-#line 455 "./parse.y"
+#line 453 "./parse.y"
 { yyval.node = NULL; ;
     break;}
 case 54:
-#line 457 "./parse.y"
+#line 455 "./parse.y"
 {
                  YYERROR_NOW;
                  yyerror ("Class or interface declaration expected");
                ;
     break;}
 case 55:
-#line 468 "./parse.y"
+#line 466 "./parse.y"
 {
                  yyval.value = (1 << yyvsp[0].value);
                ;
     break;}
 case 56:
-#line 472 "./parse.y"
+#line 470 "./parse.y"
 {
                  int acc = (1 << yyvsp[0].value);
                  if (yyval.value & acc)
@@ -2690,116 +2688,116 @@ case 56:
                ;
     break;}
 case 57:
-#line 488 "./parse.y"
+#line 486 "./parse.y"
 { create_class (yyvsp[-4].value, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 58:
-#line 490 "./parse.y"
+#line 488 "./parse.y"
 { 
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 59:
-#line 494 "./parse.y"
+#line 492 "./parse.y"
 { create_class (0, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 60:
-#line 496 "./parse.y"
+#line 494 "./parse.y"
 {      
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 61:
-#line 500 "./parse.y"
+#line 498 "./parse.y"
 {yyerror ("Missing class name"); RECOVER;;
     break;}
 case 62:
-#line 502 "./parse.y"
+#line 500 "./parse.y"
 {yyerror ("Missing class name"); RECOVER;;
     break;}
 case 63:
-#line 504 "./parse.y"
+#line 502 "./parse.y"
 {if (!ctxp->class_err) yyerror ("'{' expected"); DRECOVER(class1);;
     break;}
 case 64:
-#line 506 "./parse.y"
+#line 504 "./parse.y"
 {if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;;
     break;}
 case 65:
-#line 510 "./parse.y"
+#line 508 "./parse.y"
 { yyval.node = NULL; ;
     break;}
 case 66:
-#line 512 "./parse.y"
+#line 510 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 67:
-#line 514 "./parse.y"
+#line 512 "./parse.y"
 {yyerror ("'{' expected"); ctxp->class_err=1;;
     break;}
 case 68:
-#line 516 "./parse.y"
+#line 514 "./parse.y"
 {yyerror ("Missing super class name"); ctxp->class_err=1;;
     break;}
 case 69:
-#line 520 "./parse.y"
+#line 518 "./parse.y"
 { yyval.node = NULL_TREE; ;
     break;}
 case 70:
-#line 522 "./parse.y"
+#line 520 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 71:
-#line 524 "./parse.y"
+#line 522 "./parse.y"
 {
                  ctxp->class_err=1;
                  yyerror ("Missing interface name"); 
                ;
     break;}
 case 72:
-#line 532 "./parse.y"
+#line 530 "./parse.y"
 { 
                  ctxp->interface_number = 1;
                  yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE);
                ;
     break;}
 case 73:
-#line 537 "./parse.y"
+#line 535 "./parse.y"
 { 
                  ctxp->interface_number++;
                  yyval.node = chainon (yyvsp[-2].node, build_tree_list (yyvsp[0].node, NULL_TREE));
                ;
     break;}
 case 74:
-#line 542 "./parse.y"
+#line 540 "./parse.y"
 {yyerror ("Missing interface name"); RECOVER;;
     break;}
 case 75:
-#line 547 "./parse.y"
+#line 545 "./parse.y"
 { yyval.node = ctxp->current_parsed_class; ;
     break;}
 case 76:
-#line 549 "./parse.y"
+#line 547 "./parse.y"
 { yyval.node = ctxp->current_parsed_class; ;
     break;}
 case 82:
-#line 562 "./parse.y"
+#line 560 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("instance initializer"); ;
     break;}
 case 85:
-#line 569 "./parse.y"
+#line 567 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner classe declaration"); ;
     break;}
 case 86:
-#line 571 "./parse.y"
+#line 569 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner interface declaration"); ;
     break;}
 case 87:
-#line 577 "./parse.y"
+#line 575 "./parse.y"
 { register_fields (0, yyvsp[-2].node, yyvsp[-1].node); ;
     break;}
 case 88:
-#line 579 "./parse.y"
+#line 577 "./parse.y"
 {
                  check_modifiers 
                    ("Illegal modifier `%s' for field declaration",
@@ -2809,19 +2807,19 @@ case 88:
                ;
     break;}
 case 90:
-#line 592 "./parse.y"
+#line 590 "./parse.y"
 { yyval.node = chainon (yyvsp[-2].node, yyvsp[0].node); ;
     break;}
 case 91:
-#line 594 "./parse.y"
+#line 592 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 92:
-#line 599 "./parse.y"
+#line 597 "./parse.y"
 { yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE); ;
     break;}
 case 93:
-#line 601 "./parse.y"
+#line 599 "./parse.y"
 { 
                  if (java_error_count)
                    yyvsp[0].node = NULL_TREE;
@@ -2830,7 +2828,7 @@ case 93:
                ;
     break;}
 case 94:
-#line 608 "./parse.y"
+#line 606 "./parse.y"
 {
                  yyerror ("Missing variable initializer");
                  yyval.node = build_tree_list (yyvsp[-2].node, NULL_TREE);
@@ -2838,7 +2836,7 @@ case 94:
                ;
     break;}
 case 95:
-#line 614 "./parse.y"
+#line 612 "./parse.y"
 {
                  yyerror ("';' expected");
                  yyval.node = build_tree_list (yyvsp[-3].node, NULL_TREE);
@@ -2846,234 +2844,234 @@ case 95:
                ;
     break;}
 case 97:
-#line 624 "./parse.y"
+#line 622 "./parse.y"
 { yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
     break;}
 case 98:
-#line 626 "./parse.y"
+#line 624 "./parse.y"
 {yyerror ("Invalid declaration"); DRECOVER(vdi);;
     break;}
 case 99:
-#line 628 "./parse.y"
+#line 626 "./parse.y"
 {yyerror ("']' expected"); DRECOVER(vdi);;
     break;}
 case 100:
-#line 630 "./parse.y"
+#line 628 "./parse.y"
 {yyerror ("Unbalanced ']'"); DRECOVER(vdi);;
     break;}
 case 102:
-#line 636 "./parse.y"
+#line 634 "./parse.y"
 { yyval.node = NULL; ;
     break;}
 case 103:
-#line 642 "./parse.y"
+#line 640 "./parse.y"
 {
                  current_function_decl = yyvsp[0].node;
                  source_start_java_method (current_function_decl);
                ;
     break;}
 case 104:
-#line 647 "./parse.y"
+#line 645 "./parse.y"
 { complete_method_declaration (yyvsp[0].node); ;
     break;}
 case 105:
-#line 649 "./parse.y"
+#line 647 "./parse.y"
 {YYNOT_TWICE yyerror ("'{' expected"); RECOVER;;
     break;}
 case 106:
-#line 654 "./parse.y"
+#line 652 "./parse.y"
 { yyval.node = method_header (0, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 107:
-#line 656 "./parse.y"
+#line 654 "./parse.y"
 { yyval.node = method_header (0, void_type_node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 108:
-#line 658 "./parse.y"
+#line 656 "./parse.y"
 { yyval.node = method_header (yyvsp[-3].value, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 109:
-#line 660 "./parse.y"
+#line 658 "./parse.y"
 { yyval.node = method_header (yyvsp[-3].value, void_type_node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 110:
-#line 662 "./parse.y"
+#line 660 "./parse.y"
 {RECOVER;;
     break;}
 case 111:
-#line 664 "./parse.y"
+#line 662 "./parse.y"
 {RECOVER;;
     break;}
 case 112:
-#line 666 "./parse.y"
+#line 664 "./parse.y"
 {yyerror ("Identifier expected"); RECOVER;;
     break;}
 case 113:
-#line 668 "./parse.y"
+#line 666 "./parse.y"
 {yyerror ("Identifier expected"); RECOVER;;
     break;}
 case 114:
-#line 670 "./parse.y"
+#line 668 "./parse.y"
 {
                  yyerror ("Invalid method declaration, return type required");
                  RECOVER;
                ;
     break;}
 case 115:
-#line 678 "./parse.y"
+#line 676 "./parse.y"
 { yyval.node = method_declarator (yyvsp[-2].node, NULL_TREE); ;
     break;}
 case 116:
-#line 680 "./parse.y"
+#line 678 "./parse.y"
 { yyval.node = method_declarator (yyvsp[-3].node, yyvsp[-1].node); ;
     break;}
 case 117:
-#line 682 "./parse.y"
+#line 680 "./parse.y"
 {
                  /* Issue a warning here: obsolete declaration. FIXME */
                  yyval.node = NULL;    /* FIXME */
                ;
     break;}
 case 118:
-#line 687 "./parse.y"
+#line 685 "./parse.y"
 {yyerror ("')' expected"); DRECOVER(method_declarator);;
     break;}
 case 119:
-#line 689 "./parse.y"
+#line 687 "./parse.y"
 {yyerror ("']' expected"); RECOVER;;
     break;}
 case 120:
-#line 694 "./parse.y"
+#line 692 "./parse.y"
 {
                  ctxp->formal_parameter_number = 1;
                ;
     break;}
 case 121:
-#line 698 "./parse.y"
+#line 696 "./parse.y"
 {
                  ctxp->formal_parameter_number += 1;
                  yyval.node = chainon (yyvsp[-2].node, yyvsp[0].node);
                ;
     break;}
 case 122:
-#line 703 "./parse.y"
+#line 701 "./parse.y"
 {yyerror ("Missing formal parameter term"); RECOVER;;
     break;}
 case 123:
-#line 708 "./parse.y"
+#line 706 "./parse.y"
 {
                  yyval.node = build_tree_list (yyvsp[0].node, yyvsp[-1].node);
                ;
     break;}
 case 124:
-#line 712 "./parse.y"
+#line 710 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("final local"); ;
     break;}
 case 125:
-#line 714 "./parse.y"
+#line 712 "./parse.y"
 {yyerror ("Missing identifier"); RECOVER;;
     break;}
 case 126:
-#line 716 "./parse.y"
+#line 714 "./parse.y"
 {
                  SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[-2].value));
                  yyerror ("Missing identifier"); RECOVER;
                ;
     break;}
 case 127:
-#line 723 "./parse.y"
+#line 721 "./parse.y"
 { yyval.node = NULL_TREE; ;
     break;}
 case 128:
-#line 725 "./parse.y"
+#line 723 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 129:
-#line 727 "./parse.y"
+#line 725 "./parse.y"
 {yyerror ("Missing class type term"); RECOVER;;
     break;}
 case 130:
-#line 732 "./parse.y"
+#line 730 "./parse.y"
 { yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ;
     break;}
 case 131:
-#line 734 "./parse.y"
+#line 732 "./parse.y"
 { yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node); ;
     break;}
 case 132:
-#line 736 "./parse.y"
+#line 734 "./parse.y"
 {yyerror ("Missing class type term"); RECOVER;;
     break;}
 case 135:
-#line 743 "./parse.y"
+#line 741 "./parse.y"
 { yyval.node = NULL_TREE; ;
     break;}
 case 136:
-#line 749 "./parse.y"
+#line 747 "./parse.y"
 {
                  RULE ("STATIC_INITIALIZER");
                ;
     break;}
 case 137:
-#line 753 "./parse.y"
+#line 751 "./parse.y"
 {
                  RULE ("STATIC_INITIALIZER");
                ;
     break;}
 case 138:
-#line 760 "./parse.y"
+#line 758 "./parse.y"
 {
                  SOURCE_FRONTEND_DEBUG (("Modifiers: %d", yyvsp[0].value));
                ;
     break;}
 case 139:
-#line 768 "./parse.y"
+#line 766 "./parse.y"
 {
                  current_function_decl = yyvsp[0].node;
                  source_start_java_method (current_function_decl);
                ;
     break;}
 case 140:
-#line 773 "./parse.y"
+#line 771 "./parse.y"
 { complete_method_declaration (yyvsp[0].node); ;
     break;}
 case 141:
-#line 778 "./parse.y"
+#line 776 "./parse.y"
 { yyval.node = method_header (0, NULL_TREE, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 142:
-#line 780 "./parse.y"
+#line 778 "./parse.y"
 { yyval.node = method_header (yyvsp[-2].value, NULL_TREE, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 143:
-#line 785 "./parse.y"
+#line 783 "./parse.y"
 { yyval.node = method_declarator (yyvsp[-2].node, NULL_TREE); ;
     break;}
 case 144:
-#line 787 "./parse.y"
+#line 785 "./parse.y"
 { yyval.node = method_declarator (yyvsp[-3].node, yyvsp[-1].node); ;
     break;}
 case 145:
-#line 795 "./parse.y"
+#line 793 "./parse.y"
 { 
                  BLOCK_EXPR_BODY (yyvsp[0].node) = size_zero_node;
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 146:
-#line 800 "./parse.y"
+#line 798 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 147:
-#line 802 "./parse.y"
+#line 800 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 148:
-#line 804 "./parse.y"
+#line 802 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 149:
-#line 810 "./parse.y"
+#line 808 "./parse.y"
 { 
                  yyval.node = build_method_invocation (yyvsp[-3].node, NULL_TREE); 
                  yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-3].node), yyval.node);
@@ -3081,7 +3079,7 @@ case 149:
                ;
     break;}
 case 150:
-#line 816 "./parse.y"
+#line 814 "./parse.y"
 { 
                  yyval.node = build_method_invocation (yyvsp[-4].node, yyvsp[-2].node); 
                  yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-4].node), yyval.node);
@@ -3089,15 +3087,15 @@ case 150:
                ;
     break;}
 case 151:
-#line 824 "./parse.y"
+#line 822 "./parse.y"
 {yyval.node = parse_jdk1_1_error ("explicit constructor invocation"); ;
     break;}
 case 152:
-#line 826 "./parse.y"
+#line 824 "./parse.y"
 {yyval.node = parse_jdk1_1_error ("explicit constructor invocation"); ;
     break;}
 case 153:
-#line 831 "./parse.y"
+#line 829 "./parse.y"
 {
                  tree wfl = build_wfl_node (this_identifier_node, 
                                             input_filename, 0, 0);
@@ -3106,7 +3104,7 @@ case 153:
                ;
     break;}
 case 154:
-#line 838 "./parse.y"
+#line 836 "./parse.y"
 {
                  tree wfl = build_wfl_node (super_identifier_node,
                                             input_filename, 0, 0);
@@ -3115,167 +3113,167 @@ case 154:
                ;
     break;}
 case 155:
-#line 850 "./parse.y"
+#line 848 "./parse.y"
 { create_interface (0, yyvsp[0].node, NULL_TREE); ;
     break;}
 case 156:
-#line 852 "./parse.y"
+#line 850 "./parse.y"
 {
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 157:
-#line 856 "./parse.y"
+#line 854 "./parse.y"
 { create_interface (yyvsp[-2].value, yyvsp[0].node, NULL_TREE); ;
     break;}
 case 158:
-#line 858 "./parse.y"
+#line 856 "./parse.y"
 {
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 159:
-#line 862 "./parse.y"
+#line 860 "./parse.y"
 { create_interface (0, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 160:
-#line 864 "./parse.y"
+#line 862 "./parse.y"
 {
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 161:
-#line 868 "./parse.y"
+#line 866 "./parse.y"
 { create_interface (yyvsp[-3].value, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 162:
-#line 870 "./parse.y"
+#line 868 "./parse.y"
 {
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 163:
-#line 874 "./parse.y"
+#line 872 "./parse.y"
 {yyerror ("(here)'{' expected"); RECOVER;;
     break;}
 case 164:
-#line 876 "./parse.y"
+#line 874 "./parse.y"
 {yyerror ("(there)'{' expected"); RECOVER;;
     break;}
 case 165:
-#line 881 "./parse.y"
+#line 879 "./parse.y"
 { 
                  ctxp->interface_number = 1;
                  yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE);
                ;
     break;}
 case 166:
-#line 886 "./parse.y"
+#line 884 "./parse.y"
 { 
                  ctxp->interface_number++;
                  yyval.node = chainon (yyvsp[-2].node, build_tree_list (yyvsp[0].node, NULL_TREE));
                ;
     break;}
 case 167:
-#line 891 "./parse.y"
+#line 889 "./parse.y"
 {yyerror ("Invalid interface type"); RECOVER;;
     break;}
 case 168:
-#line 893 "./parse.y"
+#line 891 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 169:
-#line 898 "./parse.y"
+#line 896 "./parse.y"
 { yyval.node = NULL_TREE; ;
     break;}
 case 170:
-#line 900 "./parse.y"
+#line 898 "./parse.y"
 { yyval.node = NULL_TREE; ;
     break;}
 case 175:
-#line 912 "./parse.y"
+#line 910 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner class declaration"); ;
     break;}
 case 176:
-#line 914 "./parse.y"
+#line 912 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner interface declaration"); ;
     break;}
 case 178:
-#line 923 "./parse.y"
+#line 921 "./parse.y"
 { 
                  check_abstract_method_header (yyvsp[-1].node);
                  current_function_decl = NULL_TREE; /* FIXME ? */
                ;
     break;}
 case 179:
-#line 928 "./parse.y"
+#line 926 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 180:
-#line 934 "./parse.y"
+#line 932 "./parse.y"
 {
                  RULE ("ARRAY_INITIALIZER (empty)");
                ;
     break;}
 case 181:
-#line 938 "./parse.y"
+#line 936 "./parse.y"
 {
                  RULE ("ARRAY_INITIALIZER (variable)");
                ;
     break;}
 case 182:
-#line 942 "./parse.y"
+#line 940 "./parse.y"
 {
                  RULE ("ARRAY_INITIALIZER (,)");
                ;
     break;}
 case 183:
-#line 946 "./parse.y"
+#line 944 "./parse.y"
 {
                  RULE ("ARRAY_INITIALIZER (variable, ,)");
                ;
     break;}
 case 186:
-#line 955 "./parse.y"
+#line 953 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 187:
-#line 961 "./parse.y"
+#line 959 "./parse.y"
 { yyval.node = size_zero_node; ;
     break;}
 case 188:
-#line 963 "./parse.y"
+#line 961 "./parse.y"
 { yyval.node = yyvsp[0].node; ;
     break;}
 case 189:
-#line 968 "./parse.y"
+#line 966 "./parse.y"
 { enter_block (); ;
     break;}
 case 190:
-#line 973 "./parse.y"
+#line 971 "./parse.y"
 { 
                  maybe_absorb_scoping_blocks ();
                  yyval.node = exit_block ();
                ;
     break;}
 case 194:
-#line 987 "./parse.y"
+#line 985 "./parse.y"
 { yyval.node = java_method_add_stmt (current_function_decl, yyvsp[0].node); ;
     break;}
 case 195:
-#line 989 "./parse.y"
+#line 987 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner class declaration"); ;
     break;}
 case 197:
-#line 998 "./parse.y"
+#line 996 "./parse.y"
 { declare_local_variables (0, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 198:
-#line 1000 "./parse.y"
+#line 998 "./parse.y"
 { declare_local_variables (yyvsp[-2].value, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 204:
-#line 1010 "./parse.y"
+#line 1008 "./parse.y"
 { 
                  /* If the for loop is unlabeled, we must return the
                     block it was defined it. It our last chance to
@@ -3285,11 +3283,11 @@ case 204:
                ;
     break;}
 case 221:
-#line 1043 "./parse.y"
+#line 1041 "./parse.y"
 { yyval.node = size_zero_node; ;
     break;}
 case 222:
-#line 1048 "./parse.y"
+#line 1046 "./parse.y"
 {
                  yyval.node = build_labeled_block (EXPR_WFL_LINECOL (yyvsp[-1].node), 
                                            EXPR_WFL_NODE (yyvsp[-1].node));
@@ -3299,7 +3297,7 @@ case 222:
                ;
     break;}
 case 223:
-#line 1059 "./parse.y"
+#line 1057 "./parse.y"
 { 
                  yyval.node = complete_labeled_statement (yyvsp[-1].node, yyvsp[0].node);
                  pop_labeled_block ();
@@ -3307,11 +3305,11 @@ case 223:
                ;
     break;}
 case 224:
-#line 1065 "./parse.y"
+#line 1063 "./parse.y"
 {yyerror ("':' expected"); RECOVER;;
     break;}
 case 225:
-#line 1070 "./parse.y"
+#line 1068 "./parse.y"
 { 
                  yyval.node = complete_labeled_statement (yyvsp[-1].node, yyvsp[0].node);
                  pop_labeled_block ();
@@ -3319,7 +3317,7 @@ case 225:
                ;
     break;}
 case 226:
-#line 1081 "./parse.y"
+#line 1079 "./parse.y"
 {
                  /* We have a statement. Generate a WFL around it so
                     we can debug it */
@@ -3330,7 +3328,7 @@ case 226:
                ;
     break;}
 case 227:
-#line 1090 "./parse.y"
+#line 1088 "./parse.y"
 {
                  if (ctxp->prevent_ese != lineno)
                    yyerror ("Invalid expression statement");
@@ -3338,7 +3336,7 @@ case 227:
                ;
     break;}
 case 228:
-#line 1096 "./parse.y"
+#line 1094 "./parse.y"
 {
                  if (ctxp->prevent_ese != lineno)
                    yyerror ("Invalid expression statement");
@@ -3346,7 +3344,7 @@ case 228:
                ;
     break;}
 case 229:
-#line 1102 "./parse.y"
+#line 1100 "./parse.y"
 {
                  if (ctxp->prevent_ese != lineno)
                    yyerror ("Invalid expression statement");
@@ -3354,11 +3352,11 @@ case 229:
                ;
     break;}
 case 230:
-#line 1108 "./parse.y"
+#line 1106 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 231:
-#line 1110 "./parse.y"
+#line 1108 "./parse.y"
 {
                  yyerror ("Constructor invocation must be first "
                           "thing in a constructor"); 
@@ -3366,11 +3364,11 @@ case 231:
                ;
     break;}
 case 232:
-#line 1116 "./parse.y"
+#line 1114 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 233:
-#line 1118 "./parse.y"
+#line 1116 "./parse.y"
 {
                  yyerror ("Constructor invocation must be first "
                           "thing in a constructor"); 
@@ -3378,89 +3376,89 @@ case 233:
                ;
     break;}
 case 234:
-#line 1124 "./parse.y"
+#line 1122 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 235:
-#line 1126 "./parse.y"
+#line 1124 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 236:
-#line 1128 "./parse.y"
+#line 1126 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 237:
-#line 1130 "./parse.y"
+#line 1128 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 238:
-#line 1132 "./parse.y"
+#line 1130 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 246:
-#line 1147 "./parse.y"
+#line 1145 "./parse.y"
 { yyval.node = build_if_else_statement (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node, NULL_TREE); ;
     break;}
 case 247:
-#line 1149 "./parse.y"
+#line 1147 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 248:
-#line 1151 "./parse.y"
+#line 1149 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 249:
-#line 1153 "./parse.y"
+#line 1151 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 250:
-#line 1158 "./parse.y"
+#line 1156 "./parse.y"
 { yyval.node = build_if_else_statement (yyvsp[-5].operator.location, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
     break;}
 case 251:
-#line 1163 "./parse.y"
+#line 1161 "./parse.y"
 { yyval.node = build_if_else_statement (yyvsp[-5].operator.location, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
     break;}
 case 252:
-#line 1168 "./parse.y"
+#line 1166 "./parse.y"
 { 
                  TREE_OPERAND (yyvsp[-1].node, 1) = yyvsp[0].node;
                  yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-1].node), yyvsp[-1].node);
                ;
     break;}
 case 253:
-#line 1176 "./parse.y"
+#line 1174 "./parse.y"
 { 
                  yyval.node = build (SWITCH_EXPR, NULL_TREE, yyvsp[-1].node, NULL_TREE);
                  EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
                ;
     break;}
 case 254:
-#line 1181 "./parse.y"
+#line 1179 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 255:
-#line 1183 "./parse.y"
+#line 1181 "./parse.y"
 {yyerror ("Missing term or ')'"); DRECOVER(switch_statement);;
     break;}
 case 256:
-#line 1185 "./parse.y"
+#line 1183 "./parse.y"
 {yyerror ("'{' expected"); RECOVER;;
     break;}
 case 257:
-#line 1190 "./parse.y"
+#line 1188 "./parse.y"
 { yyval.node = NULL_TREE; ;
     break;}
 case 258:
-#line 1192 "./parse.y"
+#line 1190 "./parse.y"
 { yyval.node = build_tree_list (yyvsp[-1].node, NULL_TREE); ;
     break;}
 case 259:
-#line 1194 "./parse.y"
+#line 1192 "./parse.y"
 { yyval.node = yyvsp[-1].node; ;
     break;}
 case 260:
-#line 1196 "./parse.y"
+#line 1194 "./parse.y"
 { 
                  /* Switch labels alone are empty switch statements */
                  tree sl = build_tree_list (yyvsp[-1].node, NULL_TREE);
@@ -3469,18 +3467,18 @@ case 260:
                ;
     break;}
 case 262:
-#line 1207 "./parse.y"
+#line 1205 "./parse.y"
 { 
                  TREE_CHAIN (yyvsp[0].node) = yyvsp[-1].node;
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 263:
-#line 1215 "./parse.y"
+#line 1213 "./parse.y"
 { yyval.node = build_tree_list (yyvsp[-1].node, exit_block ()); ;
     break;}
 case 264:
-#line 1220 "./parse.y"
+#line 1218 "./parse.y"
 { 
                  /* All statements attached to this group of cases
                     will be stored in a block */
@@ -3489,82 +3487,82 @@ case 264:
                ;
     break;}
 case 266:
-#line 1230 "./parse.y"
+#line 1228 "./parse.y"
 {
                  TREE_CHAIN (yyvsp[0].node) = yyvsp[-1].node;
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 267:
-#line 1238 "./parse.y"
+#line 1236 "./parse.y"
 { 
                  yyval.node = build1 (CASE_EXPR, NULL_TREE, yyvsp[-1].node);
                  EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
                ;
     break;}
 case 268:
-#line 1243 "./parse.y"
+#line 1241 "./parse.y"
 { 
                  yyval.node = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
                  EXPR_WFL_LINECOL (yyval.node) = yyvsp[-1].operator.location;
                ;
     break;}
 case 269:
-#line 1248 "./parse.y"
+#line 1246 "./parse.y"
 {yyerror ("Missing or invalid constant expression"); RECOVER;;
     break;}
 case 270:
-#line 1250 "./parse.y"
+#line 1248 "./parse.y"
 {yyerror ("':' expected"); RECOVER;;
     break;}
 case 271:
-#line 1252 "./parse.y"
+#line 1250 "./parse.y"
 {yyerror ("':' expected"); RECOVER;;
     break;}
 case 272:
-#line 1257 "./parse.y"
+#line 1255 "./parse.y"
 { 
                  tree body = build_loop_body (yyvsp[-2].operator.location, yyvsp[-1].node, 0);
                  yyval.node = build_new_loop (body);
                ;
     break;}
 case 273:
-#line 1265 "./parse.y"
+#line 1263 "./parse.y"
 { yyval.node = complete_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
     break;}
 case 274:
-#line 1267 "./parse.y"
+#line 1265 "./parse.y"
 {YYERROR_NOW; yyerror ("'(' expected"); RECOVER;;
     break;}
 case 275:
-#line 1269 "./parse.y"
+#line 1267 "./parse.y"
 {yyerror ("Missing term and ')' expected"); RECOVER;;
     break;}
 case 276:
-#line 1271 "./parse.y"
+#line 1269 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 277:
-#line 1276 "./parse.y"
+#line 1274 "./parse.y"
 { yyval.node = complete_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
     break;}
 case 278:
-#line 1281 "./parse.y"
+#line 1279 "./parse.y"
 { 
                  tree body = build_loop_body (0, NULL_TREE, 1);
                  yyval.node = build_new_loop (body);
                ;
     break;}
 case 279:
-#line 1290 "./parse.y"
+#line 1288 "./parse.y"
 { yyval.node = complete_loop_body (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[-5].node, 1); ;
     break;}
 case 280:
-#line 1295 "./parse.y"
+#line 1293 "./parse.y"
 { yyval.node = complete_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);;
     break;}
 case 281:
-#line 1297 "./parse.y"
+#line 1295 "./parse.y"
 { 
                  yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
                  /* We have not condition, so we get rid of the EXIT_EXPR */
@@ -3573,23 +3571,23 @@ case 281:
                ;
     break;}
 case 282:
-#line 1304 "./parse.y"
+#line 1302 "./parse.y"
 {yyerror ("Invalid control expression"); RECOVER;;
     break;}
 case 283:
-#line 1306 "./parse.y"
+#line 1304 "./parse.y"
 {yyerror ("Invalid update expression"); RECOVER;;
     break;}
 case 284:
-#line 1308 "./parse.y"
+#line 1306 "./parse.y"
 {yyerror ("Invalid update expression"); RECOVER;;
     break;}
 case 285:
-#line 1313 "./parse.y"
+#line 1311 "./parse.y"
 { yyval.node = complete_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);;
     break;}
 case 286:
-#line 1315 "./parse.y"
+#line 1313 "./parse.y"
 { 
                  yyval.node = complete_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
                  /* We have not condition, so we get rid of the EXIT_EXPR */
@@ -3598,7 +3596,7 @@ case 286:
                ;
     break;}
 case 287:
-#line 1325 "./parse.y"
+#line 1323 "./parse.y"
 { 
                  /* This scope defined for local variable that may be
                      defined within the scope of the for loop */
@@ -3606,15 +3604,15 @@ case 287:
                ;
     break;}
 case 288:
-#line 1331 "./parse.y"
+#line 1329 "./parse.y"
 {yyerror ("'(' expected"); DRECOVER(for_1);;
     break;}
 case 289:
-#line 1333 "./parse.y"
+#line 1331 "./parse.y"
 {yyerror ("Invalid init statement"); RECOVER;;
     break;}
 case 290:
-#line 1338 "./parse.y"
+#line 1336 "./parse.y"
 { 
                  /* We now declare the loop body. The loop is
                      declared as a for loop. */
@@ -3627,11 +3625,11 @@ case 290:
                ;
     break;}
 case 291:
-#line 1350 "./parse.y"
+#line 1348 "./parse.y"
 { yyval.node = size_zero_node; ;
     break;}
 case 292:
-#line 1352 "./parse.y"
+#line 1350 "./parse.y"
 { 
                  /* Init statement recorded within the previously
                      defined block scope */
@@ -3639,7 +3637,7 @@ case 292:
                ;
     break;}
 case 293:
-#line 1358 "./parse.y"
+#line 1356 "./parse.y"
 { 
                  /* Local variable are recorded within the previously
                     defined block scope */
@@ -3647,94 +3645,94 @@ case 293:
                ;
     break;}
 case 294:
-#line 1364 "./parse.y"
+#line 1362 "./parse.y"
 {yyerror ("';' expected"); DRECOVER(for_init_1);;
     break;}
 case 295:
-#line 1368 "./parse.y"
+#line 1366 "./parse.y"
 {yyval.node = size_zero_node;;
     break;}
 case 296:
-#line 1370 "./parse.y"
+#line 1368 "./parse.y"
 { yyval.node = build_debugable_stmt (BUILD_LOCATION (), yyvsp[0].node); ;
     break;}
 case 297:
-#line 1375 "./parse.y"
+#line 1373 "./parse.y"
 { yyval.node = add_stmt_to_compound (NULL_TREE, NULL_TREE, yyvsp[0].node); ;
     break;}
 case 298:
-#line 1377 "./parse.y"
+#line 1375 "./parse.y"
 { yyval.node = add_stmt_to_compound (yyvsp[-2].node, NULL_TREE, yyvsp[0].node); ;
     break;}
 case 299:
-#line 1379 "./parse.y"
+#line 1377 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 300:
-#line 1384 "./parse.y"
+#line 1382 "./parse.y"
 { yyval.node = build_bc_statement (yyvsp[-1].operator.location, 1, NULL_TREE); ;
     break;}
 case 301:
-#line 1386 "./parse.y"
+#line 1384 "./parse.y"
 { yyval.node = build_bc_statement (yyvsp[-2].operator.location, 1, yyvsp[-1].node); ;
     break;}
 case 302:
-#line 1388 "./parse.y"
+#line 1386 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 303:
-#line 1390 "./parse.y"
+#line 1388 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 304:
-#line 1395 "./parse.y"
+#line 1393 "./parse.y"
 { yyval.node = build_bc_statement (yyvsp[-1].operator.location, 0, NULL_TREE); ;
     break;}
 case 305:
-#line 1397 "./parse.y"
+#line 1395 "./parse.y"
 { yyval.node = build_bc_statement (yyvsp[-2].operator.location, 0, yyvsp[-1].node); ;
     break;}
 case 306:
-#line 1399 "./parse.y"
+#line 1397 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 307:
-#line 1401 "./parse.y"
+#line 1399 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 308:
-#line 1406 "./parse.y"
+#line 1404 "./parse.y"
 { yyval.node = build_return (yyvsp[-1].operator.location, NULL_TREE); ;
     break;}
 case 309:
-#line 1408 "./parse.y"
+#line 1406 "./parse.y"
 { yyval.node = build_return (yyvsp[-2].operator.location, yyvsp[-1].node); ;
     break;}
 case 310:
-#line 1410 "./parse.y"
+#line 1408 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 311:
-#line 1412 "./parse.y"
+#line 1410 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 312:
-#line 1417 "./parse.y"
+#line 1415 "./parse.y"
 { 
                  yyval.node = build1 (THROW_EXPR, NULL_TREE, yyvsp[-1].node);
                  EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
                ;
     break;}
 case 313:
-#line 1422 "./parse.y"
+#line 1420 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 314:
-#line 1424 "./parse.y"
+#line 1422 "./parse.y"
 {yyerror ("';' expected"); RECOVER;;
     break;}
 case 315:
-#line 1429 "./parse.y"
+#line 1427 "./parse.y"
 { 
                  yyval.node = build (SYNCHRONIZED_EXPR, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
                  EXPR_WFL_LINECOL (yyval.node) = 
@@ -3742,53 +3740,53 @@ case 315:
                ;
     break;}
 case 316:
-#line 1435 "./parse.y"
+#line 1433 "./parse.y"
 {yyerror ("'{' expected"); RECOVER;;
     break;}
 case 317:
-#line 1437 "./parse.y"
+#line 1435 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 318:
-#line 1439 "./parse.y"
+#line 1437 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 319:
-#line 1441 "./parse.y"
+#line 1439 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 320:
-#line 1446 "./parse.y"
+#line 1444 "./parse.y"
 {
                  if ((1 << yyvsp[0].value) != ACC_SYNCHRONIZED)
                    fatal ("synchronized was '%d' - yyparse", (1 << yyvsp[0].value));
                ;
     break;}
 case 321:
-#line 1454 "./parse.y"
+#line 1452 "./parse.y"
 { yyval.node = build_try_statement (yyvsp[-2].operator.location, yyvsp[-1].node, yyvsp[0].node, NULL_TREE); ;
     break;}
 case 322:
-#line 1456 "./parse.y"
+#line 1454 "./parse.y"
 { yyval.node = build_try_statement (yyvsp[-2].operator.location, yyvsp[-1].node, NULL_TREE, yyvsp[0].node); ;
     break;}
 case 323:
-#line 1458 "./parse.y"
+#line 1456 "./parse.y"
 { yyval.node = build_try_statement (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
     break;}
 case 324:
-#line 1460 "./parse.y"
+#line 1458 "./parse.y"
 {yyerror ("'{' expected"); DRECOVER (try_statement);;
     break;}
 case 326:
-#line 1466 "./parse.y"
+#line 1464 "./parse.y"
 { 
                  TREE_CHAIN (yyvsp[0].node) = yyvsp[-1].node;
                  yyval.node = yyvsp[0].node;
                ;
     break;}
 case 327:
-#line 1474 "./parse.y"
+#line 1472 "./parse.y"
 { 
                  java_method_add_stmt (current_function_decl, yyvsp[0].node);
                  exit_block ();
@@ -3796,7 +3794,7 @@ case 327:
                ;
     break;}
 case 328:
-#line 1482 "./parse.y"
+#line 1480 "./parse.y"
 { 
                  /* We add a block to define a scope for
                     formal_parameter (CCBP). The formal parameter is
@@ -3814,179 +3812,179 @@ case 328:
                ;
     break;}
 case 329:
-#line 1498 "./parse.y"
+#line 1496 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 330:
-#line 1500 "./parse.y"
+#line 1498 "./parse.y"
 {yyerror ("Missing term or ')' expected"); DRECOVER (2);;
     break;}
 case 331:
-#line 1502 "./parse.y"
+#line 1500 "./parse.y"
 {yyerror ("')' expected"); DRECOVER (1);;
     break;}
 case 332:
-#line 1507 "./parse.y"
+#line 1505 "./parse.y"
 { 
                  yyval.node = build (FINALLY_EXPR, NULL_TREE,
                              create_label_decl (generate_name ()), yyvsp[0].node);
                ;
     break;}
 case 333:
-#line 1512 "./parse.y"
+#line 1510 "./parse.y"
 {yyerror ("'{' expected"); RECOVER; ;
     break;}
 case 337:
-#line 1524 "./parse.y"
+#line 1522 "./parse.y"
 { yyval.node = build_this (yyvsp[0].operator.location); ;
     break;}
 case 338:
-#line 1526 "./parse.y"
+#line 1524 "./parse.y"
 {yyval.node = yyvsp[-1].node;;
     break;}
 case 343:
-#line 1535 "./parse.y"
+#line 1533 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("class literals"); ;
     break;}
 case 344:
-#line 1537 "./parse.y"
+#line 1535 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("class literals"); ;
     break;}
 case 345:
-#line 1539 "./parse.y"
+#line 1537 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("class literals"); ;
     break;}
 case 346:
-#line 1544 "./parse.y"
+#line 1542 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("class literals"); ;
     break;}
 case 347:
-#line 1546 "./parse.y"
+#line 1544 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 348:
-#line 1548 "./parse.y"
+#line 1546 "./parse.y"
 {yyerror ("'class' or 'this' expected" ); RECOVER;;
     break;}
 case 349:
-#line 1550 "./parse.y"
+#line 1548 "./parse.y"
 {yyerror ("'class' expected" ); RECOVER;;
     break;}
 case 350:
-#line 1552 "./parse.y"
+#line 1550 "./parse.y"
 {yyerror ("'class' expected" ); RECOVER;;
     break;}
 case 351:
-#line 1557 "./parse.y"
+#line 1555 "./parse.y"
 { yyval.node = build_new_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
     break;}
 case 352:
-#line 1559 "./parse.y"
+#line 1557 "./parse.y"
 { yyval.node = build_new_invocation (yyvsp[-2].node, NULL_TREE); ;
     break;}
 case 353:
-#line 1564 "./parse.y"
+#line 1562 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner class instance creation"); ;
     break;}
 case 354:
-#line 1566 "./parse.y"
+#line 1564 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("inner class instance creation"); ;
     break;}
 case 359:
-#line 1575 "./parse.y"
+#line 1573 "./parse.y"
 {yyerror ("'(' expected"); DRECOVER(new_1);;
     break;}
 case 360:
-#line 1577 "./parse.y"
+#line 1575 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 361:
-#line 1579 "./parse.y"
+#line 1577 "./parse.y"
 {yyerror ("')' or term expected"); RECOVER;;
     break;}
 case 362:
-#line 1581 "./parse.y"
+#line 1579 "./parse.y"
 {yyerror ("')' expected"); RECOVER;;
     break;}
 case 363:
-#line 1583 "./parse.y"
+#line 1581 "./parse.y"
 {YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;;
     break;}
 case 364:
-#line 1585 "./parse.y"
+#line 1583 "./parse.y"
 {yyerror ("'(' expected"); RECOVER;;
     break;}
 case 367:
-#line 1595 "./parse.y"
+#line 1593 "./parse.y"
 { 
                  yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, NULL_TREE);
                  ctxp->formal_parameter_number = 1; 
                ;
     break;}
 case 368:
-#line 1600 "./parse.y"
+#line 1598 "./parse.y"
 {
                  ctxp->formal_parameter_number += 1;
                  yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node);
                ;
     break;}
 case 369:
-#line 1605 "./parse.y"
+#line 1603 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 370:
-#line 1610 "./parse.y"
+#line 1608 "./parse.y"
 { yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
     break;}
 case 371:
-#line 1612 "./parse.y"
+#line 1610 "./parse.y"
 { yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
     break;}
 case 372:
-#line 1614 "./parse.y"
+#line 1612 "./parse.y"
 { yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ;
     break;}
 case 373:
-#line 1616 "./parse.y"
+#line 1614 "./parse.y"
 { yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, ctxp->osb_number); ;
     break;}
 case 374:
-#line 1620 "./parse.y"
+#line 1618 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("anonymous array"); ;
     break;}
 case 375:
-#line 1622 "./parse.y"
+#line 1620 "./parse.y"
 { yyval.node = parse_jdk1_1_error ("anonymous array"); ;
     break;}
 case 376:
-#line 1624 "./parse.y"
+#line 1622 "./parse.y"
 {yyerror ("'[' expected"); DRECOVER ("]");;
     break;}
 case 377:
-#line 1626 "./parse.y"
+#line 1624 "./parse.y"
 {yyerror ("']' expected"); RECOVER;;
     break;}
 case 378:
-#line 1631 "./parse.y"
+#line 1629 "./parse.y"
 { yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ;
     break;}
 case 379:
-#line 1633 "./parse.y"
+#line 1631 "./parse.y"
 { yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyval.node); ;
     break;}
 case 380:
-#line 1638 "./parse.y"
+#line 1636 "./parse.y"
 { 
                  EXPR_WFL_LINECOL (yyvsp[-1].node) = yyvsp[-2].operator.location;
                  yyval.node = yyvsp[-1].node;
                ;
     break;}
 case 381:
-#line 1643 "./parse.y"
+#line 1641 "./parse.y"
 {yyerror ("']' expected"); RECOVER;;
     break;}
 case 382:
-#line 1645 "./parse.y"
+#line 1643 "./parse.y"
 {
                  yyerror ("Missing term");
                  yyerror ("']' expected");
@@ -3994,23 +3992,23 @@ case 382:
                ;
     break;}
 case 383:
-#line 1654 "./parse.y"
+#line 1652 "./parse.y"
 { ctxp->osb_number = 1; ;
     break;}
 case 384:
-#line 1656 "./parse.y"
+#line 1654 "./parse.y"
 { ctxp->osb_number++; ;
     break;}
 case 385:
-#line 1658 "./parse.y"
+#line 1656 "./parse.y"
 { yyerror ("']' expected"); RECOVER;;
     break;}
 case 386:
-#line 1663 "./parse.y"
+#line 1661 "./parse.y"
 { yyval.node = make_qualified_primary (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
     break;}
 case 387:
-#line 1665 "./parse.y"
+#line 1663 "./parse.y"
 {
                  tree super_wfl = 
                    build_wfl_node (super_identifier_node, 
@@ -4020,19 +4018,19 @@ case 387:
                ;
     break;}
 case 388:
-#line 1673 "./parse.y"
+#line 1671 "./parse.y"
 {yyerror ("Field expected"); DRECOVER (super_field_acces);;
     break;}
 case 389:
-#line 1678 "./parse.y"
+#line 1676 "./parse.y"
 { yyval.node = build_method_invocation (yyvsp[-2].node, NULL_TREE); ;
     break;}
 case 390:
-#line 1680 "./parse.y"
+#line 1678 "./parse.y"
 { yyval.node = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
     break;}
 case 391:
-#line 1682 "./parse.y"
+#line 1680 "./parse.y"
 { 
                  if (TREE_CODE (yyvsp[-4].node) == THIS_EXPR)
                    yyval.node = build_this_super_qualified_invocation 
@@ -4045,7 +4043,7 @@ case 391:
                ;
     break;}
 case 392:
-#line 1693 "./parse.y"
+#line 1691 "./parse.y"
 { 
                  if (TREE_CODE (yyvsp[-5].node) == THIS_EXPR)
                    yyval.node = build_this_super_qualified_invocation 
@@ -4058,121 +4056,121 @@ case 392:
                ;
     break;}
 case 393:
-#line 1704 "./parse.y"
+#line 1702 "./parse.y"
 { 
                  yyval.node = build_this_super_qualified_invocation 
                    (0, yyvsp[-2].node, NULL_TREE, yyvsp[-4].operator.location, yyvsp[-3].operator.location);
                ;
     break;}
 case 394:
-#line 1709 "./parse.y"
+#line 1707 "./parse.y"
 {
                  yyval.node = build_this_super_qualified_invocation 
                    (0, yyvsp[-3].node, yyvsp[-1].node, yyvsp[-5].operator.location, yyvsp[-4].operator.location);
                ;
     break;}
 case 395:
-#line 1718 "./parse.y"
+#line 1716 "./parse.y"
 { yyerror ("'(' expected"); DRECOVER (method_invocation); ;
     break;}
 case 396:
-#line 1720 "./parse.y"
+#line 1718 "./parse.y"
 { yyerror ("'(' expected"); DRECOVER (method_invocation); ;
     break;}
 case 397:
-#line 1725 "./parse.y"
+#line 1723 "./parse.y"
 { yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
     break;}
 case 398:
-#line 1727 "./parse.y"
+#line 1725 "./parse.y"
 { yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
     break;}
 case 399:
-#line 1729 "./parse.y"
+#line 1727 "./parse.y"
 {
                  yyerror ("Missing term and ']' expected");
                  DRECOVER(array_access);
                ;
     break;}
 case 400:
-#line 1734 "./parse.y"
+#line 1732 "./parse.y"
 {
                  yyerror ("']' expected");
                  DRECOVER(array_access);
                ;
     break;}
 case 401:
-#line 1739 "./parse.y"
+#line 1737 "./parse.y"
 {
                  yyerror ("Missing term and ']' expected");
                  DRECOVER(array_access);
                ;
     break;}
 case 402:
-#line 1744 "./parse.y"
+#line 1742 "./parse.y"
 {
                  yyerror ("']' expected");
                  DRECOVER(array_access);
                ;
     break;}
 case 407:
-#line 1759 "./parse.y"
+#line 1757 "./parse.y"
 { yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
     break;}
 case 408:
-#line 1764 "./parse.y"
+#line 1762 "./parse.y"
 { yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
     break;}
 case 411:
-#line 1771 "./parse.y"
+#line 1769 "./parse.y"
 {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
     break;}
 case 412:
-#line 1773 "./parse.y"
+#line 1771 "./parse.y"
 {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
     break;}
 case 414:
-#line 1776 "./parse.y"
+#line 1774 "./parse.y"
 {yyerror ("Missing term"); RECOVER;
     break;}
 case 415:
-#line 1778 "./parse.y"
+#line 1776 "./parse.y"
 {yyerror ("Missing term"); RECOVER;
     break;}
 case 416:
-#line 1783 "./parse.y"
+#line 1781 "./parse.y"
 {yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
     break;}
 case 417:
-#line 1785 "./parse.y"
+#line 1783 "./parse.y"
 {yyerror ("Missing term"); RECOVER;
     break;}
 case 418:
-#line 1790 "./parse.y"
+#line 1788 "./parse.y"
 {yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
     break;}
 case 419:
-#line 1792 "./parse.y"
+#line 1790 "./parse.y"
 {yyerror ("Missing term"); RECOVER;
     break;}
 case 421:
-#line 1798 "./parse.y"
+#line 1796 "./parse.y"
 {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
     break;}
 case 422:
-#line 1800 "./parse.y"
+#line 1798 "./parse.y"
 {yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
     break;}
 case 424:
-#line 1803 "./parse.y"
+#line 1801 "./parse.y"
 {yyerror ("Missing term"); RECOVER;
     break;}
 case 425:
-#line 1805 "./parse.y"
+#line 1803 "./parse.y"
 {yyerror ("Missing term"); RECOVER;
     break;}
 case 426:
-#line 1810 "./parse.y"
+#line 1808 "./parse.y"
 { 
                  tree type = yyvsp[-3].node;
                  while (ctxp->osb_number--)
@@ -4181,15 +4179,15 @@ case 426:
                ;
     break;}
 case 427:
-#line 1817 "./parse.y"
+#line 1815 "./parse.y"
 { yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
     break;}
 case 428:
-#line 1819 "./parse.y"
+#line 1817 "./parse.y"
 { yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
     break;}
 case 429:
-#line 1821 "./parse.y"
+#line 1819 "./parse.y"
 { 
                  char *ptr;
                  while (ctxp->osb_number--)
@@ -4203,11 +4201,11 @@ case 429:
                ;
     break;}
 case 430:
-#line 1833 "./parse.y"
+#line 1831 "./parse.y"
 {yyerror ("']' expected, invalid type expression");;
     break;}
 case 431:
-#line 1835 "./parse.y"
+#line 1833 "./parse.y"
 {
                  if (ctxp->prevent_ese != lineno)
                    yyerror ("Invalid type expression"); RECOVER;
@@ -4215,239 +4213,243 @@ case 431:
                ;
     break;}
 case 432:
-#line 1841 "./parse.y"
+#line 1839 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 433:
-#line 1843 "./parse.y"
+#line 1841 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 434:
-#line 1845 "./parse.y"
+#line 1843 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 436:
-#line 1851 "./parse.y"
+#line 1849 "./parse.y"
 { 
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), 
                                    yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node);
                ;
     break;}
 case 437:
-#line 1856 "./parse.y"
+#line 1854 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 438:
-#line 1861 "./parse.y"
+#line 1859 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 439:
-#line 1866 "./parse.y"
+#line 1864 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 440:
-#line 1868 "./parse.y"
+#line 1866 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 441:
-#line 1870 "./parse.y"
+#line 1868 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 443:
-#line 1876 "./parse.y"
+#line 1874 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 444:
-#line 1881 "./parse.y"
+#line 1879 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 445:
-#line 1886 "./parse.y"
+#line 1884 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 446:
-#line 1888 "./parse.y"
+#line 1886 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 448:
-#line 1894 "./parse.y"
+#line 1892 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 449:
-#line 1899 "./parse.y"
+#line 1897 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 450:
-#line 1904 "./parse.y"
+#line 1902 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 451:
-#line 1909 "./parse.y"
+#line 1907 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 452:
-#line 1911 "./parse.y"
+#line 1909 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 453:
-#line 1913 "./parse.y"
+#line 1911 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 455:
-#line 1919 "./parse.y"
+#line 1917 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 456:
-#line 1924 "./parse.y"
+#line 1922 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 457:
-#line 1929 "./parse.y"
+#line 1927 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 458:
-#line 1934 "./parse.y"
+#line 1932 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
+case 459:
+#line 1937 "./parse.y"
+{ yyval.node = build_binop (INSTANCEOF_EXPR, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
+    break;}
 case 460:
-#line 1940 "./parse.y"
+#line 1939 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 461:
-#line 1942 "./parse.y"
+#line 1941 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 462:
-#line 1944 "./parse.y"
+#line 1943 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 463:
-#line 1946 "./parse.y"
+#line 1945 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 464:
-#line 1948 "./parse.y"
+#line 1947 "./parse.y"
 {yyerror ("Invalid reference type"); RECOVER;;
     break;}
 case 466:
-#line 1954 "./parse.y"
+#line 1953 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 467:
-#line 1959 "./parse.y"
+#line 1958 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 468:
-#line 1964 "./parse.y"
+#line 1963 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 469:
-#line 1966 "./parse.y"
+#line 1965 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 471:
-#line 1972 "./parse.y"
+#line 1971 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 472:
-#line 1977 "./parse.y"
+#line 1976 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 474:
-#line 1983 "./parse.y"
+#line 1982 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 475:
-#line 1988 "./parse.y"
+#line 1987 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 477:
-#line 1994 "./parse.y"
+#line 1993 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 478:
-#line 1999 "./parse.y"
+#line 1998 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 480:
-#line 2005 "./parse.y"
+#line 2004 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 481:
-#line 2010 "./parse.y"
+#line 2009 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 483:
-#line 2016 "./parse.y"
+#line 2015 "./parse.y"
 {
                  yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
                                    yyvsp[-2].node, yyvsp[0].node); 
                ;
     break;}
 case 484:
-#line 2021 "./parse.y"
+#line 2020 "./parse.y"
 {yyerror ("Missing term"); RECOVER;;
     break;}
 case 486:
-#line 2027 "./parse.y"
+#line 2026 "./parse.y"
 {
                  yyval.node = build (CONDITIONAL_EXPR, NULL_TREE, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);
                  EXPR_WFL_LINECOL (yyval.node) = yyvsp[-3].operator.location;
                ;
     break;}
 case 487:
-#line 2032 "./parse.y"
+#line 2031 "./parse.y"
 {
                  YYERROR_NOW;
                  yyerror ("Missing term");
@@ -4455,19 +4457,19 @@ case 487:
                ;
     break;}
 case 488:
-#line 2038 "./parse.y"
+#line 2037 "./parse.y"
 {yyerror ("Missing term"); DRECOVER (2);;
     break;}
 case 489:
-#line 2040 "./parse.y"
+#line 2039 "./parse.y"
 {yyerror ("Missing term"); DRECOVER (3);;
     break;}
 case 492:
-#line 2050 "./parse.y"
+#line 2049 "./parse.y"
 { yyval.node = build_assignment (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
     break;}
 case 493:
-#line 2052 "./parse.y"
+#line 2051 "./parse.y"
 {
                  if (ctxp->prevent_ese != lineno)
                    yyerror ("Missing term");
@@ -4672,7 +4674,7 @@ yyerrhandle:
   yystate = yyn;
   goto yynewstate;
 }
-#line 2078 "./parse.y"
+#line 2077 "./parse.y"
 
 \f
 
@@ -4696,7 +4698,10 @@ java_push_parser_context ()
   new->next = ctxp;
   ctxp = new;
   if (ctxp->next)
-    ctxp->incomplete_class = ctxp->next->incomplete_class;
+    {
+      ctxp->incomplete_class = ctxp->next->incomplete_class;
+      ctxp->gclass_list = ctxp->next->gclass_list;
+    }
 }  
 
 /* If the first file of a file list was a class file, no context
@@ -4740,12 +4745,17 @@ java_pop_parser_context (generate)
      int generate;
 {
   tree current;
-  struct parser_ctxt *toFree = ctxp;
-  struct parser_ctxt *next = ctxp->next;
+  struct parser_ctxt *toFree, *next;
 
+  if (!ctxp)
+    return;
+
+  toFree = ctxp;
+  next = ctxp->next;
   if (next)
     {
       next->incomplete_class = ctxp->incomplete_class;
+      next->gclass_list = ctxp->gclass_list;
       lineno = ctxp->lineno;
       finput = ctxp->finput;
       current_class = ctxp->current_class;
@@ -4857,6 +4867,24 @@ parse_error (msg)
   java_error (msg);
 }
 
+static void
+issue_warning_error_from_context (cl, msg)
+     tree cl;
+     char *msg;
+{
+  char *saved;
+
+  ctxp->elc.line = EXPR_WFL_LINENO (cl);
+  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
+
+  /* We have a CL, that's a good reason for using it if it contains data */
+  saved = ctxp->filename;
+  if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
+    ctxp->filename = EXPR_WFL_FILENAME (cl);
+  parse_error (msg);
+  ctxp->filename = saved;
+}
+
 /* Issue an error message at a current source line CL */
 
 static void
@@ -4877,10 +4905,7 @@ parse_error_context VPROTO ((tree cl, char *msg, ...))
   vsprintf (buffer, msg, ap);
 
   force_error = 1;
-  ctxp->elc.line = EXPR_WFL_LINENO (cl);
-  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
-  parse_error (buffer);
+  issue_warning_error_from_context (cl, buffer);
   force_error = 0;
 }
 
@@ -4904,10 +4929,7 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...))
   vsprintf (buffer, msg, ap);
 
   force_error = do_warning = 1;
-  ctxp->elc.line = EXPR_WFL_LINENO (cl);
-  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
-  parse_error (buffer);
+  issue_warning_error_from_context (cl, buffer);
   do_warning = force_error = 0;
 }
 
@@ -5160,9 +5182,7 @@ static tree
 maybe_create_class_interface_decl (decl, qualified_name, cl)
      tree decl, qualified_name, cl;
 {
-  if (decl)
-    DECL_ARTIFICIAL (decl) = 1; /* FIXME */
-  else
+  if (!decl)
     decl = push_class (make_class (), qualified_name);
   
   /* Take care of the file and line business */
@@ -5177,6 +5197,10 @@ maybe_create_class_interface_decl (decl, qualified_name, cl)
   /* Link the declaration to the already seen ones */
   TREE_CHAIN (decl) = ctxp->class_list;
   ctxp->class_list = decl;
+
+  /* Create a new node in the global list */
+  ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
+
   /* Install a new dependency list element */
   create_jdep_list (ctxp);
 
@@ -5199,11 +5223,12 @@ add_superinterfaces (decl, interface_list)
    defined.  */
   for (node = interface_list; node; node = TREE_CHAIN (node))
     {
-      tree current = TREE_PURPOSE (node), interface_decl;
-      if ((interface_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current))))
+      tree current = TREE_PURPOSE (node);
+      tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
+      if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
        {
-         if (!parser_check_super_interface (interface_decl, decl, current))
-           parser_add_interface (decl, interface_decl, current);
+         if (!parser_check_super_interface (idecl, decl, current))
+           parser_add_interface (decl, idecl, current);
        }
       else
        register_incomplete_type (JDEP_INTERFACE,
@@ -5271,6 +5296,7 @@ create_class (flags, id, super, interfaces)
 
   class_id = parser_qualified_classname (id);
   decl = IDENTIFIER_CLASS_VALUE (class_id);
+  ctxp->current_parsed_class_un = EXPR_WFL_NODE (id);
   EXPR_WFL_NODE (id) = class_id;
 
   /* Basic check: scope, redefinition, modifiers */
@@ -5323,6 +5349,9 @@ create_class (flags, id, super, interfaces)
   CLASS_COMPLETE_P (decl) = 1;
   add_superinterfaces (decl, interfaces);
 
+  /* Eventually sets the @deprecated tag flag */
+  CHECK_DEPRECATED (decl);
+
   return decl;
 }
 
@@ -5452,9 +5481,10 @@ register_fields (flags, type, variable_list)
        }
 
       /* Set lineno to the line the field was found and create a
-         declaration for it */
+         declaration for it. Eventually sets the @deprecated tag flag. */
       lineno = EXPR_WFL_LINENO (cl);
       field_decl = add_field (class_type, current_name, type, flags);
+      CHECK_DEPRECATED (field_decl);
       
       /* Check if we must chain. */
       if (must_chain)
@@ -5471,12 +5501,16 @@ register_fields (flags, type, variable_list)
          /* The field is declared static */
          if (flags & ACC_STATIC)
            {
-             /* FIXME */
              if (flags & ACC_FINAL)
-               ;               
-             /* Otherwise, the field should be initialized in
-                <clinit>. This field is remembered so we can
-                generate <clinit> later. */
+               {
+                 if (DECL_LANG_SPECIFIC (field_decl) == NULL)
+                   DECL_LANG_SPECIFIC (field_decl) = (struct lang_decl *)
+                     permalloc (sizeof (struct lang_decl_var));
+                 DECL_LOCAL_STATIC_VALUE (field_decl) = 
+                   TREE_OPERAND (init, 1);
+               }
+             /* Otherwise, the field should be initialized in <clinit>. 
+                This field is remembered so we can generate <clinit> later */
              else
                {
                  INITIALIZED_P (field_decl) = 1;
@@ -5484,10 +5518,9 @@ register_fields (flags, type, variable_list)
                  ctxp->static_initialized = init;
                }
            }
-         /* A non-static field declared with an immediate
-            initialization is to be initialized in <init>, if
-            any.  This field is remembered to be processed at the
-            time of the generation of <init>. */
+         /* A non-static field declared with an immediate initialization is
+            to be initialized in <init>, if any.  This field is remembered
+            to be processed at the time of the generation of <init>. */
          else
            {
              INITIALIZED_P (field_decl) = 1;
@@ -5584,7 +5617,7 @@ method_header (flags, type, mdecl, throws)
   tree meth = TREE_VALUE (mdecl);
   tree id = TREE_PURPOSE (mdecl);
   tree this_class = TREE_TYPE (ctxp->current_parsed_class);
-  tree meth_name, returned_type, current;
+  tree meth_name, returned_type, current, orig_arg;
   int saved_lineno;
   int constructor_ok = 0;
   
@@ -5612,7 +5645,7 @@ method_header (flags, type, mdecl, throws)
       int ec = java_error_count;
       /* 8.6: Constructor declarations: we might be trying to define a
          method without specifying a return type. */
-      if (EXPR_WFL_NODE (id) != DECL_NAME (ctxp->current_parsed_class))
+      if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
        parse_error_context 
          (id, "Invalid method declaration, return type required");
       /* 8.6.3: Constructor modifiers */
@@ -5674,8 +5707,12 @@ method_header (flags, type, mdecl, throws)
            register_incomplete_type (patch_stage, type, id, NULL_TREE);
        }
     }
-  else
-    TREE_TYPE (meth) = type;
+  else
+    {
+      if (TREE_CODE (type) == RECORD_TYPE)
+       type = promote_type (type);
+      TREE_TYPE (meth) = type;
+    }
 
   saved_lineno = lineno;
   /* When defining an abstract or interface method, the curly
@@ -5684,6 +5721,9 @@ method_header (flags, type, mdecl, throws)
   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
            EXPR_WFL_LINENO (id));
 
+  /* Remember the original argument list */
+  orig_arg = TYPE_ARG_TYPES (meth);
+
   if (patch_stage)             /* includes ret type and/or all args */
     {
       jdep *jdep;
@@ -5699,28 +5739,15 @@ method_header (flags, type, mdecl, throws)
       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
     }
   else
-    {
-      tree signature = build_java_signature (meth);
-      tree arg, orig_arg;
-      /* Save original argument list, including argument's names */
-      orig_arg = TYPE_ARG_TYPES (meth);
-      /* Add the method to its class */
-      meth = add_method (this_class, flags, meth_name, signature);
-      /* Fix the method argument list so we have the argument name
-         information */
-      arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
-      if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
-       {
-         TREE_PURPOSE (arg) = this_identifier_node;
-         arg = TREE_CHAIN (arg);
-       }
-      while (orig_arg)
-        {
-         TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
-         orig_arg = TREE_CHAIN (orig_arg);
-         arg = TREE_CHAIN (arg);
-       }
-    }
+    meth = add_method (this_class, flags, meth_name, 
+                      build_java_signature (meth));
+
+  /* Fix the method argument list so we have the argument name
+     information */
+  fix_method_argument_names (orig_arg, meth);
+
+  /* Register the parameter number and re-install the current line
+     number */
   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
   lineno = saved_lineno;
 
@@ -5755,9 +5782,30 @@ method_header (flags, type, mdecl, throws)
   if (constructor_ok)
     DECL_CONSTRUCTOR_P (meth) = 1;
 
+  /* Eventually set the @deprecated tag flag */
+  CHECK_DEPRECATED (meth);
+
   return meth;
 }
 
+static void
+fix_method_argument_names (orig_arg, meth)
+    tree orig_arg, meth;
+{
+  tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
+  if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
+    {
+      TREE_PURPOSE (arg) = this_identifier_node;
+      arg = TREE_CHAIN (arg);
+    }
+  while (orig_arg)
+    {
+      TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
+      orig_arg = TREE_CHAIN (orig_arg);
+      arg = TREE_CHAIN (arg);
+    }
+}
+
 /* Complete the method declaration with METHOD_BODY.  */
 
 static void
@@ -5903,6 +5951,9 @@ method_declarator (id, list)
       type = build_array_from_name (type, type_wfl, name, &name);
       EXPR_WFL_NODE (wfl_name) = name;
 
+      if (TREE_CODE (type) == RECORD_TYPE)
+       type = promote_type (type);
+
       /* Check redefinition */
       for (already = arg_types; already; already = TREE_CHAIN (already))
        if (TREE_PURPOSE (already) == name)
@@ -6165,11 +6216,16 @@ safe_layout_class (class)
   tree save_current_class = current_class;
   char *save_input_filename = input_filename;
   int save_lineno = lineno;
-  
+
   push_obstacks (&permanent_obstack, &permanent_obstack);
+
+  if (!CLASS_METHOD_CHECKED_P (class))
+    CHECK_METHODS (TYPE_NAME (class));
+  CLASS_METHOD_CHECKED_P (class) = 1;
+
   layout_class (class);
   pop_obstacks ();
-  
+
   current_class = save_current_class;
   input_filename = save_input_filename;
   lineno = save_lineno;
@@ -6253,6 +6309,8 @@ java_complete_class ()
                  field_type = promote_type (field_type);
                pop_obstacks ();
                TREE_TYPE (field_decl) = field_type;
+               DECL_ALIGN (field_decl) = 0;
+               layout_decl (field_decl, 0);
                SOURCE_FRONTEND_DEBUG 
                  (("Completed field/var decl `%s' with `%s'",
                    IDENTIFIER_POINTER (DECL_NAME (field_decl)),
@@ -6415,7 +6473,6 @@ do_resolve_class (class_type, decl, cl)
 
   /* 2- And check for the type in the current compilation unit. If it fails,
      try with a name qualified with the package name if appropriate. */
-
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     {
       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -6428,6 +6485,8 @@ do_resolve_class (class_type, decl, cl)
   if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
     TYPE_NAME (class_type) = merge_qualified_name (ctxp->package, 
                                                   TYPE_NAME (class_type));
+  if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
+    load_class (TYPE_NAME (class_type), 0);
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     {
       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -6582,9 +6641,7 @@ get_printable_method_name (decl)
   if (DECL_CONSTRUCTOR_P (decl))
     {
       name = DECL_NAME (decl);
-      DECL_NAME (decl) = 
-       DECL_NAME (ctxp->current_parsed_class ? 
-                  ctxp->current_parsed_class : current_class);
+      DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
     }
       
   to_return = lang_printable_name (decl, 0);
@@ -6594,6 +6651,28 @@ get_printable_method_name (decl)
   return to_return;
 }
 
+/* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
+   nevertheless needs to be verfied, 1 otherwise.  */
+
+static int
+reset_method_name (method)
+     tree method;
+{
+  if (DECL_NAME (method) != clinit_identifier_node
+      && DECL_NAME (method) != finit_identifier_node)
+    {
+      /* NAME is just the plain name when Object is being defined */
+      if (DECL_CONTEXT (method) != object_type_node)
+       DECL_NAME (method) = 
+         (DECL_CONSTRUCTOR_P (method) ? init_identifier_node :
+          (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION ? 
+           EXPR_WFL_NODE (DECL_NAME (method)) : DECL_NAME (method)));
+      return 0;
+    }
+  else 
+    return 1;
+}
+
 /* Track method being redefined inside the same class. As a side
    effect, set DECL_NAME to an IDENTIFIER (prior entering this
    function it's a FWL, so we can track errors more accurately */
@@ -6607,19 +6686,14 @@ check_method_redefinition (class, method)
   tree sig = TYPE_LANG_SPECIFIC (TREE_TYPE (method))->signature;
   /* decl name of artificial <clinit> and <finit> doesn't need to be fixed and
      checked */
-  if (DECL_NAME (method) != clinit_identifier_node
-      && DECL_NAME (method) != finit_identifier_node)
-    {
-      /* NAME is just the plain name when Object is being defined */
-      if (class != object_type_node)
-       name = DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
-                                    init_identifier_node :
-                                    EXPR_WFL_NODE (DECL_NAME (method)));
-      else 
-       name = DECL_NAME (method);
-    }
-  else 
+
+  /* Reset the method name before running the check. If it returns 1,
+     the method doesn't need to be verified with respect to method
+     redeclaration and we return 0 */
+  if (reset_method_name (method))
     return 0;
+
+  name = DECL_NAME (method);
   
   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
     {
@@ -6647,20 +6721,26 @@ static void
 java_check_regular_methods (class_decl)
      tree class_decl;
 {
+  int saw_constructor = 0;
   tree method;
   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
   tree super_class = CLASSTYPE_SUPER (class);
-  int saw_constructor = 0;
+  tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
 
   TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
   /* Should take interfaces into account. FIXME */
   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
     {
-      tree found, sig;
+      tree sig;
       tree method_wfl = DECL_NAME (method);
       int aflags;
 
+      /* If we previously found something and its name was saved,
+         reinstall it now */
+      if (found && saved_found_wfl)
+       DECL_NAME (found) = saved_found_wfl;
+
       /* Check for redefinitions */
       if (check_method_redefinition (class, method))
        continue;
@@ -6675,12 +6755,17 @@ java_check_regular_methods (class_decl)
        }
 
       sig = build_java_argument_signature (TREE_TYPE (method));
-
       found = lookup_argument_method (super_class, DECL_NAME (method), sig);
 
-      /* Nothing overrides or it's a private method */
+      /* Nothing overrides or it's a private method. */
       if (!found || (found && METHOD_PRIVATE (found)))
-        continue;
+       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. */
+      saved_found_wfl = DECL_NAME (found);
+      reset_method_name (found);
+
       /* Can't override a method with the same name and different return
         types. */
       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
@@ -6724,19 +6809,27 @@ java_check_regular_methods (class_decl)
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          continue;
        }
-      /* Overriding/hiding public must be public or
-        overriding/hiding protected must be protected or public */
-      if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) ||
-         (METHOD_PROTECTED (found) 
-          && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method))))
+
+      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)
+           access, then the overriding or hiding method must not be
+           private; otherwise, a compile-time error occurs */
+      if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) 
+         || (METHOD_PROTECTED (found) 
+             && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
+         || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
+             && METHOD_PRIVATE (method)))
        {
          parse_error_context 
            (method_wfl,
             "Methods can't be overridden to be more private. Method `%s' is "
-            "%s in class `%s'", lang_printable_name (found, 0),
-            (METHOD_PUBLIC (found) ? "public" : "protected"),
-            IDENTIFIER_POINTER 
-              (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+            "not %s in class `%s'", lang_printable_name (method, 0),
+            (METHOD_PUBLIC (method) ? "public" : 
+             (METHOD_PRIVATE (method) ? "private" : "protected")),
+            IDENTIFIER_POINTER (DECL_NAME 
+                                (TYPE_NAME (DECL_CONTEXT (found)))));
          continue;
        }
 
@@ -6746,9 +6839,10 @@ java_check_regular_methods (class_decl)
 
       /* 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 */
-      aflags = get_access_flags_from_decl (found);
-      if ((!aflags || (aflags > ACC_PROTECTED))
+        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)))
        parse_warning_context 
          (method_wfl, "Method `%s' in class `%s' does not "
@@ -6758,10 +6852,16 @@ java_check_regular_methods (class_decl)
           IDENTIFIER_POINTER (DECL_NAME (class_decl)),
           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
 
-      /* Check on (default) package access. FIXME.  */
       /* Inheriting multiple methods with the same signature. FIXME */
     }
   
+  /* Don't forget eventual pending found and saved_found_wfl. Take
+     into account that we might have exited because we saw an
+     aritifical method as the last entry. */
+
+  if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
+    DECL_NAME (found) = saved_found_wfl;
+
   TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
   if (!saw_constructor)
@@ -6818,11 +6918,12 @@ check_throws_clauses (method, method_wfl, found)
 /* Check abstract method of interface INTERFACE */
 
 static void
-java_check_abstract_methods (interface)
-     tree interface;
+java_check_abstract_methods (interface_decl)
+     tree interface_decl;
 {
   int i, n;
   tree method, basetype_vec, found;
+  tree interface = TREE_TYPE (interface_decl);
 
   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
     {
@@ -6837,16 +6938,20 @@ java_check_abstract_methods (interface)
       found = lookup_java_interface_method2 (interface, method);
       if (found)
        {
-         char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
-                                                0));
+         char *t;
+         tree saved_found_wfl = DECL_NAME (found);
+         reset_method_name (found);
+         t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
          parse_error_context 
            (method_wfl,
-            "Method `%s' was defined with return type `%s' in class `%s ",
+            "Method `%s' was defined with return type `%s' in class `%s'",
             lang_printable_name (found, 0), t,
             IDENTIFIER_POINTER 
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          free (t);
          continue;
+         
+         DECL_NAME (found) = saved_found_wfl;
        }
     }
 
@@ -6868,37 +6973,39 @@ java_check_abstract_methods (interface)
          found = lookup_java_interface_method2 (interface, 
                                                 sub_interface_method);
          if (found && (found != sub_interface_method))
-           parse_error_context 
-             (lookup_cl (sub_interface_method),
-              "Interface `%s' inherits method `%s' from interface `%s'. This "
-              "method is redefined with a different return "
-              "type in interface `%s'",
-              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
-              lang_printable_name (found, 0),
-              IDENTIFIER_POINTER 
-                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (sub_interface_method)))),
-              IDENTIFIER_POINTER 
-                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+           {
+             tree saved_found_wfl = DECL_NAME (found);
+             reset_method_name (found);
+             parse_error_context 
+               (lookup_cl (sub_interface_method),
+                "Interface `%s' inherits method `%s' from interface `%s'. "
+                "This method is redefined with a different return type in "
+                "interface `%s'",
+                IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
+                lang_printable_name (found, 0),
+                IDENTIFIER_POINTER 
+                  (DECL_NAME (TYPE_NAME 
+                              (DECL_CONTEXT (sub_interface_method)))),
+                IDENTIFIER_POINTER 
+                  (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+             DECL_NAME (found) = saved_found_wfl;
+           }
        }
     }
 }
 
-/* Check the method on all the defined classes. Should be done to the
-   classes declared in the compilation unit only. FIXME  */
+/* Check the method on all the defined classes. Process all the
+   classes that we compiled from source code for this CU.  */
 
 void
 java_check_methods ()
 {
   tree current;
-  for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
-    if (CLASS_FROM_SOURCE_P (TREE_TYPE (current)))
+  for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
+    if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
       {
-       tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
-
-       if (CLASS_INTERFACE (TYPE_NAME (class)))
-         java_check_abstract_methods (class);
-       else
-         java_check_regular_methods (current);
+       CHECK_METHODS (TREE_VALUE (current));
+       CLASS_METHOD_CHECKED_P (TREE_TYPE (TREE_VALUE (current))) = 1;
       }
 }
 
@@ -6943,9 +7050,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
      tree clas, method_decl;
      int do_interface;
 {
-  tree method, method_signature, method_name, method_type;
+  tree method, method_signature, method_name, method_type, name;
+
   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
-  method_name = DECL_NAME (method_decl);
+  name = DECL_NAME (method_decl);
+  method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
+                EXPR_WFL_NODE (name) : name);
   method_type = TREE_TYPE (TREE_TYPE (method_decl));
 
   while (clas != NULL_TREE)
@@ -6954,12 +7064,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
           method != NULL_TREE;  method = TREE_CHAIN (method))
        {
          tree method_sig = build_java_argument_signature (TREE_TYPE (method));
-         if (DECL_NAME (method) == method_name 
+         tree name = DECL_NAME (method);
+         if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+              EXPR_WFL_NODE (name) : name) == method_name
              && method_sig == method_signature 
              && TREE_TYPE (TREE_TYPE (method)) != method_type)
-           {
-             return method;
-           }
+           return method;
        }
       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
     }
@@ -7048,8 +7158,6 @@ find_in_imports (class_type)
       {
        TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
        QUALIFIED_P (TYPE_NAME (class_type)) = 1;
-       return check_pkg_class_access (TYPE_NAME (class_type), 
-                                      TREE_PURPOSE (import));
       }
   return 0;
 }
@@ -7273,6 +7381,49 @@ find_in_imports_on_demand (class_type)
     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
 }
 
+static tree
+resolve_package (pkg, next)
+     tree pkg, *next;
+{
+  tree type_name = NULL_TREE;
+  char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
+
+  /* The trick is to determine when the package name stops and were
+     the name of something contained in the package starts. Then we
+     return a fully qualified name of what we want to get. */
+
+  /* Do a quick search on well known package names */
+  if (!strncmp (name, "java.lang.reflect", 17))
+    {
+      *next = 
+       TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
+      type_name = lookup_package_type (name, 17);
+    }
+  else if (!strncmp (name, "java.lang", 9))
+    {
+      *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
+      type_name = lookup_package_type (name, 9);
+    }
+  else
+    return NULL_TREE;          /* FIXME, search all imported packages. */
+
+  return type_name;
+}
+
+static tree
+lookup_package_type (name, from)
+     char *name;
+     int from;
+{
+  char subname [128];
+  char *sub = &name[from+1];
+  while (*sub != '.' && *sub)
+    sub++;
+  strncpy (subname, name, sub-name);
+  subname [sub-name] = '\0';
+  return get_identifier (subname);
+}
+
 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
    access violations were found, 1 otherwise.  */
 
@@ -7619,16 +7770,21 @@ add_stmt_to_compound (existing, type, stmt)
 /* Hold THIS for the scope of the current public method decl.  */
 static tree current_this;
 
-/* Layout all class found during parsing. Also fixes the order of
-   several field related lists. */
+/* Layout all class found during parsing. Also fixes the order of some
+   lists.  */
 
 void
 java_layout_classes ()
 {
   tree current;
-  for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
+
+  java_check_methods ();
+  /* Error reported by the caller */
+  if (java_error_count)
+    return;
+  for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
     {
-      current_class = TREE_TYPE (current);
+      current_class = TREE_TYPE (TREE_VALUE (current));
 
       /* Reverse the fields if it's necessary (they've already
          reversed if the dummy field has been inserted at the
@@ -7640,6 +7796,10 @@ java_layout_classes ()
       /* Do a layout if necessary */
       if (!TYPE_SIZE (current_class) || (current_class == object_type_node))
        safe_layout_class (current_class);
+
+      /* Error reported by the caller */
+      if (java_error_count)
+       return;
     }
 }
 
@@ -7678,7 +7838,9 @@ java_complete_expand_methods ()
                    restore_line_number_status (0);
                  }
              }
-           else
+           else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
+             continue;
+           else 
              java_complete_expand_method (decl);
          }
 
@@ -7733,6 +7895,7 @@ java_complete_expand_method (mdecl)
 
       if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)))
        java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)));
+
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -7892,6 +8055,13 @@ java_expand_finals ()
 void
 java_expand_classes ()
 {
+  ctxp = ctxp_for_generation;
+  /* If we found error earlier, we don't want to report then twice. */
+  if (java_error_count || !ctxp)
+    return;
+  java_layout_classes ();
+  java_parse_abort_on_error ();
+
   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
     {
       ctxp = ctxp_for_generation;
@@ -8023,8 +8193,9 @@ cut_identifier_in_qualified (wfl)
 /* Resolve the expression name NAME. Return its decl.  */
 
 static tree
-resolve_expression_name (id)
+resolve_expression_name (id, orig)
      tree id;
+     tree *orig;
 {
   tree name = EXPR_WFL_NODE (id);
   tree decl;
@@ -8043,6 +8214,7 @@ resolve_expression_name (id)
          decl = lookup_field_wrapper (current_class, name);
          if (decl)
            {
+             tree value = NULL_TREE;
              int fs = FIELD_STATIC (decl);
              /* Instance variable (8.3.1.1) can't appear within
                 static method, static initializer or initializer for
@@ -8066,9 +8238,20 @@ resolve_expression_name (id)
                     "constructor has been called", IDENTIFIER_POINTER (name));
                  return error_mark_node;
                }
+             /* The field is final. We may use its value instead */
+             if (fs && FIELD_FINAL (decl))
+               value = java_complete_tree (DECL_LOCAL_STATIC_VALUE (decl));
+
+             /* Otherwise build what it takes to access the field */
              decl = build_field_ref ((fs ? NULL_TREE : current_this),
                                      current_class, name);
-             return (fs ? build_class_init (current_class, decl) : decl);
+             if (fs && !flag_emit_class_files)
+               decl = build_class_init (current_class, decl);
+             /* We may be asked to save the real field access node */
+             if (orig)
+               *orig = decl;
+             /* And we return what we got */
+             return (value ? value : decl);
            }
          /* Fall down to error report on undefined variable */
        }
@@ -8076,6 +8259,8 @@ resolve_expression_name (id)
   /* 6.5.5.2 Qualified Expression Names */
   else
     {
+      if (orig)
+       *orig = NULL_TREE;
       qualify_ambiguous_name (id);
       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
       /* 15.10.2: Accessing Superclass Members using super */
@@ -8121,12 +8306,24 @@ resolve_field_access (qual_wfl, field_decl, field_type)
     field_ref = decl;
   else if (DECL_P (decl))
     {
+      int static_final_found = 0;
+      if (!type_found)
+       type_found = DECL_CONTEXT (decl);
       is_static = DECL_P (decl) && FIELD_STATIC (decl);
-      field_ref = build_field_ref ((is_static ? NULL_TREE : where_found), 
-                                  type_found, DECL_NAME (decl));
+      if (FIELD_FINAL (decl) 
+         && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
+         && DECL_LANG_SPECIFIC (decl)
+         && DECL_LOCAL_STATIC_VALUE (decl))
+       {
+         field_ref = java_complete_tree (DECL_LOCAL_STATIC_VALUE (decl));
+         static_final_found = 1;
+       }
+      else
+       field_ref = build_field_ref ((is_static ? NULL_TREE : where_found), 
+                                    type_found, DECL_NAME (decl));
       if (field_ref == error_mark_node)
        return error_mark_node;
-      if (is_static)
+      if (is_static && !static_final_found)
        {
          field_ref = build_class_init (type_found, field_ref);
          /* If the static field was identified by an expression that
@@ -8169,7 +8366,6 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
       tree qual_wfl = QUAL_WFL (q);
 
       /* 15.10.1 Field Access Using a Primary */
-      
       switch (TREE_CODE (qual_wfl))
        {
        case CALL_EXPR:
@@ -8217,6 +8413,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          continue;
 
        case CONDITIONAL_EXPR:
+       case STRING_CST:
          *where_found = decl = java_complete_tree (qual_wfl);
          if (decl == error_mark_node)
            return 1;
@@ -8258,7 +8455,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
            }
          /* We have to generate code for intermediate acess */
          *where_found = decl = current_this;
-         type = QUAL_DECL_TYPE (decl);
+         *type_found = type = QUAL_DECL_TYPE (decl);
          continue;
        }
 
@@ -8290,17 +8487,33 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
         assume a variable/class name was meant. */
       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
        {
-         if (from_super || from_cast)
-           parse_error_context 
-             ((from_cast ? qual_wfl : wfl),
-              "No variable `%s' defined in class `%s'",
-              IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
-              lang_printable_name (type, 0));
+         tree name = resolve_package (wfl, &q);
+         if (name)
+           {
+             *where_found = decl = resolve_no_layout (name, qual_wfl);
+             /* We wan't to be absolutely that the class is laid
+                 out. We're going to search something inside it. */
+             *type_found = type = TREE_TYPE (decl);
+             layout_class (type);
+             from_type = 1;
+             /* Should be a list, really. FIXME */
+             RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
+             RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
+           }
          else
-           parse_error_context
-             (qual_wfl, "Undefined variable or class name: `%s'",
-              IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
-         return 1;
+           {
+             if (from_super || from_cast)
+               parse_error_context 
+                 ((from_cast ? qual_wfl : wfl),
+                  "No variable `%s' defined in class `%s'",
+                  IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
+                  lang_printable_name (type, 0));
+             else
+               parse_error_context
+                 (qual_wfl, "Undefined variable or class name: `%s'",
+                  IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
+             return 1;
+           }
        }
 
       /* We have a type name. It's been already resolved when the
@@ -8320,6 +8533,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
              return 1;
            }
+         check_deprecation (qual_wfl, decl);
          
          type = TREE_TYPE (decl);
          from_type = 1;
@@ -8336,18 +8550,24 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          if (!from_super && QUAL_RESOLUTION (q))
            {
              decl = QUAL_RESOLUTION (q);
-             *type_found = type;
+             if (!type && !FIELD_STATIC (decl))
+               {
+                 *where_found = current_this;
+                 *type_found = type;
+               }
            }
 
          /* We have to search for a field, knowing the type of its
              container. The flag FROM_TYPE indicates that we resolved
              the last member of the expression as a type name, which
-             means that for the resolution of this field, will check
-             on other errors than if the it was resolved as a member
-             of an other field. */
+             means that for the resolution of this field, we'll look
+             for other errors than if it was resolved as a member of
+             an other field. */
          else
            {
              int is_static;
+             tree field_decl_type; /* For layout */
+
              if (!from_type && !JREFERENCE_TYPE_P (type))
                {
                  parse_error_context 
@@ -8367,6 +8587,17 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
                  return 1;
                }
+
+             /* Layout the type of field_decl, since we may need
+                 it. Don't do primitive types or loaded classes */
+             if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
+               field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
+             else
+               field_decl_type = TREE_TYPE (field_decl);
+             if (!JPRIMITIVE_TYPE_P (field_decl_type) 
+                 && !CLASS_LOADED_P (field_decl_type))
+               resolve_and_layout (DECL_NAME (TYPE_NAME (field_decl_type)),
+                                   NULL_TREE);
              
              /* Check on accessibility here */
              if (not_accessible_p (type, field_decl, from_super))
@@ -8382,6 +8613,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                       (DECL_NAME (TYPE_NAME (current_class))));
                  return 1;
                }
+             check_deprecation (qual_wfl, field_decl);
              
              /* There are things to check when fields are accessed
                 from type. There are no restrictions on a static
@@ -8400,8 +8632,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                }
              from_cast = from_super = 0;
 
-             /* If we need to generate something to get a proper handle
-                on what this field is accessed from, do it now. */
+             /* If we need to generate something to get a proper
+                handle on what this field is accessed from, do it
+                now. */
              if (!is_static)
                {
                  decl = maybe_access_field (decl, *where_found, *type_found);
@@ -8487,6 +8720,40 @@ int not_accessible_p (reference, member, from_super)
   return 0;
 }
 
+/* Test deprecated decl access.  */
+static void
+check_deprecation (wfl, decl)
+     tree wfl, decl;
+{
+  char *file = DECL_SOURCE_FILE (decl);
+  /* Complain if the field is deprecated and the file it was defined
+     in isn't compiled at the same time the file which contains its
+     use is */
+  if (DECL_DEPRECATED (decl) 
+      && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
+    {
+      char the [20];
+      switch (TREE_CODE (decl))
+       {
+       case FUNCTION_DECL:
+         strcpy (the, "method");
+         break;
+       case FIELD_DECL:
+         strcpy (the, "field");
+         break;
+       case TYPE_DECL:
+         strcpy (the, "class");
+         break;
+       default:
+         fatal ("unexpected DECL code - check_deprecation");
+       }
+      parse_warning_context 
+       (wfl, "The %s `%s' in class `%s' has been deprecated", 
+        the, lang_printable_name (decl, 0),
+        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
+    }
+}
+
 /* Returns 1 if class was declared in the current package, 0 otherwise */
 
 static int
@@ -8531,10 +8798,8 @@ static tree
 maybe_access_field (decl, where, type)
   tree decl, where, type;
 {
-  if (DECL_P (decl) && decl != current_this
-      && (!(TREE_CODE (decl) != PARM_DECL
-           && FIELD_STATIC (decl)))
-      && !IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
+  if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
+      && !FIELD_STATIC (decl))
     decl = build_field_ref (where ? where : current_this, 
                            (type ? type : DECL_CONTEXT (decl)),
                            DECL_NAME (decl));
@@ -8555,7 +8820,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
   tree wfl = TREE_OPERAND (patch, 0);
   tree args = TREE_OPERAND (patch, 1);
   tree name = EXPR_WFL_NODE (wfl);
-  tree list, class_type;
+  tree list;
   int is_static_flag = 0;
   
   /* Should be overriden if everything goes well. Otherwise, if
@@ -8626,6 +8891,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
              free (fct_name);
              PATCH_METHOD_RETURN_ERROR ();
            }
+         args = nreverse (args);
        }
       /* We're resolving an expression name */
       else
@@ -8651,9 +8917,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
          args = tree_cons (NULL_TREE, field, nreverse (args));
        }
 
-      /* CLASS_TYPE is used during the call to not_accessible_p and
-        IDENTIFIER_WFL will be used to report any problem further */
-      class_type = TREE_TYPE (class_decl);
+      /* IDENTIFIER_WFL will be used to report any problem further */
       wfl = identifier_wfl;
     }
   /* Resolution of simple names, names generated after a primary: or
@@ -8697,8 +8961,11 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
                  PATCH_METHOD_RETURN_ERROR ();
                }
              
-             /* Can't instantiate an abstract class */
-             if (CLASS_ABSTRACT (class_to_search))
+             /* Can't instantiate an abstract class, but we can
+                invoke it's constructor. It's use within the `new'
+                context is denied here. */
+             if (CLASS_ABSTRACT (class_to_search) 
+                 && TREE_CODE (patch) == NEW_CLASS_EXPR)
                {
                  parse_error_context 
                    (wfl, "Class `%s' is an abstract class. It can't be "
@@ -8741,8 +9008,6 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
       args = nreverse (args);
       if (!METHOD_STATIC (list) && TREE_CODE (patch) != NEW_CLASS_EXPR)
        args = tree_cons (NULL_TREE, primary ? primary : current_this, args);
-
-      class_type = class_to_search;
     }
 
   /* Merge point of all resolution schemes. If we have nothing, this
@@ -8752,18 +9017,19 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
 
   /* Check accessibility, position the is_static flag, build and
      return the call */
-  if (not_accessible_p (class_type, list, 0))
+  if (not_accessible_p (DECL_CONTEXT (list), list, 0))
     {
       char *fct_name = strdup (lang_printable_name (list, 0));
       parse_error_context 
        (wfl, "Can't access %s method `%s %s.%s' from `%s'",
         java_accstring_lookup (get_access_flags_from_decl (list)),
         lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
-        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))), fct_name,
-        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
+        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
+        fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
       free (fct_name);
       PATCH_METHOD_RETURN_ERROR ();
     }
+  check_deprecation (wfl, list);
 
   is_static_flag = METHOD_STATIC (list);
 
@@ -8821,9 +9087,14 @@ patch_invoke (patch, method, args, from_super)
   tree signature = build_java_signature (TREE_TYPE (method));
   tree original_call, t, ta;
 
-  /* Last step for args: convert build-in types. */
-  for (t = TYPE_ARG_TYPES (TREE_TYPE (method)), ta = args;
-       t && ta; t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
+  /* Last step for args: convert build-in types. If we're dealing with
+     a new TYPE() type call, the first argument to the constructor
+     isn't found in the incomming argument list, but delivered by
+     `new' */
+  t = TYPE_ARG_TYPES (TREE_TYPE (method));
+  if (TREE_CODE (patch) == NEW_CLASS_EXPR)
+    t = TREE_CHAIN (t);
+  for (ta = args; t && ta; t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
        TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
@@ -8841,6 +9112,11 @@ patch_invoke (patch, method, args, from_super)
                                     DECL_CONTEXT (method), signature, args);
       break;
 
+    case INVOKE_INTERFACE:
+      dtable = invoke_build_dtable (1, args);
+      func = build_invokeinterface (dtable, DECL_NAME (method), signature);
+      break;
+
     default:
       fatal ("Unknown invocation mode `%d' - build_invoke", im);
       return NULL_TREE;
@@ -8916,34 +9192,24 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
      tree class, name, arg_list;
 {
   tree method = make_node (FUNCTION_TYPE);
-  tree arg_type_list = NULL_TREE;
+  tree atl = NULL_TREE;                /* Arg Type List */
   tree signature, list, node;
   char *candidates;            /* Used for error report */
 
+  /* Fix the arguments */
   for (node = arg_list; node; node = TREE_CHAIN (node))
     {
       tree current_arg = TREE_TYPE (TREE_VALUE (node));
       if (TREE_CODE (current_arg) == RECORD_TYPE)
        current_arg = promote_type (current_arg);
-      arg_type_list = tree_cons (NULL_TREE, current_arg, arg_type_list);
-    }
-  TYPE_ARG_TYPES (method) = arg_type_list;
-
-  if (!lc)
-    {
-      list = find_applicable_accessible_methods_list (class, name, 
-                                                     arg_type_list);
-      list = find_most_specific_methods_list (list);
-    }
-  else
-    {
-      TREE_TYPE (method) = void_type_node;
-      signature = build_java_signature (method);
-      list = lookup_java_constructor (class, signature);
+      atl = tree_cons (NULL_TREE, current_arg, atl);
     }
+  TYPE_ARG_TYPES (method) = atl;
 
-  if (lc && list)
-    return list;
+  /* Find all candidates and then refine the list, searching for the
+     most specific method. */
+  list = find_applicable_accessible_methods_list (lc, class, name, atl);
+  list = find_most_specific_methods_list (list);
   if (list && !TREE_CHAIN (list))
     return TREE_VALUE (list);
 
@@ -8984,10 +9250,12 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
   return NULL_TREE;
 }
 
-/* 15.11.2.1: Find Methods that are Applicable and Accessible */
+/* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
+   when we're looking for a constructor. */
 
 static tree
-find_applicable_accessible_methods_list (class, name, arglist)
+find_applicable_accessible_methods_list (lc, class, name, arglist)
+     int lc;
      tree class, name, arglist;
 {
   tree method;
@@ -8998,10 +9266,12 @@ find_applicable_accessible_methods_list (class, name, arglist)
       for (method = TYPE_METHODS (class);
           method != NULL_TREE;  method = TREE_CHAIN (method))
        {
-         /* Names have to match and we're not looking for constructor */
-         if (DECL_NAME (method) != name || DECL_CONSTRUCTOR_P (method))
+         if (lc && !DECL_CONSTRUCTOR_P (method))
            continue;
-
+         else if (!lc && (DECL_CONSTRUCTOR_P (method)
+                          || DECL_NAME (method) != name))
+           continue;
+         
          if (argument_types_convertible (method, arglist))
            {
              /* Retain accessible methods only */
@@ -9012,7 +9282,9 @@ find_applicable_accessible_methods_list (class, name, arglist)
                all_list = tree_cons (NULL_TREE, method, list);
            }
        }
-      class = CLASSTYPE_SUPER (class);
+      /* When dealing with constructor, stop here, otherwise search
+         other classes */
+      class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
     }
   /* Either return the list obtained or all selected (but
      inaccessible) methods for better error report. */
@@ -9196,8 +9468,9 @@ 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 ?: up front */
-    if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR)
+    /* Loop one more time if we're dealing with ?: or a string constant */
+    if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
+       || TREE_CODE (qual_wfl) == STRING_CST)
       {
        qual = TREE_CHAIN (qual);
        qual_wfl = QUAL_WFL (qual);
@@ -9307,8 +9580,10 @@ not_initialized_as_it_should_p (decl)
 {
   if (DECL_P (decl))
     {
-      if (TREE_CODE (decl) == FIELD_DECL
-         && METHOD_STATIC (current_function_decl))
+      if (FIELD_FINAL (decl))
+       return 0;
+      if (TREE_CODE (decl) == FIELD_DECL 
+         && (METHOD_STATIC (current_function_decl)))
        return 0;
       return DECL_P (decl) && !INITIALIZED_P (decl);
     }
@@ -9458,7 +9733,7 @@ java_complete_tree (node)
     case EXPR_WITH_FILE_LOCATION:
       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
          || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
-        return resolve_expression_name (node);
+        return resolve_expression_name (node, NULL);
       else
        {
          EXPR_WFL_NODE (node) = java_complete_tree (EXPR_WFL_NODE (node));
@@ -9556,7 +9831,8 @@ java_complete_tree (node)
             an error during the assignment. In any cases, the
             assignment operation fails. */
          if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
-             && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
+             && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node
+             && TREE_TYPE (TREE_OPERAND (node, 1)))
            patch_assignment (node, wfl_op1, wfl_op2);
 
          /* Now, we still mark the lhs as initialized */
@@ -9613,6 +9889,11 @@ java_complete_tree (node)
        }
       return patch_binop (node, wfl_op1, wfl_op2);
 
+    case INSTANCEOF_EXPR:
+      wfl_op1 = TREE_OPERAND (node, 0);
+      COMPLETE_CHECK_OP_0 (node);
+      return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
+
     case UNARY_PLUS_EXPR:
     case NEGATE_EXPR:
     case TRUTH_NOT_EXPR:
@@ -9706,8 +9987,10 @@ complete_function_arguments (node)
         `+' operator. Build `parm.toString()' and expand it. */
       if ((temp = patch_string (parm)))
        parm = temp;
-      TREE_VALUE (cn) = parm;
+      /* Inline PRIMTYPE.TYPE read access */
+      parm = maybe_build_primttype_type_ref (parm, wfl);
 
+      TREE_VALUE (cn) = parm;
       if (not_initialized_as_it_should_p (parm))
        {
          ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
@@ -9948,6 +10231,47 @@ print_int_node (node)
   return buffer;
 }
 
+/* Return 1 if you an assignment of a FINAL is attempted */
+
+static int
+check_final_assignment (lvalue, wfl)
+     tree lvalue, wfl;
+{
+  if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
+    {
+      parse_error_context 
+        (wfl, "Can't assign a value to the final variable `%s'",
+        IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+      return 1;
+    }
+  return 0;
+}
+
+/* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
+   read. This is needed to avoid circularities in the implementation
+   of these fields in libjava. */
+
+static tree
+maybe_build_primttype_type_ref (rhs, wfl)
+    tree rhs, wfl;
+{
+  tree to_return = NULL_TREE;
+  tree rhs_type = TREE_TYPE (rhs);
+  if (TREE_CODE (rhs) == COMPOUND_EXPR)
+    {
+      tree n = TREE_OPERAND (rhs, 1);
+      if (TREE_CODE (n) == VAR_DECL 
+         && DECL_NAME (n) == TYPE_identifier_node
+         && rhs_type == class_ptr_type)
+       {
+         char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
+         if (!strncmp (self_name, "java.lang.", 10))
+           to_return = build_primtype_type_ref (self_name);
+       }
+    }
+  return (to_return ? to_return : rhs );
+}
+
 /* 15.25 Assignment operators. */
 
 static tree
@@ -9957,19 +10281,14 @@ patch_assignment (node, wfl_op1, wfl_op2)
      tree wfl_op2;
 {
   tree rhs = TREE_OPERAND (node, 1);
-  tree lvalue = TREE_OPERAND (node, 0);
+  tree lvalue = TREE_OPERAND (node, 0), llvalue;
   tree lhs_type, rhs_type, new_rhs = NULL_TREE;
   int error_found = 0;
   int lvalue_from_array = 0;
 
   /* Can't assign to a final. */
-  if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
-    {
-      parse_error_context 
-        (wfl_op1, "Can't assign a value to the final variable `%s'",
-        IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op1)));
-      error_found = 1;
-    }
+  if (check_final_assignment (lvalue, wfl_op1))
+    error_found = 1;
 
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
 
@@ -9992,8 +10311,18 @@ patch_assignment (node, wfl_op1, wfl_op2)
   /* Or a function return slot */
   else if (TREE_CODE (lvalue) == RESULT_DECL)
     lhs_type = TREE_TYPE (lvalue);
-  /* Otherwise, this is an error */
-  else
+  /* 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))
+    {
+      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;
+    }
+  else 
     {
       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
       error_found = 1;
@@ -10060,6 +10389,22 @@ patch_assignment (node, wfl_op1, wfl_op2)
       INITIALIZED_P (rhs) = 1;
     }
 
+  /* Inline read access to java.lang.PRIMTYPE.TYPE */
+  rhs = maybe_build_primttype_type_ref (rhs, wfl_op2);
+
+  if (TREE_CODE (rhs) == COMPOUND_EXPR)
+    {
+      tree n = TREE_OPERAND (rhs, 1);
+      if (TREE_CODE (n) == VAR_DECL 
+         && DECL_NAME (n) == TYPE_identifier_node
+         && rhs_type == class_ptr_type)
+       {
+         char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op2));
+         if (!strncmp (self_name, "java.lang.", 10))
+           rhs = build_primtype_type_ref (self_name);
+       }
+    }
+
   if (error_found)
     return error_mark_node;
 
@@ -10113,9 +10458,15 @@ try_builtin_assignconv (wfl_op1, lhs_type, rhs)
   tree new_rhs = NULL_TREE;
   tree rhs_type = TREE_TYPE (rhs);
 
+  /* Zero accepted everywhere */
+  if (TREE_CODE (rhs) == INTEGER_CST 
+      && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
+      && JPRIMITIVE_TYPE_P (rhs_type))
+    new_rhs = convert (lhs_type, rhs);
+
   /* 5.1.1 Try Identity Conversion,
      5.1.2 Try Widening Primitive Conversion */
-  if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
+  else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
     new_rhs = convert (lhs_type, rhs);
 
   /* Try a narrowing primitive conversion (5.1.3): 
@@ -10150,20 +10501,32 @@ static int
 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
      tree lhs_type, rhs_type;
 {
-  int all_primitive = 
+  int all_primitive;
+
+  if (lhs_type == rhs_type)
+    return 1;
+
+  all_primitive = 
     JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
 
   if (!all_primitive)
     return 0;
 
-  if (lhs_type == rhs_type)
-    return 1;
-
   /* 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;
 
+  /* Accept all promoted type here. Note, we can't use <= in the test
+     below, because we still need to bounce out assignments of short
+     to char and the likes */
+  if (lhs_type == int_type_node
+      && (rhs_type == promoted_byte_type_node
+         || rhs_type == promoted_short_type_node
+         || rhs_type == promoted_char_type_node
+         || 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) &&
@@ -10188,6 +10551,8 @@ valid_ref_assignconv_cast_p (source, dest, cast)
      tree dest;
      int cast;
 {
+  if (JNULLP_TYPE_P (source))
+    return 1;
   if (TREE_CODE (source) == POINTER_TYPE)
     source = TREE_TYPE (source);
   if (TREE_CODE (dest) == POINTER_TYPE)
@@ -10313,8 +10678,8 @@ valid_method_invocation_conversion_p (dest, source)
   return ((JPRIMITIVE_TYPE_P (source) 
            && JPRIMITIVE_TYPE_P (dest)
            && valid_builtin_assignconv_identity_widening_p (dest, source))
-          || (JREFERENCE_TYPE_P (source) 
-              && JREFERENCE_TYPE_P (dest)
+          || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
+              && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
               && valid_ref_assignconv_cast_p (source, dest, 0)));
 }
 
@@ -10326,9 +10691,7 @@ build_binop (op, op_location, op1, op2)
      int op_location;
      tree op1, op2;
 {
-  tree binop;
-
-  binop = build (op, NULL_TREE, op1, op2);
+  tree binop = build (op, NULL_TREE, op1, op2);
   TREE_SIDE_EFFECTS (binop) = 1;
   /* Store the location of the operator, for better error report. The
      string of the operator will be rebuild based on the OP value. */
@@ -10533,7 +10896,63 @@ patch_binop (node, wfl_op1, wfl_op2)
          TREE_SET_CODE (node, RSHIFT_EXPR);
        }
       break;
+
+      /* 15.19.1 Type Comparison Operator instaceof */
+    case INSTANCEOF_EXPR:
+
+      TREE_TYPE (node) = boolean_type_node;
+
+      if (!(op2_type = resolve_type_during_patch (op2)))
+       return error_mark_node;
+
+      /* The first operand must be a reference type or the null type */
+      if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
+       error_found = 1;        /* Error reported further below */
+
+      /* The second operand must be a reference type */
+      if (!JREFERENCE_TYPE_P (op2_type))
+       {
+         SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+         parse_error_context
+           (wfl_operator, "Invalid argument `%s' for `instanceof'",
+            lang_printable_name (op2_type, 0));
+         error_found = 1;
+       }
+
+      if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
+       {
+         /* If the first operand is null, the result is always false */
+         if (op1 == null_pointer_node)
+           return boolean_false_node;
+         /* Otherwise we have to invoke instance of to figure it out */
+         else
+           {
+             tree call =
+               build (CALL_EXPR, boolean_type_node,
+                      build_address_of (soft_instanceof_node),
+                      tree_cons 
+                      (NULL_TREE, op1,
+                       build_tree_list (NULL_TREE,
+                                        build_class_ref (op2_type))),
+                      NULL_TREE);
+             TREE_SIDE_EFFECTS (call) = 1;
+             return call;
+           }
+       }
+      /* There is no way the expression operand can be an instance of
+        the type operand. This is a compile time error. */
+      else
+       {
+         char *t1 = strdup (lang_printable_name (op1_type, 0));
+         SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+         parse_error_context 
+           (wfl_operator, "Impossible for `%s' to be instance of `%s'",
+            t1, lang_printable_name (op2_type, 0));
+         free (t1);
+         error_found = 1;
+       }
       
+      break;
 
       /* 15.21 Bitwise and Logical Operators */
     case BIT_AND_EXPR:
@@ -10609,7 +11028,7 @@ patch_binop (node, wfl_op1, wfl_op2)
     case NE_EXPR:
       /* 15.20.1 Numerical Equality Operators == and != */
       /* Binary numeric promotion is performed on the operands */
-      if (JPRIMITIVE_TYPE_P (op1_type) && JPRIMITIVE_TYPE_P (op2_type))
+      if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
        binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
       
       /* 15.20.2 Boolean Equality Operators == and != */
@@ -10618,10 +11037,14 @@ patch_binop (node, wfl_op1, wfl_op2)
        ;                       /* Nothing to do here */
       
       /* 15.20.3 Reference Equality Operators == and != */
-      /* Types have to be either references or the null type */
+      /* Types have to be either references or the null type. If
+         they're references, it must be possible to convert either
+         type to the other by casting conversion. */
       else if (op1 == null_pointer_node || op2 == null_pointer_node 
               || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
-                  && ((op1_type == op2_type))))
+                  && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
+                      || valid_ref_assignconv_cast_p (op2_type, 
+                                                      op1_type, 1))))
        ;                       /* Nothing to do here */
          
       /* Else we have an error figure what can't be converted into
@@ -10942,22 +11365,25 @@ 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 
+      if (!DECL_P (op) && !((TREE_CODE (op) == INDIRECT_REF 
+                            || TREE_CODE (op) == COMPONENT_REF) 
                            && JPRIMITIVE_TYPE_P (TREE_TYPE (op))))
        {
-         parse_error_context (wfl_operator, "Invalid argument to `%s'",
-                              operator_string (node));
-         TREE_TYPE (node) = error_mark_node;
-         error_found = 1;
-       }
-      else if (DECL_P (op) && FIELD_FINAL (op))
-       {
-         parse_error_context 
-           (wfl_op, "Can't assign a value to the final variable `%s'",
-            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op)));
+         tree lvalue;
+         /* Before screaming, check that we're not in fact trying to
+            increment a optimized static final access, in which case
+            we issue an different error message. */
+         if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
+               && resolve_expression_name (wfl_op, &lvalue)
+               && check_final_assignment (lvalue, wfl_op)))
+           parse_error_context (wfl_operator, "Invalid argument to `%s'",
+                                operator_string (node));
          TREE_TYPE (node) = error_mark_node;
          error_found = 1;
        }
+      else if (check_final_assignment (op, wfl_op))
+       error_found = 1;
+
       /* From now on, we know that op if a variable and that it has a
          valid wfl. We use wfl_op to locate errors related to the
          ++/-- operand. */
@@ -11078,7 +11504,10 @@ resolve_type_during_patch (type)
          return NULL_TREE;
        }
       else
-       return TREE_TYPE (type_decl);
+       {
+         CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
+         return TREE_TYPE (type_decl);
+       }
     }
   return type;
 }
@@ -11113,6 +11542,10 @@ patch_cast (node, wfl_operator)
       return convert (cast_type, op);
     }
 
+  /* null can be casted to references */
+  if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
+    return build_null_of_type (cast_type);
+
   /* 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) 
@@ -11142,6 +11575,17 @@ patch_cast (node, wfl_operator)
   return error_mark_node;
 }
 
+/* Build a null constant and give it the type TYPE.  */
+
+static tree
+build_null_of_type (type)
+     tree type;
+{
+  tree node = build_int_2 (0, 0);
+  TREE_TYPE (node) = promote_type (type);
+  return node;
+}
+
 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
    a list of indices. */
 static tree
@@ -11215,8 +11659,11 @@ patch_array_ref (node, wfl_array, wfl_index)
     return error_mark_node;
   index = convert (promoted_index_type, index);
 
-  if (TREE_CODE (array_type) == RECORD_TYPE)
-    array_type = promote_type (TYPE_ARRAY_ELEMENT (array_type));
+  array_type = TYPE_ARRAY_ELEMENT (array_type);
+  if (TREE_CODE (array_type) == RECORD_TYPE 
+      && !JPRIMITIVE_TYPE_P (TREE_TYPE (array_type)))
+    array_type = promote_type (array_type);
+
   if (flag_emit_class_files)
     {
       TREE_OPERAND (node, 0)= array;
@@ -11402,7 +11849,6 @@ patch_return (node)
   tree return_exp = TREE_OPERAND (node, 0);
   tree meth = current_function_decl;
   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
-  tree modify;
   int error_found = 0;
 
   TREE_TYPE (node) = error_mark_node;
@@ -11436,12 +11882,33 @@ patch_return (node)
       return error_mark_node;
     }
 
-  /* If we have a return_exp, build a modify expression and expand it */
+  /* If we have a return_exp, build a modify expression and expand
+     it. Note: at that point, the assignment is declared valid, but we
+     may want to carry some more hacks */
   if (return_exp)
     {
-      modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), return_exp);
+      tree exp = java_complete_tree (return_exp);
+      tree modify, patched;
+
+      /* If the function returned value and EXP are booleans, EXP has
+      to be converted into the type of DECL_RESULT, which is integer
+      (see complete_start_java_method) */
+      if (TREE_TYPE (exp) == boolean_type_node &&
+         TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
+       exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
+
+      /* `null' can be assigned to a function returning a reference */
+      if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
+         exp == null_pointer_node)
+       exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
+
+      if ((patched = patch_string (exp)))
+       exp = patched;
+      
+      modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
       modify = java_complete_tree (modify);
+
       if (modify != error_mark_node)
        {
          TREE_SIDE_EFFECTS (modify) = 1;
index bb9477a..7f783dc 100644 (file)
@@ -47,7 +47,7 @@ extern tree stabilize_reference PROTO ((tree));
 #define RULE( rule )
 #endif
 
-#ifdef SOURCE_FRONTEND_DEBUG
+#ifdef VERBOSE_SKELETON
 #undef SOURCE_FRONTEND_DEBUG
 #define SOURCE_FRONTEND_DEBUG(X)                               \
   {if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
@@ -182,6 +182,8 @@ extern tree stabilize_reference PROTO ((tree));
                                     || (TREE_CODE (TYPE) == POINTER_TYPE     \
                                         &&  TREE_CODE (TREE_TYPE (TYPE)) ==  \
                                         RECORD_TYPE)))
+#define JNULLP_TYPE_P(TYPE) ((TYPE) && (TREE_CODE (TYPE) == POINTER_TYPE) \
+                            && (TYPE) == TREE_TYPE (null_pointer_node))
 
 /* Other predicate */
 #define DECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL           \
@@ -523,6 +525,32 @@ static jdeplist *reverse_jdep_list ();
       *ret_decl = NULL_TREE;                   \
     return error_mark_node;                    \
   }
+
+/* Convenient macro to check. Assumes that CLASS is a CLASS_DECL.  */
+#define CHECK_METHODS(CLASS)                   \
+  {                                            \
+    if (CLASS_INTERFACE ((CLASS)))             \
+      java_check_abstract_methods ((CLASS));   \
+    else                                       \
+      java_check_regular_methods ((CLASS));    \
+  }
+
+/* Using and reseting the @deprecated tag flag */
+#define CHECK_DEPRECATED(DECL)                 \
+  {                                            \
+    if (ctxp->deprecated)                      \
+      DECL_DEPRECATED (DECL) = 1;              \
+    ctxp->deprecated = 0;                      \
+  }
+
+/* Register an impor */
+#define REGISTER_IMPORT(WHOLE, NAME)                   \
+{                                                      \
+  IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P ((NAME)) = 1;    \
+  node = build_tree_list ((WHOLE), (NAME));            \
+  TREE_CHAIN (node) = ctxp->import_list;               \
+  ctxp->import_list = node;                            \
+}
      
 /* Parser context data structure. */
 struct parser_ctxt {
@@ -542,6 +570,7 @@ struct parser_ctxt {
   int minus_seen;                   /* Integral literal overflow */
   int lineno;                      /* Current lineno */
   int java_error_flag;             /* Report error when true */
+  int deprecated;                   /* @deprecated tag seen */
 
   /* This section is defined only if we compile jc1 */
 #ifndef JC1_LITE
@@ -561,7 +590,9 @@ struct parser_ctxt {
 
   tree  incomplete_class;          /* List of non-complete classes */
   tree  current_parsed_class;      /* Class currently parsed */
+  tree  current_parsed_class_un;    /* Curr. parsed class unqualified name */
   tree  class_list;                /* List of classes in a CU */
+  tree  gclass_list;               /* All classes seen so far. */
   jdeplist *classd_list;           /* Classe dependencies in a CU */
   
   tree non_static_initialized;     /* List of non static initialized fields */
@@ -604,9 +635,11 @@ static void check_modifiers_consistency PROTO ((int));
 static tree lookup_cl PROTO ((tree));
 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_error_context VPROTO ((tree cl, char *msg, ...));
 static void parse_warning_context VPROTO ((tree cl, char *msg, ...));
+static void issue_warning_error_from_context PROTO ((tree, char *msg));
 static tree parse_jdk1_1_error PROTO ((char *));
 static void complete_class_report_errors PROTO ((jdep *));
 static int process_imports PROTO ((void));
@@ -614,6 +647,8 @@ static void read_import_dir PROTO ((tree));
 static int find_in_imports_on_demand PROTO ((tree));
 static int find_in_imports PROTO ((tree));
 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));
@@ -623,7 +658,7 @@ static void expand_start_java_method PROTO ((tree));
 static tree find_name_in_single_imports PROTO ((tree));
 static void check_abstract_method_header PROTO ((tree));
 static tree lookup_java_interface_method2 PROTO ((tree, tree));
-static tree resolve_expression_name PROTO ((tree));
+static tree resolve_expression_name PROTO ((tree, tree *));
 static tree maybe_create_class_interface_decl PROTO ((tree, tree, tree));
 static int check_class_interface_creation PROTO ((int, int, tree, 
                                                  tree, tree, tree));
@@ -633,7 +668,8 @@ static int breakdown_qualified PROTO ((tree *, tree *, tree));
 static tree resolve_and_layout PROTO ((tree, tree));
 static tree resolve_no_layout PROTO ((tree, tree));
 static int invocation_mode PROTO ((tree, int));
-static tree find_applicable_accessible_methods_list PROTO ((tree, tree, tree));
+static tree find_applicable_accessible_methods_list PROTO ((int, 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, int));
@@ -654,12 +690,14 @@ static tree build_method_invocation PROTO ((tree, tree));
 static tree build_new_invocation PROTO ((tree, tree));
 static tree build_assignment PROTO ((int, int, tree, tree));
 static tree build_binop PROTO ((enum tree_code, int, tree, tree));
+static int check_final_assignment PROTO ((tree ,tree));
 static tree patch_assignment PROTO ((tree, tree, tree ));
 static tree patch_binop PROTO ((tree, tree, tree));
 static tree build_unaryop PROTO ((int, int, tree));
 static tree build_incdec PROTO ((int, int, tree, int));
 static tree patch_unaryop PROTO ((tree, tree));
 static tree build_cast PROTO ((int, tree, tree));
+static tree build_null_of_type PROTO ((tree));
 static tree patch_cast PROTO ((tree, tree));
 static int valid_ref_assignconv_cast_p PROTO ((tree, tree, int));
 static int valid_builtin_assignconv_identity_widening_p PROTO ((tree, tree));
@@ -689,6 +727,7 @@ static tree maybe_access_field PROTO ((tree, tree, tree));
 static int complete_function_arguments PROTO ((tree));
 static int check_for_static_method_reference PROTO ((tree, tree, tree, tree, tree));
 static int not_accessible_p PROTO ((tree, tree, int));
+static void check_deprecation PROTO ((tree, tree));
 static int class_in_current_package PROTO ((tree));
 static tree build_if_else_statement PROTO ((int, tree, tree, tree));
 static tree patch_if_else_statement PROTO ((tree));
@@ -735,6 +774,11 @@ static tree create_artificial_method PROTO ((tree, int, tree, tree, tree));
 static void start_artificial_method_body PROTO ((tree));
 static void end_artificial_method_body PROTO ((tree));
 static tree generate_field_initialization_code PROTO ((tree));
+static int check_method_redefinition PROTO ((tree, tree));
+static int reset_method_name PROTO ((tree));
+static void java_check_regular_methods PROTO ((tree));
+static void java_check_abstract_methods PROTO ((tree));
+static tree maybe_build_primttype_type_ref PROTO ((tree, tree));
 
 void safe_layout_class PROTO ((tree));
 void java_complete_class PROTO ((void));
index c71178f..8d7c676 100644 (file)
@@ -67,6 +67,7 @@ definitions and other extensions.  */
 #include "lex.h"
 #include "parse.h"
 #include "zipfile.h"
+#include "convert.h"
 
 /* Number of error found so far. */
 int java_error_count; 
@@ -248,7 +249,7 @@ static tree wfl_to_string = NULL_TREE;
 %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
-%token   <operator>     OP_TK OSB_TK DOT_TK THROW_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
 
@@ -409,14 +410,11 @@ single_type_import_declaration:
                          ($2, "Ambiguous class: `%s' and `%s'",
                           IDENTIFIER_POINTER (name), 
                           IDENTIFIER_POINTER (err));
+                     else
+                       REGISTER_IMPORT ($2, last_name)
                    }
                  else
-                   {
-                     IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (last_name) = 1;
-                     node = build_tree_list ($2, last_name);
-                     TREE_CHAIN (node) = ctxp->import_list;
-                     ctxp->import_list = node;
-                   }
+                   REGISTER_IMPORT ($2, last_name);
                }
 |      IMPORT_TK error
                {yyerror ("Missing name"); RECOVER;}
@@ -1936,6 +1934,7 @@ relational_expression:
                                    $1, $3); 
                }
 |      relational_expression INSTANCEOF_TK reference_type
+               { $$ = build_binop (INSTANCEOF_EXPR, $2.location, $1, $3); }
 |      relational_expression LT_TK error
                {yyerror ("Missing term"); RECOVER;}
 |      relational_expression GT_TK error
@@ -2098,7 +2097,10 @@ java_push_parser_context ()
   new->next = ctxp;
   ctxp = new;
   if (ctxp->next)
-    ctxp->incomplete_class = ctxp->next->incomplete_class;
+    {
+      ctxp->incomplete_class = ctxp->next->incomplete_class;
+      ctxp->gclass_list = ctxp->next->gclass_list;
+    }
 }  
 
 /* If the first file of a file list was a class file, no context
@@ -2142,12 +2144,17 @@ java_pop_parser_context (generate)
      int generate;
 {
   tree current;
-  struct parser_ctxt *toFree = ctxp;
-  struct parser_ctxt *next = ctxp->next;
+  struct parser_ctxt *toFree, *next;
 
+  if (!ctxp)
+    return;
+
+  toFree = ctxp;
+  next = ctxp->next;
   if (next)
     {
       next->incomplete_class = ctxp->incomplete_class;
+      next->gclass_list = ctxp->gclass_list;
       lineno = ctxp->lineno;
       finput = ctxp->finput;
       current_class = ctxp->current_class;
@@ -2259,6 +2266,24 @@ parse_error (msg)
   java_error (msg);
 }
 
+static void
+issue_warning_error_from_context (cl, msg)
+     tree cl;
+     char *msg;
+{
+  char *saved;
+
+  ctxp->elc.line = EXPR_WFL_LINENO (cl);
+  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
+
+  /* We have a CL, that's a good reason for using it if it contains data */
+  saved = ctxp->filename;
+  if (TREE_CODE (cl) == EXPR_WITH_FILE_LOCATION && EXPR_WFL_FILENAME_NODE (cl))
+    ctxp->filename = EXPR_WFL_FILENAME (cl);
+  parse_error (msg);
+  ctxp->filename = saved;
+}
+
 /* Issue an error message at a current source line CL */
 
 static void
@@ -2269,6 +2294,7 @@ parse_error_context VPROTO ((tree cl, char *msg, ...))
   char *msg;
 #endif
   char buffer [4096];
+  char *saved;
   va_list ap;
 
   VA_START (ap, msg);
@@ -2279,10 +2305,7 @@ parse_error_context VPROTO ((tree cl, char *msg, ...))
   vsprintf (buffer, msg, ap);
 
   force_error = 1;
-  ctxp->elc.line = EXPR_WFL_LINENO (cl);
-  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
-  parse_error (buffer);
+  issue_warning_error_from_context (cl, buffer);
   force_error = 0;
 }
 
@@ -2296,6 +2319,7 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...))
   char *msg;
 #endif
   char buffer [4096];
+  char *saved;
   va_list ap;
 
   VA_START (ap, msg);
@@ -2306,10 +2330,7 @@ parse_warning_context VPROTO ((tree cl, char *msg, ...))
   vsprintf (buffer, msg, ap);
 
   force_error = do_warning = 1;
-  ctxp->elc.line = EXPR_WFL_LINENO (cl);
-  ctxp->elc.col  = (EXPR_WFL_COLNO (cl) == 0xfff ? -1 : EXPR_WFL_COLNO (cl));
-
-  parse_error (buffer);
+  issue_warning_error_from_context (cl, buffer);
   do_warning = force_error = 0;
 }
 
@@ -2562,9 +2583,7 @@ static tree
 maybe_create_class_interface_decl (decl, qualified_name, cl)
      tree decl, qualified_name, cl;
 {
-  if (decl)
-    DECL_ARTIFICIAL (decl) = 1; /* FIXME */
-  else
+  if (!decl)
     decl = push_class (make_class (), qualified_name);
   
   /* Take care of the file and line business */
@@ -2579,6 +2598,10 @@ maybe_create_class_interface_decl (decl, qualified_name, cl)
   /* Link the declaration to the already seen ones */
   TREE_CHAIN (decl) = ctxp->class_list;
   ctxp->class_list = decl;
+
+  /* Create a new node in the global list */
+  ctxp->gclass_list = tree_cons (NULL_TREE, decl, ctxp->gclass_list);
+
   /* Install a new dependency list element */
   create_jdep_list (ctxp);
 
@@ -2602,10 +2625,11 @@ add_superinterfaces (decl, interface_list)
   for (node = interface_list; node; node = TREE_CHAIN (node))
     {
       tree current = TREE_PURPOSE (node), interface_decl;
-      if ((interface_decl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current))))
+      tree idecl = IDENTIFIER_CLASS_VALUE (EXPR_WFL_NODE (current));
+      if (idecl && CLASS_LOADED_P (TREE_TYPE (idecl)))
        {
-         if (!parser_check_super_interface (interface_decl, decl, current))
-           parser_add_interface (decl, interface_decl, current);
+         if (!parser_check_super_interface (idecl, decl, current))
+           parser_add_interface (decl, idecl, current);
        }
       else
        register_incomplete_type (JDEP_INTERFACE,
@@ -2673,6 +2697,7 @@ create_class (flags, id, super, interfaces)
 
   class_id = parser_qualified_classname (id);
   decl = IDENTIFIER_CLASS_VALUE (class_id);
+  ctxp->current_parsed_class_un = EXPR_WFL_NODE (id);
   EXPR_WFL_NODE (id) = class_id;
 
   /* Basic check: scope, redefinition, modifiers */
@@ -2725,6 +2750,9 @@ create_class (flags, id, super, interfaces)
   CLASS_COMPLETE_P (decl) = 1;
   add_superinterfaces (decl, interfaces);
 
+  /* Eventually sets the @deprecated tag flag */
+  CHECK_DEPRECATED (decl);
+
   return decl;
 }
 
@@ -2854,9 +2882,10 @@ register_fields (flags, type, variable_list)
        }
 
       /* Set lineno to the line the field was found and create a
-         declaration for it */
+         declaration for it. Eventually sets the @deprecated tag flag. */
       lineno = EXPR_WFL_LINENO (cl);
       field_decl = add_field (class_type, current_name, type, flags);
+      CHECK_DEPRECATED (field_decl);
       
       /* Check if we must chain. */
       if (must_chain)
@@ -2873,12 +2902,16 @@ register_fields (flags, type, variable_list)
          /* The field is declared static */
          if (flags & ACC_STATIC)
            {
-             /* FIXME */
              if (flags & ACC_FINAL)
-               ;               
-             /* Otherwise, the field should be initialized in
-                <clinit>. This field is remembered so we can
-                generate <clinit> later. */
+               {
+                 if (DECL_LANG_SPECIFIC (field_decl) == NULL)
+                   DECL_LANG_SPECIFIC (field_decl) = (struct lang_decl *)
+                     permalloc (sizeof (struct lang_decl_var));
+                 DECL_LOCAL_STATIC_VALUE (field_decl) = 
+                   TREE_OPERAND (init, 1);
+               }
+             /* Otherwise, the field should be initialized in <clinit>. 
+                This field is remembered so we can generate <clinit> later */
              else
                {
                  INITIALIZED_P (field_decl) = 1;
@@ -2886,10 +2919,9 @@ register_fields (flags, type, variable_list)
                  ctxp->static_initialized = init;
                }
            }
-         /* A non-static field declared with an immediate
-            initialization is to be initialized in <init>, if
-            any.  This field is remembered to be processed at the
-            time of the generation of <init>. */
+         /* A non-static field declared with an immediate initialization is
+            to be initialized in <init>, if any.  This field is remembered
+            to be processed at the time of the generation of <init>. */
          else
            {
              INITIALIZED_P (field_decl) = 1;
@@ -2986,7 +3018,7 @@ method_header (flags, type, mdecl, throws)
   tree meth = TREE_VALUE (mdecl);
   tree id = TREE_PURPOSE (mdecl);
   tree this_class = TREE_TYPE (ctxp->current_parsed_class);
-  tree meth_name, returned_type, current;
+  tree meth_name, returned_type, current, orig_arg;
   int saved_lineno;
   int constructor_ok = 0;
   
@@ -3014,7 +3046,7 @@ method_header (flags, type, mdecl, throws)
       int ec = java_error_count;
       /* 8.6: Constructor declarations: we might be trying to define a
          method without specifying a return type. */
-      if (EXPR_WFL_NODE (id) != DECL_NAME (ctxp->current_parsed_class))
+      if (EXPR_WFL_NODE (id) != ctxp->current_parsed_class_un)
        parse_error_context 
          (id, "Invalid method declaration, return type required");
       /* 8.6.3: Constructor modifiers */
@@ -3077,7 +3109,11 @@ method_header (flags, type, mdecl, throws)
        }
     }
   else
-    TREE_TYPE (meth) = type;
+    {
+      if (TREE_CODE (type) == RECORD_TYPE)
+       type = promote_type (type);
+      TREE_TYPE (meth) = type;
+    }
 
   saved_lineno = lineno;
   /* When defining an abstract or interface method, the curly
@@ -3086,6 +3122,9 @@ method_header (flags, type, mdecl, throws)
   lineno = (ctxp->first_ccb_indent1 ? ctxp->first_ccb_indent1 : 
            EXPR_WFL_LINENO (id));
 
+  /* Remember the original argument list */
+  orig_arg = TYPE_ARG_TYPES (meth);
+
   if (patch_stage)             /* includes ret type and/or all args */
     {
       jdep *jdep;
@@ -3101,28 +3140,15 @@ method_header (flags, type, mdecl, throws)
       register_incomplete_type (JDEP_METHOD_END, NULL_TREE, meth, NULL_TREE);
     }
   else
-    {
-      tree signature = build_java_signature (meth);
-      tree arg, orig_arg;
-      /* Save original argument list, including argument's names */
-      orig_arg = TYPE_ARG_TYPES (meth);
-      /* Add the method to its class */
-      meth = add_method (this_class, flags, meth_name, signature);
-      /* Fix the method argument list so we have the argument name
-         information */
-      arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
-      if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
-       {
-         TREE_PURPOSE (arg) = this_identifier_node;
-         arg = TREE_CHAIN (arg);
-       }
-      while (orig_arg)
-        {
-         TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
-         orig_arg = TREE_CHAIN (orig_arg);
-         arg = TREE_CHAIN (arg);
-       }
-    }
+    meth = add_method (this_class, flags, meth_name, 
+                      build_java_signature (meth));
+
+  /* Fix the method argument list so we have the argument name
+     information */
+  fix_method_argument_names (orig_arg, meth);
+
+  /* Register the parameter number and re-install the current line
+     number */
   DECL_MAX_LOCALS (meth) = ctxp->formal_parameter_number+1;
   lineno = saved_lineno;
 
@@ -3157,9 +3183,30 @@ method_header (flags, type, mdecl, throws)
   if (constructor_ok)
     DECL_CONSTRUCTOR_P (meth) = 1;
 
+  /* Eventually set the @deprecated tag flag */
+  CHECK_DEPRECATED (meth);
+
   return meth;
 }
 
+static void
+fix_method_argument_names (orig_arg, meth)
+    tree orig_arg, meth;
+{
+  tree arg = TYPE_ARG_TYPES (TREE_TYPE (meth));
+  if (TREE_CODE (TREE_TYPE (meth)) == METHOD_TYPE)
+    {
+      TREE_PURPOSE (arg) = this_identifier_node;
+      arg = TREE_CHAIN (arg);
+    }
+  while (orig_arg)
+    {
+      TREE_PURPOSE (arg) = TREE_PURPOSE (orig_arg);
+      orig_arg = TREE_CHAIN (orig_arg);
+      arg = TREE_CHAIN (arg);
+    }
+}
+
 /* Complete the method declaration with METHOD_BODY.  */
 
 static void
@@ -3305,6 +3352,9 @@ method_declarator (id, list)
       type = build_array_from_name (type, type_wfl, name, &name);
       EXPR_WFL_NODE (wfl_name) = name;
 
+      if (TREE_CODE (type) == RECORD_TYPE)
+       type = promote_type (type);
+
       /* Check redefinition */
       for (already = arg_types; already; already = TREE_CHAIN (already))
        if (TREE_PURPOSE (already) == name)
@@ -3564,14 +3614,20 @@ void
 safe_layout_class (class)
      tree class;
 {
+  tree list;
   tree save_current_class = current_class;
   char *save_input_filename = input_filename;
   int save_lineno = lineno;
-  
+
   push_obstacks (&permanent_obstack, &permanent_obstack);
+
+  if (!CLASS_METHOD_CHECKED_P (class))
+    CHECK_METHODS (TYPE_NAME (class));
+  CLASS_METHOD_CHECKED_P (class) = 1;
+
   layout_class (class);
   pop_obstacks ();
-  
+
   current_class = save_current_class;
   input_filename = save_input_filename;
   lineno = save_lineno;
@@ -3655,6 +3711,8 @@ java_complete_class ()
                  field_type = promote_type (field_type);
                pop_obstacks ();
                TREE_TYPE (field_decl) = field_type;
+               DECL_ALIGN (field_decl) = 0;
+               layout_decl (field_decl, 0);
                SOURCE_FRONTEND_DEBUG 
                  (("Completed field/var decl `%s' with `%s'",
                    IDENTIFIER_POINTER (DECL_NAME (field_decl)),
@@ -3817,7 +3875,6 @@ do_resolve_class (class_type, decl, cl)
 
   /* 2- And check for the type in the current compilation unit. If it fails,
      try with a name qualified with the package name if appropriate. */
-
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     {
       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -3830,6 +3887,8 @@ do_resolve_class (class_type, decl, cl)
   if (!QUALIFIED_P (TYPE_NAME (class_type)) && ctxp->package)
     TYPE_NAME (class_type) = merge_qualified_name (ctxp->package, 
                                                   TYPE_NAME (class_type));
+  if (!(new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
+    load_class (TYPE_NAME (class_type), 0);
   if ((new_class_decl = IDENTIFIER_CLASS_VALUE (TYPE_NAME (class_type))))
     {
       if (!CLASS_LOADED_P (TREE_TYPE (new_class_decl)) &&
@@ -3984,9 +4043,7 @@ get_printable_method_name (decl)
   if (DECL_CONSTRUCTOR_P (decl))
     {
       name = DECL_NAME (decl);
-      DECL_NAME (decl) = 
-       DECL_NAME (ctxp->current_parsed_class ? 
-                  ctxp->current_parsed_class : current_class);
+      DECL_NAME (decl) = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
     }
       
   to_return = lang_printable_name (decl, 0);
@@ -3996,6 +4053,28 @@ get_printable_method_name (decl)
   return to_return;
 }
 
+/* Reinstall the proper DECL_NAME on METHOD. Return 0 if the method
+   nevertheless needs to be verfied, 1 otherwise.  */
+
+static int
+reset_method_name (method)
+     tree method;
+{
+  if (DECL_NAME (method) != clinit_identifier_node
+      && DECL_NAME (method) != finit_identifier_node)
+    {
+      /* NAME is just the plain name when Object is being defined */
+      if (DECL_CONTEXT (method) != object_type_node)
+       DECL_NAME (method) = 
+         (DECL_CONSTRUCTOR_P (method) ? init_identifier_node :
+          (TREE_CODE (DECL_NAME (method)) == EXPR_WITH_FILE_LOCATION ? 
+           EXPR_WFL_NODE (DECL_NAME (method)) : DECL_NAME (method)));
+      return 0;
+    }
+  else 
+    return 1;
+}
+
 /* Track method being redefined inside the same class. As a side
    effect, set DECL_NAME to an IDENTIFIER (prior entering this
    function it's a FWL, so we can track errors more accurately */
@@ -4009,19 +4088,14 @@ check_method_redefinition (class, method)
   tree sig = TYPE_LANG_SPECIFIC (TREE_TYPE (method))->signature;
   /* decl name of artificial <clinit> and <finit> doesn't need to be fixed and
      checked */
-  if (DECL_NAME (method) != clinit_identifier_node
-      && DECL_NAME (method) != finit_identifier_node)
-    {
-      /* NAME is just the plain name when Object is being defined */
-      if (class != object_type_node)
-       name = DECL_NAME (method) = (DECL_CONSTRUCTOR_P (method) ? 
-                                    init_identifier_node :
-                                    EXPR_WFL_NODE (DECL_NAME (method)));
-      else 
-       name = DECL_NAME (method);
-    }
-  else 
+
+  /* Reset the method name before running the check. If it returns 1,
+     the method doesn't need to be verified with respect to method
+     redeclaration and we return 0 */
+  if (reset_method_name (method))
     return 0;
+
+  name = DECL_NAME (method);
   
   for (redef = TYPE_METHODS (class); redef; redef = TREE_CHAIN (redef))
     {
@@ -4049,20 +4123,26 @@ static void
 java_check_regular_methods (class_decl)
      tree class_decl;
 {
+  int saw_constructor = 0;
   tree method;
   tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (class_decl));
   tree super_class = CLASSTYPE_SUPER (class);
-  int saw_constructor = 0;
+  tree saved_found_wfl = NULL_TREE, found = NULL_TREE;
 
   TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
   /* Should take interfaces into account. FIXME */
   for (method = TYPE_METHODS (class); method; method = TREE_CHAIN (method))
     {
-      tree found, sig;
+      tree sig;
       tree method_wfl = DECL_NAME (method);
       int aflags;
 
+      /* If we previously found something and its name was saved,
+         reinstall it now */
+      if (found && saved_found_wfl)
+       DECL_NAME (found) = saved_found_wfl;
+
       /* Check for redefinitions */
       if (check_method_redefinition (class, method))
        continue;
@@ -4077,12 +4157,17 @@ java_check_regular_methods (class_decl)
        }
 
       sig = build_java_argument_signature (TREE_TYPE (method));
-
       found = lookup_argument_method (super_class, DECL_NAME (method), sig);
 
-      /* Nothing overrides or it's a private method */
+      /* Nothing overrides or it's a private method. */
       if (!found || (found && METHOD_PRIVATE (found)))
-        continue;
+       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. */
+      saved_found_wfl = DECL_NAME (found);
+      reset_method_name (found);
+
       /* Can't override a method with the same name and different return
         types. */
       if (TREE_TYPE (TREE_TYPE (found)) != TREE_TYPE (TREE_TYPE (method)))
@@ -4126,19 +4211,27 @@ java_check_regular_methods (class_decl)
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          continue;
        }
-      /* Overriding/hiding public must be public or
-        overriding/hiding protected must be protected or public */
-      if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) ||
-         (METHOD_PROTECTED (found) 
-          && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method))))
+
+      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)
+           access, then the overriding or hiding method must not be
+           private; otherwise, a compile-time error occurs */
+      if ((METHOD_PUBLIC (found) && !METHOD_PUBLIC (method)) 
+         || (METHOD_PROTECTED (found) 
+             && !(METHOD_PUBLIC (method) || METHOD_PROTECTED (method)))
+         || (!(aflags & (ACC_PUBLIC | ACC_PRIVATE | ACC_STATIC))
+             && METHOD_PRIVATE (method)))
        {
          parse_error_context 
            (method_wfl,
             "Methods can't be overridden to be more private. Method `%s' is "
-            "%s in class `%s'", lang_printable_name (found, 0),
-            (METHOD_PUBLIC (found) ? "public" : "protected"),
-            IDENTIFIER_POINTER 
-              (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+            "not %s in class `%s'", lang_printable_name (method, 0),
+            (METHOD_PUBLIC (method) ? "public" : 
+             (METHOD_PRIVATE (method) ? "private" : "protected")),
+            IDENTIFIER_POINTER (DECL_NAME 
+                                (TYPE_NAME (DECL_CONTEXT (found)))));
          continue;
        }
 
@@ -4148,9 +4241,10 @@ java_check_regular_methods (class_decl)
 
       /* 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 */
-      aflags = get_access_flags_from_decl (found);
-      if ((!aflags || (aflags > ACC_PROTECTED))
+        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)))
        parse_warning_context 
          (method_wfl, "Method `%s' in class `%s' does not "
@@ -4160,10 +4254,16 @@ java_check_regular_methods (class_decl)
           IDENTIFIER_POINTER (DECL_NAME (class_decl)),
           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
 
-      /* Check on (default) package access. FIXME.  */
       /* Inheriting multiple methods with the same signature. FIXME */
     }
   
+  /* Don't forget eventual pending found and saved_found_wfl. Take
+     into account that we might have exited because we saw an
+     aritifical method as the last entry. */
+
+  if (found && !DECL_ARTIFICIAL (found) && saved_found_wfl)
+    DECL_NAME (found) = saved_found_wfl;
+
   TYPE_METHODS (class) = nreverse (TYPE_METHODS (class));
 
   if (!saw_constructor)
@@ -4220,11 +4320,12 @@ check_throws_clauses (method, method_wfl, found)
 /* Check abstract method of interface INTERFACE */
 
 static void
-java_check_abstract_methods (interface)
-     tree interface;
+java_check_abstract_methods (interface_decl)
+     tree interface_decl;
 {
   int i, n;
   tree method, basetype_vec, found;
+  tree interface = TREE_TYPE (interface_decl);
 
   for (method = TYPE_METHODS (interface); method; method = TREE_CHAIN (method))
     {
@@ -4239,16 +4340,20 @@ java_check_abstract_methods (interface)
       found = lookup_java_interface_method2 (interface, method);
       if (found)
        {
-         char *t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)),
-                                                0));
+         char *t;
+         tree saved_found_wfl = DECL_NAME (found);
+         reset_method_name (found);
+         t = strdup (lang_printable_name (TREE_TYPE (TREE_TYPE (found)), 0));
          parse_error_context 
            (method_wfl,
-            "Method `%s' was defined with return type `%s' in class `%s ",
+            "Method `%s' was defined with return type `%s' in class `%s'",
             lang_printable_name (found, 0), t,
             IDENTIFIER_POINTER 
               (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
          free (t);
          continue;
+         
+         DECL_NAME (found) = saved_found_wfl;
        }
     }
 
@@ -4270,37 +4375,39 @@ java_check_abstract_methods (interface)
          found = lookup_java_interface_method2 (interface, 
                                                 sub_interface_method);
          if (found && (found != sub_interface_method))
-           parse_error_context 
-             (lookup_cl (sub_interface_method),
-              "Interface `%s' inherits method `%s' from interface `%s'. This "
-              "method is redefined with a different return "
-              "type in interface `%s'",
-              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
-              lang_printable_name (found, 0),
-              IDENTIFIER_POINTER 
-                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (sub_interface_method)))),
-              IDENTIFIER_POINTER 
-                (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+           {
+             tree saved_found_wfl = DECL_NAME (found);
+             reset_method_name (found);
+             parse_error_context 
+               (lookup_cl (sub_interface_method),
+                "Interface `%s' inherits method `%s' from interface `%s'. "
+                "This method is redefined with a different return type in "
+                "interface `%s'",
+                IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (interface))),
+                lang_printable_name (found, 0),
+                IDENTIFIER_POINTER 
+                  (DECL_NAME (TYPE_NAME 
+                              (DECL_CONTEXT (sub_interface_method)))),
+                IDENTIFIER_POINTER 
+                  (DECL_NAME (TYPE_NAME (DECL_CONTEXT (found)))));
+             DECL_NAME (found) = saved_found_wfl;
+           }
        }
     }
 }
 
-/* Check the method on all the defined classes. Should be done to the
-   classes declared in the compilation unit only. FIXME  */
+/* Check the method on all the defined classes. Process all the
+   classes that we compiled from source code for this CU.  */
 
 void
 java_check_methods ()
 {
   tree current;
-  for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
-    if (CLASS_FROM_SOURCE_P (TREE_TYPE (current)))
+  for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
+    if (CLASS_FROM_SOURCE_P (TREE_TYPE (TREE_VALUE (current))))
       {
-       tree class = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current));
-
-       if (CLASS_INTERFACE (TYPE_NAME (class)))
-         java_check_abstract_methods (class);
-       else
-         java_check_regular_methods (current);
+       CHECK_METHODS (TREE_VALUE (current));
+       CLASS_METHOD_CHECKED_P (TREE_TYPE (TREE_VALUE (current))) = 1;
       }
 }
 
@@ -4345,9 +4452,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
      tree clas, method_decl;
      int do_interface;
 {
-  tree method, method_signature, method_name, method_type;
+  tree method, method_signature, method_name, method_type, name;
+
   method_signature = build_java_argument_signature (TREE_TYPE (method_decl));
-  method_name = DECL_NAME (method_decl);
+  name = DECL_NAME (method_decl);
+  method_name = (TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ? 
+                EXPR_WFL_NODE (name) : name);
   method_type = TREE_TYPE (TREE_TYPE (method_decl));
 
   while (clas != NULL_TREE)
@@ -4356,12 +4466,12 @@ lookup_java_method2 (clas, method_decl, do_interface)
           method != NULL_TREE;  method = TREE_CHAIN (method))
        {
          tree method_sig = build_java_argument_signature (TREE_TYPE (method));
-         if (DECL_NAME (method) == method_name 
+         tree name = DECL_NAME (method);
+         if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
+              EXPR_WFL_NODE (name) : name) == method_name
              && method_sig == method_signature 
              && TREE_TYPE (TREE_TYPE (method)) != method_type)
-           {
-             return method;
-           }
+           return method;
        }
       clas = (do_interface ? NULL_TREE : CLASSTYPE_SUPER (clas));
     }
@@ -4450,8 +4560,6 @@ find_in_imports (class_type)
       {
        TYPE_NAME (class_type) = EXPR_WFL_NODE (TREE_PURPOSE (import));
        QUALIFIED_P (TYPE_NAME (class_type)) = 1;
-       return check_pkg_class_access (TYPE_NAME (class_type), 
-                                      TREE_PURPOSE (import));
       }
   return 0;
 }
@@ -4675,6 +4783,50 @@ find_in_imports_on_demand (class_type)
     return (seen_once < 0 ? 0 : seen_once); /* It's ok not to have found */
 }
 
+static tree
+resolve_package (pkg, next)
+     tree pkg, *next;
+{
+  tree type_name = NULL_TREE;
+  char *name = IDENTIFIER_POINTER (EXPR_WFL_NODE (pkg));
+  int   length = IDENTIFIER_LENGTH (EXPR_WFL_NODE (pkg));
+
+  /* The trick is to determine when the package name stops and were
+     the name of something contained in the package starts. Then we
+     return a fully qualified name of what we want to get. */
+
+  /* Do a quick search on well known package names */
+  if (!strncmp (name, "java.lang.reflect", 17))
+    {
+      *next = 
+       TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg))));
+      type_name = lookup_package_type (name, 17);
+    }
+  else if (!strncmp (name, "java.lang", 9))
+    {
+      *next = TREE_CHAIN (TREE_CHAIN (EXPR_WFL_QUALIFICATION (pkg)));
+      type_name = lookup_package_type (name, 9);
+    }
+  else
+    return NULL_TREE;          /* FIXME, search all imported packages. */
+
+  return type_name;
+}
+
+static tree
+lookup_package_type (name, from)
+     char *name;
+     int from;
+{
+  char subname [128];
+  char *sub = &name[from+1];
+  while (*sub != '.' && *sub)
+    sub++;
+  strncpy (subname, name, sub-name);
+  subname [sub-name] = '\0';
+  return get_identifier (subname);
+}
+
 /* Check that CLASS_NAME refers to a PUBLIC class. Return 0 if no
    access violations were found, 1 otherwise.  */
 
@@ -5021,16 +5173,21 @@ add_stmt_to_compound (existing, type, stmt)
 /* Hold THIS for the scope of the current public method decl.  */
 static tree current_this;
 
-/* Layout all class found during parsing. Also fixes the order of
-   several field related lists. */
+/* Layout all class found during parsing. Also fixes the order of some
+   lists.  */
 
 void
 java_layout_classes ()
 {
   tree current;
-  for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
+
+  java_check_methods ();
+  /* Error reported by the caller */
+  if (java_error_count)
+    return;
+  for (current = ctxp->gclass_list; current; current = TREE_CHAIN (current))
     {
-      current_class = TREE_TYPE (current);
+      current_class = TREE_TYPE (TREE_VALUE (current));
 
       /* Reverse the fields if it's necessary (they've already
          reversed if the dummy field has been inserted at the
@@ -5042,6 +5199,10 @@ java_layout_classes ()
       /* Do a layout if necessary */
       if (!TYPE_SIZE (current_class) || (current_class == object_type_node))
        safe_layout_class (current_class);
+
+      /* Error reported by the caller */
+      if (java_error_count)
+       return;
     }
 }
 
@@ -5080,7 +5241,9 @@ java_complete_expand_methods ()
                    restore_line_number_status (0);
                  }
              }
-           else
+           else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl))
+             continue;
+           else 
              java_complete_expand_method (decl);
          }
 
@@ -5135,6 +5298,7 @@ java_complete_expand_method (mdecl)
 
       if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)))
        java_complete_tree (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (mdecl)));
+
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -5294,6 +5458,13 @@ java_expand_finals ()
 void
 java_expand_classes ()
 {
+  ctxp = ctxp_for_generation;
+  /* If we found error earlier, we don't want to report then twice. */
+  if (java_error_count || !ctxp)
+    return;
+  java_layout_classes ();
+  java_parse_abort_on_error ();
+
   for (; ctxp_for_generation; ctxp_for_generation = ctxp_for_generation->next)
     {
       ctxp = ctxp_for_generation;
@@ -5425,8 +5596,9 @@ cut_identifier_in_qualified (wfl)
 /* Resolve the expression name NAME. Return its decl.  */
 
 static tree
-resolve_expression_name (id)
+resolve_expression_name (id, orig)
      tree id;
+     tree *orig;
 {
   tree name = EXPR_WFL_NODE (id);
   tree decl;
@@ -5445,6 +5617,7 @@ resolve_expression_name (id)
          decl = lookup_field_wrapper (current_class, name);
          if (decl)
            {
+             tree value = NULL_TREE;
              int fs = FIELD_STATIC (decl);
              /* Instance variable (8.3.1.1) can't appear within
                 static method, static initializer or initializer for
@@ -5468,9 +5641,20 @@ resolve_expression_name (id)
                     "constructor has been called", IDENTIFIER_POINTER (name));
                  return error_mark_node;
                }
+             /* The field is final. We may use its value instead */
+             if (fs && FIELD_FINAL (decl))
+               value = java_complete_tree (DECL_LOCAL_STATIC_VALUE (decl));
+
+             /* Otherwise build what it takes to access the field */
              decl = build_field_ref ((fs ? NULL_TREE : current_this),
                                      current_class, name);
-             return (fs ? build_class_init (current_class, decl) : decl);
+             if (fs && !flag_emit_class_files)
+               decl = build_class_init (current_class, decl);
+             /* We may be asked to save the real field access node */
+             if (orig)
+               *orig = decl;
+             /* And we return what we got */
+             return (value ? value : decl);
            }
          /* Fall down to error report on undefined variable */
        }
@@ -5478,6 +5662,8 @@ resolve_expression_name (id)
   /* 6.5.5.2 Qualified Expression Names */
   else
     {
+      if (orig)
+       *orig = NULL_TREE;
       qualify_ambiguous_name (id);
       /* 15.10.1 Field Access Using a Primary and/or Expression Name */
       /* 15.10.2: Accessing Superclass Members using super */
@@ -5523,12 +5709,24 @@ resolve_field_access (qual_wfl, field_decl, field_type)
     field_ref = decl;
   else if (DECL_P (decl))
     {
+      int static_final_found = 0;
+      if (!type_found)
+       type_found = DECL_CONTEXT (decl);
       is_static = DECL_P (decl) && FIELD_STATIC (decl);
-      field_ref = build_field_ref ((is_static ? NULL_TREE : where_found), 
-                                  type_found, DECL_NAME (decl));
+      if (FIELD_FINAL (decl) 
+         && JPRIMITIVE_TYPE_P (TREE_TYPE (decl))
+         && DECL_LANG_SPECIFIC (decl)
+         && DECL_LOCAL_STATIC_VALUE (decl))
+       {
+         field_ref = java_complete_tree (DECL_LOCAL_STATIC_VALUE (decl));
+         static_final_found = 1;
+       }
+      else
+       field_ref = build_field_ref ((is_static ? NULL_TREE : where_found), 
+                                    type_found, DECL_NAME (decl));
       if (field_ref == error_mark_node)
        return error_mark_node;
-      if (is_static)
+      if (is_static && !static_final_found)
        {
          field_ref = build_class_init (type_found, field_ref);
          /* If the static field was identified by an expression that
@@ -5571,7 +5769,6 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
       tree qual_wfl = QUAL_WFL (q);
 
       /* 15.10.1 Field Access Using a Primary */
-      
       switch (TREE_CODE (qual_wfl))
        {
        case CALL_EXPR:
@@ -5619,6 +5816,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          continue;
 
        case CONDITIONAL_EXPR:
+       case STRING_CST:
          *where_found = decl = java_complete_tree (qual_wfl);
          if (decl == error_mark_node)
            return 1;
@@ -5660,7 +5858,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
            }
          /* We have to generate code for intermediate acess */
          *where_found = decl = current_this;
-         type = QUAL_DECL_TYPE (decl);
+         *type_found = type = QUAL_DECL_TYPE (decl);
          continue;
        }
 
@@ -5692,17 +5890,33 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
         assume a variable/class name was meant. */
       if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
        {
-         if (from_super || from_cast)
-           parse_error_context 
-             ((from_cast ? qual_wfl : wfl),
-              "No variable `%s' defined in class `%s'",
-              IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
-              lang_printable_name (type, 0));
+         tree name = resolve_package (wfl, &q);
+         if (name)
+           {
+             *where_found = decl = resolve_no_layout (name, qual_wfl);
+             /* We wan't to be absolutely that the class is laid
+                 out. We're going to search something inside it. */
+             *type_found = type = TREE_TYPE (decl);
+             layout_class (type);
+             from_type = 1;
+             /* Should be a list, really. FIXME */
+             RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 1;
+             RESOLVE_PACKAGE_NAME_P (QUAL_WFL (TREE_CHAIN (q))) = 0;
+           }
          else
-           parse_error_context
-             (qual_wfl, "Undefined variable or class name: `%s'",
-              IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
-         return 1;
+           {
+             if (from_super || from_cast)
+               parse_error_context 
+                 ((from_cast ? qual_wfl : wfl),
+                  "No variable `%s' defined in class `%s'",
+                  IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)),
+                  lang_printable_name (type, 0));
+             else
+               parse_error_context
+                 (qual_wfl, "Undefined variable or class name: `%s'",
+                  IDENTIFIER_POINTER (EXPR_WFL_NODE (qual_wfl)));
+             return 1;
+           }
        }
 
       /* We have a type name. It's been already resolved when the
@@ -5722,6 +5936,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                 IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
              return 1;
            }
+         check_deprecation (qual_wfl, decl);
          
          type = TREE_TYPE (decl);
          from_type = 1;
@@ -5738,18 +5953,24 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
          if (!from_super && QUAL_RESOLUTION (q))
            {
              decl = QUAL_RESOLUTION (q);
-             *type_found = type;
+             if (!type && !FIELD_STATIC (decl))
+               {
+                 *where_found = current_this;
+                 *type_found = type;
+               }
            }
 
          /* We have to search for a field, knowing the type of its
              container. The flag FROM_TYPE indicates that we resolved
              the last member of the expression as a type name, which
-             means that for the resolution of this field, will check
-             on other errors than if the it was resolved as a member
-             of an other field. */
+             means that for the resolution of this field, we'll look
+             for other errors than if it was resolved as a member of
+             an other field. */
          else
            {
              int is_static;
+             tree field_decl_type; /* For layout */
+
              if (!from_type && !JREFERENCE_TYPE_P (type))
                {
                  parse_error_context 
@@ -5769,6 +5990,17 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                     IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
                  return 1;
                }
+
+             /* Layout the type of field_decl, since we may need
+                 it. Don't do primitive types or loaded classes */
+             if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
+               field_decl_type = TREE_TYPE (TREE_TYPE (field_decl));
+             else
+               field_decl_type = TREE_TYPE (field_decl);
+             if (!JPRIMITIVE_TYPE_P (field_decl_type) 
+                 && !CLASS_LOADED_P (field_decl_type))
+               resolve_and_layout (DECL_NAME (TYPE_NAME (field_decl_type)),
+                                   NULL_TREE);
              
              /* Check on accessibility here */
              if (not_accessible_p (type, field_decl, from_super))
@@ -5784,6 +6016,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                       (DECL_NAME (TYPE_NAME (current_class))));
                  return 1;
                }
+             check_deprecation (qual_wfl, field_decl);
              
              /* There are things to check when fields are accessed
                 from type. There are no restrictions on a static
@@ -5802,8 +6035,9 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
                }
              from_cast = from_super = 0;
 
-             /* If we need to generate something to get a proper handle
-                on what this field is accessed from, do it now. */
+             /* If we need to generate something to get a proper
+                handle on what this field is accessed from, do it
+                now. */
              if (!is_static)
                {
                  decl = maybe_access_field (decl, *where_found, *type_found);
@@ -5889,6 +6123,38 @@ int not_accessible_p (reference, member, from_super)
   return 0;
 }
 
+/* Test deprecated decl access.  */
+static void
+check_deprecation (wfl, decl)
+     tree wfl, decl;
+{
+  char *file = DECL_SOURCE_FILE (decl);
+  /* Complain if the field is deprecated and the file it was defined
+     in isn't compiled at the same time the file which contains its
+     use is */
+  if (DECL_DEPRECATED (decl) 
+      && !IS_A_COMMAND_LINE_FILENAME_P (get_identifier (file)))
+    {
+      char the [20];
+      switch (TREE_CODE (decl))
+       {
+       case FUNCTION_DECL:
+         strcpy (the, "method");
+         break;
+       case FIELD_DECL:
+         strcpy (the, "field");
+         break;
+       case TYPE_DECL:
+         strcpy (the, "class");
+         break;
+       }
+      parse_warning_context 
+       (wfl, "The %s `%s' in class `%s' has been deprecated", 
+        the, lang_printable_name (decl, 0),
+        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)))));
+    }
+}
+
 /* Returns 1 if class was declared in the current package, 0 otherwise */
 
 static int
@@ -5933,10 +6199,8 @@ static tree
 maybe_access_field (decl, where, type)
   tree decl, where, type;
 {
-  if (DECL_P (decl) && decl != current_this
-      && (!(TREE_CODE (decl) != PARM_DECL
-           && FIELD_STATIC (decl)))
-      && !IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
+  if (TREE_CODE (decl) == FIELD_DECL && decl != current_this
+      && !FIELD_STATIC (decl))
     decl = build_field_ref (where ? where : current_this, 
                            (type ? type : DECL_CONTEXT (decl)),
                            DECL_NAME (decl));
@@ -5957,7 +6221,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
   tree wfl = TREE_OPERAND (patch, 0);
   tree args = TREE_OPERAND (patch, 1);
   tree name = EXPR_WFL_NODE (wfl);
-  tree list, class_type;
+  tree list;
   int is_static_flag = 0;
   
   /* Should be overriden if everything goes well. Otherwise, if
@@ -6028,6 +6292,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
              free (fct_name);
              PATCH_METHOD_RETURN_ERROR ();
            }
+         args = nreverse (args);
        }
       /* We're resolving an expression name */
       else
@@ -6053,9 +6318,7 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
          args = tree_cons (NULL_TREE, field, nreverse (args));
        }
 
-      /* CLASS_TYPE is used during the call to not_accessible_p and
-        IDENTIFIER_WFL will be used to report any problem further */
-      class_type = TREE_TYPE (class_decl);
+      /* IDENTIFIER_WFL will be used to report any problem further */
       wfl = identifier_wfl;
     }
   /* Resolution of simple names, names generated after a primary: or
@@ -6099,8 +6362,11 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
                  PATCH_METHOD_RETURN_ERROR ();
                }
              
-             /* Can't instantiate an abstract class */
-             if (CLASS_ABSTRACT (class_to_search))
+             /* Can't instantiate an abstract class, but we can
+                invoke it's constructor. It's use within the `new'
+                context is denied here. */
+             if (CLASS_ABSTRACT (class_to_search) 
+                 && TREE_CODE (patch) == NEW_CLASS_EXPR)
                {
                  parse_error_context 
                    (wfl, "Class `%s' is an abstract class. It can't be "
@@ -6143,8 +6409,6 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
       args = nreverse (args);
       if (!METHOD_STATIC (list) && TREE_CODE (patch) != NEW_CLASS_EXPR)
        args = tree_cons (NULL_TREE, primary ? primary : current_this, args);
-
-      class_type = class_to_search;
     }
 
   /* Merge point of all resolution schemes. If we have nothing, this
@@ -6154,18 +6418,19 @@ patch_method_invocation_stmt (patch, primary, where, is_static, ret_decl, super)
 
   /* Check accessibility, position the is_static flag, build and
      return the call */
-  if (not_accessible_p (class_type, list, 0))
+  if (not_accessible_p (DECL_CONTEXT (list), list, 0))
     {
       char *fct_name = strdup (lang_printable_name (list, 0));
       parse_error_context 
        (wfl, "Can't access %s method `%s %s.%s' from `%s'",
         java_accstring_lookup (get_access_flags_from_decl (list)),
         lang_printable_name (TREE_TYPE (TREE_TYPE (list)), 0), 
-        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (class_type))), fct_name,
-        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
+        IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (DECL_CONTEXT (list)))), 
+        fct_name, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (current_class))));
       free (fct_name);
       PATCH_METHOD_RETURN_ERROR ();
     }
+  check_deprecation (wfl, list);
 
   is_static_flag = METHOD_STATIC (list);
 
@@ -6223,9 +6488,14 @@ patch_invoke (patch, method, args, from_super)
   tree signature = build_java_signature (TREE_TYPE (method));
   tree original_call, t, ta;
 
-  /* Last step for args: convert build-in types. */
-  for (t = TYPE_ARG_TYPES (TREE_TYPE (method)), ta = args;
-       t && ta; t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
+  /* Last step for args: convert build-in types. If we're dealing with
+     a new TYPE() type call, the first argument to the constructor
+     isn't found in the incomming argument list, but delivered by
+     `new' */
+  t = TYPE_ARG_TYPES (TREE_TYPE (method));
+  if (TREE_CODE (patch) == NEW_CLASS_EXPR)
+    t = TREE_CHAIN (t);
+  for (ta = args; t && ta; t = TREE_CHAIN (t), ta = TREE_CHAIN (ta))
     if (JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_VALUE (ta))) &&
        TREE_TYPE (TREE_VALUE (ta)) != TREE_VALUE (t))
       TREE_VALUE (ta) = convert (TREE_VALUE (t), TREE_VALUE (ta));
@@ -6243,6 +6513,11 @@ patch_invoke (patch, method, args, from_super)
                                     DECL_CONTEXT (method), signature, args);
       break;
 
+    case INVOKE_INTERFACE:
+      dtable = invoke_build_dtable (1, args);
+      func = build_invokeinterface (dtable, DECL_NAME (method), signature);
+      break;
+
     default:
       fatal ("Unknown invocation mode `%d' - build_invoke", im);
       return NULL_TREE;
@@ -6318,34 +6593,24 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
      tree class, name, arg_list;
 {
   tree method = make_node (FUNCTION_TYPE);
-  tree arg_type_list = NULL_TREE;
+  tree atl = NULL_TREE;                /* Arg Type List */
   tree signature, list, node;
   char *candidates;            /* Used for error report */
 
+  /* Fix the arguments */
   for (node = arg_list; node; node = TREE_CHAIN (node))
     {
       tree current_arg = TREE_TYPE (TREE_VALUE (node));
       if (TREE_CODE (current_arg) == RECORD_TYPE)
        current_arg = promote_type (current_arg);
-      arg_type_list = tree_cons (NULL_TREE, current_arg, arg_type_list);
+      atl = tree_cons (NULL_TREE, current_arg, atl);
     }
-  TYPE_ARG_TYPES (method) = arg_type_list;
+  TYPE_ARG_TYPES (method) = atl;
 
-  if (!lc)
-    {
-      list = find_applicable_accessible_methods_list (class, name, 
-                                                     arg_type_list);
-      list = find_most_specific_methods_list (list);
-    }
-  else
-    {
-      TREE_TYPE (method) = void_type_node;
-      signature = build_java_signature (method);
-      list = lookup_java_constructor (class, signature);
-    }
-
-  if (lc && list)
-    return list;
+  /* Find all candidates and then refine the list, searching for the
+     most specific method. */
+  list = find_applicable_accessible_methods_list (lc, class, name, atl);
+  list = find_most_specific_methods_list (list);
   if (list && !TREE_CHAIN (list))
     return TREE_VALUE (list);
 
@@ -6386,10 +6651,12 @@ lookup_method_invoke (lc, cl, class, name, arg_list)
   return NULL_TREE;
 }
 
-/* 15.11.2.1: Find Methods that are Applicable and Accessible */
+/* 15.11.2.1: Find Methods that are Applicable and Accessible. LC is 1
+   when we're looking for a constructor. */
 
 static tree
-find_applicable_accessible_methods_list (class, name, arglist)
+find_applicable_accessible_methods_list (lc, class, name, arglist)
+     int lc;
      tree class, name, arglist;
 {
   tree method;
@@ -6400,10 +6667,12 @@ find_applicable_accessible_methods_list (class, name, arglist)
       for (method = TYPE_METHODS (class);
           method != NULL_TREE;  method = TREE_CHAIN (method))
        {
-         /* Names have to match and we're not looking for constructor */
-         if (DECL_NAME (method) != name || DECL_CONSTRUCTOR_P (method))
+         if (lc && !DECL_CONSTRUCTOR_P (method))
            continue;
-
+         else if (!lc && (DECL_CONSTRUCTOR_P (method)
+                          || DECL_NAME (method) != name))
+           continue;
+         
          if (argument_types_convertible (method, arglist))
            {
              /* Retain accessible methods only */
@@ -6414,7 +6683,9 @@ find_applicable_accessible_methods_list (class, name, arglist)
                all_list = tree_cons (NULL_TREE, method, list);
            }
        }
-      class = CLASSTYPE_SUPER (class);
+      /* When dealing with constructor, stop here, otherwise search
+         other classes */
+      class = (lc ? NULL_TREE : CLASSTYPE_SUPER (class));
     }
   /* Either return the list obtained or all selected (but
      inaccessible) methods for better error report. */
@@ -6598,8 +6869,9 @@ 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 ?: up front */
-    if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR)
+    /* Loop one more time if we're dealing with ?: or a string constant */
+    if (TREE_CODE (qual_wfl) == CONDITIONAL_EXPR
+       || TREE_CODE (qual_wfl) == STRING_CST)
       {
        qual = TREE_CHAIN (qual);
        qual_wfl = QUAL_WFL (qual);
@@ -6709,8 +6981,10 @@ not_initialized_as_it_should_p (decl)
 {
   if (DECL_P (decl))
     {
-      if (TREE_CODE (decl) == FIELD_DECL
-         && METHOD_STATIC (current_function_decl))
+      if (FIELD_FINAL (decl))
+       return 0;
+      if (TREE_CODE (decl) == FIELD_DECL 
+         && (METHOD_STATIC (current_function_decl)))
        return 0;
       return DECL_P (decl) && !INITIALIZED_P (decl);
     }
@@ -6860,7 +7134,7 @@ java_complete_tree (node)
     case EXPR_WITH_FILE_LOCATION:
       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
          || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
-        return resolve_expression_name (node);
+        return resolve_expression_name (node, NULL);
       else
        {
          EXPR_WFL_NODE (node) = java_complete_tree (EXPR_WFL_NODE (node));
@@ -6958,7 +7232,8 @@ java_complete_tree (node)
             an error during the assignment. In any cases, the
             assignment operation fails. */
          if (TREE_CODE (TREE_OPERAND (node, 1)) != EXPR_WITH_FILE_LOCATION
-             && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node)
+             && TREE_TYPE (TREE_OPERAND (node, 1)) != error_mark_node
+             && TREE_TYPE (TREE_OPERAND (node, 1)))
            patch_assignment (node, wfl_op1, wfl_op2);
 
          /* Now, we still mark the lhs as initialized */
@@ -7015,6 +7290,11 @@ java_complete_tree (node)
        }
       return patch_binop (node, wfl_op1, wfl_op2);
 
+    case INSTANCEOF_EXPR:
+      wfl_op1 = TREE_OPERAND (node, 0);
+      COMPLETE_CHECK_OP_0 (node);
+      return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
+
     case UNARY_PLUS_EXPR:
     case NEGATE_EXPR:
     case TRUTH_NOT_EXPR:
@@ -7108,8 +7388,10 @@ complete_function_arguments (node)
         `+' operator. Build `parm.toString()' and expand it. */
       if ((temp = patch_string (parm)))
        parm = temp;
-      TREE_VALUE (cn) = parm;
+      /* Inline PRIMTYPE.TYPE read access */
+      parm = maybe_build_primttype_type_ref (parm, wfl);
 
+      TREE_VALUE (cn) = parm;
       if (not_initialized_as_it_should_p (parm))
        {
          ERROR_VARIABLE_NOT_INITIALIZED (wfl, EXPR_WFL_NODE (wfl));
@@ -7350,6 +7632,47 @@ print_int_node (node)
   return buffer;
 }
 
+/* Return 1 if you an assignment of a FINAL is attempted */
+
+static int
+check_final_assignment (lvalue, wfl)
+     tree lvalue, wfl;
+{
+  if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
+    {
+      parse_error_context 
+        (wfl, "Can't assign a value to the final variable `%s'",
+        IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl)));
+      return 1;
+    }
+  return 0;
+}
+
+/* Inline references to java.lang.PRIMTYPE.TYPE when accessed in
+   read. This is needed to avoid circularities in the implementation
+   of these fields in libjava. */
+
+static tree
+maybe_build_primttype_type_ref (rhs, wfl)
+    tree rhs, wfl;
+{
+  tree to_return = NULL_TREE;
+  tree rhs_type = TREE_TYPE (rhs);
+  if (TREE_CODE (rhs) == COMPOUND_EXPR)
+    {
+      tree n = TREE_OPERAND (rhs, 1);
+      if (TREE_CODE (n) == VAR_DECL 
+         && DECL_NAME (n) == TYPE_identifier_node
+         && rhs_type == class_ptr_type)
+       {
+         char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl));
+         if (!strncmp (self_name, "java.lang.", 10))
+           to_return = build_primtype_type_ref (self_name);
+       }
+    }
+  return (to_return ? to_return : rhs );
+}
+
 /* 15.25 Assignment operators. */
 
 static tree
@@ -7359,19 +7682,14 @@ patch_assignment (node, wfl_op1, wfl_op2)
      tree wfl_op2;
 {
   tree rhs = TREE_OPERAND (node, 1);
-  tree lvalue = TREE_OPERAND (node, 0);
+  tree lvalue = TREE_OPERAND (node, 0), llvalue;
   tree lhs_type, rhs_type, new_rhs = NULL_TREE;
   int error_found = 0;
   int lvalue_from_array = 0;
 
   /* Can't assign to a final. */
-  if (DECL_P (lvalue) && FIELD_FINAL (lvalue))
-    {
-      parse_error_context 
-        (wfl_op1, "Can't assign a value to the final variable `%s'",
-        IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op1)));
-      error_found = 1;
-    }
+  if (check_final_assignment (lvalue, wfl_op1))
+    error_found = 1;
 
   EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
 
@@ -7394,8 +7712,18 @@ patch_assignment (node, wfl_op1, wfl_op2)
   /* Or a function return slot */
   else if (TREE_CODE (lvalue) == RESULT_DECL)
     lhs_type = TREE_TYPE (lvalue);
-  /* Otherwise, this is an error */
-  else
+  /* 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))
+    {
+      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;
+    }
+  else 
     {
       parse_error_context (wfl_op1, "Invalid left hand side of assignment");
       error_found = 1;
@@ -7462,6 +7790,22 @@ patch_assignment (node, wfl_op1, wfl_op2)
       INITIALIZED_P (rhs) = 1;
     }
 
+  /* Inline read access to java.lang.PRIMTYPE.TYPE */
+  rhs = maybe_build_primttype_type_ref (rhs, wfl_op2);
+
+  if (TREE_CODE (rhs) == COMPOUND_EXPR)
+    {
+      tree n = TREE_OPERAND (rhs, 1);
+      if (TREE_CODE (n) == VAR_DECL 
+         && DECL_NAME (n) == TYPE_identifier_node
+         && rhs_type == class_ptr_type)
+       {
+         char *self_name = IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op2));
+         if (!strncmp (self_name, "java.lang.", 10))
+           rhs = build_primtype_type_ref (self_name);
+       }
+    }
+
   if (error_found)
     return error_mark_node;
 
@@ -7515,9 +7859,15 @@ try_builtin_assignconv (wfl_op1, lhs_type, rhs)
   tree new_rhs = NULL_TREE;
   tree rhs_type = TREE_TYPE (rhs);
 
+  /* Zero accepted everywhere */
+  if (TREE_CODE (rhs) == INTEGER_CST 
+      && TREE_INT_CST_HIGH (rhs) == 0 && TREE_INT_CST_LOW (rhs) == 0
+      && JPRIMITIVE_TYPE_P (rhs_type))
+    new_rhs = convert (lhs_type, rhs);
+
   /* 5.1.1 Try Identity Conversion,
      5.1.2 Try Widening Primitive Conversion */
-  if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
+  else if (valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type))
     new_rhs = convert (lhs_type, rhs);
 
   /* Try a narrowing primitive conversion (5.1.3): 
@@ -7552,20 +7902,32 @@ static int
 valid_builtin_assignconv_identity_widening_p (lhs_type, rhs_type)
      tree lhs_type, rhs_type;
 {
-  int all_primitive = 
+  int all_primitive;
+
+  if (lhs_type == rhs_type)
+    return 1;
+
+  all_primitive = 
     JPRIMITIVE_TYPE_P (lhs_type) && JPRIMITIVE_TYPE_P (rhs_type);
 
   if (!all_primitive)
     return 0;
 
-  if (lhs_type == rhs_type)
-    return 1;
-
   /* 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;
 
+  /* Accept all promoted type here. Note, we can't use <= in the test
+     below, because we still need to bounce out assignments of short
+     to char and the likes */
+  if (lhs_type == int_type_node
+      && (rhs_type == promoted_byte_type_node
+         || rhs_type == promoted_short_type_node
+         || rhs_type == promoted_char_type_node
+         || 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) &&
@@ -7590,6 +7952,8 @@ valid_ref_assignconv_cast_p (source, dest, cast)
      tree dest;
      int cast;
 {
+  if (JNULLP_TYPE_P (source))
+    return 1;
   if (TREE_CODE (source) == POINTER_TYPE)
     source = TREE_TYPE (source);
   if (TREE_CODE (dest) == POINTER_TYPE)
@@ -7715,8 +8079,8 @@ valid_method_invocation_conversion_p (dest, source)
   return ((JPRIMITIVE_TYPE_P (source) 
            && JPRIMITIVE_TYPE_P (dest)
            && valid_builtin_assignconv_identity_widening_p (dest, source))
-          || (JREFERENCE_TYPE_P (source) 
-              && JREFERENCE_TYPE_P (dest)
+          || ((JREFERENCE_TYPE_P (source) || JNULLP_TYPE_P (source))
+              && (JREFERENCE_TYPE_P (dest) || JNULLP_TYPE_P (dest))
               && valid_ref_assignconv_cast_p (source, dest, 0)));
 }
 
@@ -7728,9 +8092,7 @@ build_binop (op, op_location, op1, op2)
      int op_location;
      tree op1, op2;
 {
-  tree binop;
-
-  binop = build (op, NULL_TREE, op1, op2);
+  tree binop = build (op, NULL_TREE, op1, op2);
   TREE_SIDE_EFFECTS (binop) = 1;
   /* Store the location of the operator, for better error report. The
      string of the operator will be rebuild based on the OP value. */
@@ -7935,7 +8297,63 @@ patch_binop (node, wfl_op1, wfl_op2)
          TREE_SET_CODE (node, RSHIFT_EXPR);
        }
       break;
+
+      /* 15.19.1 Type Comparison Operator instaceof */
+    case INSTANCEOF_EXPR:
+
+      TREE_TYPE (node) = boolean_type_node;
+
+      if (!(op2_type = resolve_type_during_patch (op2)))
+       return error_mark_node;
+
+      /* The first operand must be a reference type or the null type */
+      if (!JREFERENCE_TYPE_P (op1_type) && op1 != null_pointer_node)
+       error_found = 1;        /* Error reported further below */
+
+      /* The second operand must be a reference type */
+      if (!JREFERENCE_TYPE_P (op2_type))
+       {
+         SET_WFL_OPERATOR (wfl_operator, node, wfl_op2);
+         parse_error_context
+           (wfl_operator, "Invalid argument `%s' for `instanceof'",
+            lang_printable_name (op2_type, 0));
+         error_found = 1;
+       }
+
+      if (!error_found && valid_ref_assignconv_cast_p (op1_type, op2_type, 1))
+       {
+         /* If the first operand is null, the result is always false */
+         if (op1 == null_pointer_node)
+           return boolean_false_node;
+         /* Otherwise we have to invoke instance of to figure it out */
+         else
+           {
+             tree call =
+               build (CALL_EXPR, boolean_type_node,
+                      build_address_of (soft_instanceof_node),
+                      tree_cons 
+                      (NULL_TREE, op1,
+                       build_tree_list (NULL_TREE,
+                                        build_class_ref (op2_type))),
+                      NULL_TREE);
+             TREE_SIDE_EFFECTS (call) = 1;
+             return call;
+           }
+       }
+      /* There is no way the expression operand can be an instance of
+        the type operand. This is a compile time error. */
+      else
+       {
+         char *t1 = strdup (lang_printable_name (op1_type, 0));
+         SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
+         parse_error_context 
+           (wfl_operator, "Impossible for `%s' to be instance of `%s'",
+            t1, lang_printable_name (op2_type, 0));
+         free (t1);
+         error_found = 1;
+       }
       
+      break;
 
       /* 15.21 Bitwise and Logical Operators */
     case BIT_AND_EXPR:
@@ -8011,7 +8429,7 @@ patch_binop (node, wfl_op1, wfl_op2)
     case NE_EXPR:
       /* 15.20.1 Numerical Equality Operators == and != */
       /* Binary numeric promotion is performed on the operands */
-      if (JPRIMITIVE_TYPE_P (op1_type) && JPRIMITIVE_TYPE_P (op2_type))
+      if (JNUMERIC_TYPE_P (op1_type) && JNUMERIC_TYPE_P (op2_type))
        binary_numeric_promotion (op1_type, op2_type, &op1, &op2);
       
       /* 15.20.2 Boolean Equality Operators == and != */
@@ -8020,10 +8438,14 @@ patch_binop (node, wfl_op1, wfl_op2)
        ;                       /* Nothing to do here */
       
       /* 15.20.3 Reference Equality Operators == and != */
-      /* Types have to be either references or the null type */
+      /* Types have to be either references or the null type. If
+         they're references, it must be possible to convert either
+         type to the other by casting conversion. */
       else if (op1 == null_pointer_node || op2 == null_pointer_node 
               || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
-                  && ((op1_type == op2_type))))
+                  && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
+                      || valid_ref_assignconv_cast_p (op2_type, 
+                                                      op1_type, 1))))
        ;                       /* Nothing to do here */
          
       /* Else we have an error figure what can't be converted into
@@ -8344,22 +8766,25 @@ 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 
+      if (!DECL_P (op) && !((TREE_CODE (op) == INDIRECT_REF 
+                            || TREE_CODE (op) == COMPONENT_REF) 
                            && JPRIMITIVE_TYPE_P (TREE_TYPE (op))))
        {
-         parse_error_context (wfl_operator, "Invalid argument to `%s'",
-                              operator_string (node));
-         TREE_TYPE (node) = error_mark_node;
-         error_found = 1;
-       }
-      else if (DECL_P (op) && FIELD_FINAL (op))
-       {
-         parse_error_context 
-           (wfl_op, "Can't assign a value to the final variable `%s'",
-            IDENTIFIER_POINTER (EXPR_WFL_NODE (wfl_op)));
+         tree lvalue;
+         /* Before screaming, check that we're not in fact trying to
+            increment a optimized static final access, in which case
+            we issue an different error message. */
+         if (!(TREE_CODE (wfl_op) == EXPR_WITH_FILE_LOCATION
+               && resolve_expression_name (wfl_op, &lvalue)
+               && check_final_assignment (lvalue, wfl_op)))
+           parse_error_context (wfl_operator, "Invalid argument to `%s'",
+                                operator_string (node));
          TREE_TYPE (node) = error_mark_node;
          error_found = 1;
        }
+      else if (check_final_assignment (op, wfl_op))
+       error_found = 1;
+
       /* From now on, we know that op if a variable and that it has a
          valid wfl. We use wfl_op to locate errors related to the
          ++/-- operand. */
@@ -8480,7 +8905,10 @@ resolve_type_during_patch (type)
          return NULL_TREE;
        }
       else
-       return TREE_TYPE (type_decl);
+       {
+         CLASS_LOADED_P (TREE_TYPE (type_decl)) = 1;
+         return TREE_TYPE (type_decl);
+       }
     }
   return type;
 }
@@ -8515,6 +8943,10 @@ patch_cast (node, wfl_operator)
       return convert (cast_type, op);
     }
 
+  /* null can be casted to references */
+  if (op == null_pointer_node && JREFERENCE_TYPE_P (cast_type))
+    return build_null_of_type (cast_type);
+
   /* 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) 
@@ -8544,6 +8976,17 @@ patch_cast (node, wfl_operator)
   return error_mark_node;
 }
 
+/* Build a null constant and give it the type TYPE.  */
+
+static tree
+build_null_of_type (type)
+     tree type;
+{
+  tree node = build_int_2 (0, 0);
+  TREE_TYPE (node) = promote_type (type);
+  return node;
+}
+
 /* Build an ARRAY_REF incomplete tree node. Note that operand 1 isn't
    a list of indices. */
 static tree
@@ -8617,8 +9060,11 @@ patch_array_ref (node, wfl_array, wfl_index)
     return error_mark_node;
   index = convert (promoted_index_type, index);
 
-  if (TREE_CODE (array_type) == RECORD_TYPE)
-    array_type = promote_type (TYPE_ARRAY_ELEMENT (array_type));
+  array_type = TYPE_ARRAY_ELEMENT (array_type);
+  if (TREE_CODE (array_type) == RECORD_TYPE 
+      && !JPRIMITIVE_TYPE_P (TREE_TYPE (array_type)))
+    array_type = promote_type (array_type);
+
   if (flag_emit_class_files)
     {
       TREE_OPERAND (node, 0)= array;
@@ -8804,7 +9250,6 @@ patch_return (node)
   tree return_exp = TREE_OPERAND (node, 0);
   tree meth = current_function_decl;
   tree mtype = TREE_TYPE (TREE_TYPE (current_function_decl));
-  tree modify;
   int error_found = 0;
 
   TREE_TYPE (node) = error_mark_node;
@@ -8838,12 +9283,33 @@ patch_return (node)
       return error_mark_node;
     }
 
-  /* If we have a return_exp, build a modify expression and expand it */
+  /* If we have a return_exp, build a modify expression and expand
+     it. Note: at that point, the assignment is declared valid, but we
+     may want to carry some more hacks */
   if (return_exp)
     {
-      modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), return_exp);
+      tree exp = java_complete_tree (return_exp);
+      tree modify, patched;
+
+      /* If the function returned value and EXP are booleans, EXP has
+      to be converted into the type of DECL_RESULT, which is integer
+      (see complete_start_java_method) */
+      if (TREE_TYPE (exp) == boolean_type_node &&
+         TREE_TYPE (TREE_TYPE (meth)) == boolean_type_node)
+       exp = convert_to_integer (TREE_TYPE (DECL_RESULT (meth)), exp);
+
+      /* `null' can be assigned to a function returning a reference */
+      if (JREFERENCE_TYPE_P (TREE_TYPE (TREE_TYPE (meth))) &&
+         exp == null_pointer_node)
+       exp = build_null_of_type (TREE_TYPE (TREE_TYPE (meth)));
+
+      if ((patched = patch_string (exp)))
+       exp = patched;
+      
+      modify = build (MODIFY_EXPR, NULL_TREE, DECL_RESULT (meth), exp);
       EXPR_WFL_LINECOL (modify) = EXPR_WFL_LINECOL (node);
       modify = java_complete_tree (modify);
+
       if (modify != error_mark_node)
        {
          TREE_SIDE_EFFECTS (modify) = 1;
index 9aad0fb..154ba57 100644 (file)
@@ -52,10 +52,6 @@ set_local_type (slot, type)
     type_map[++slot] = void_type_node;
 }
 
-extern tree convert_to_integer (tree type, tree expr);
-extern tree convert_to_real (tree type, tree expr);
-extern tree convert_to_pointer (tree type, tree expr);
-
 /* Create an expression whose value is that of EXPR,
    converted to type TYPE.  The TREE_TYPE of the value
    is always TYPE.  This function implements all reasonable
@@ -663,7 +659,7 @@ lookup_argument_method (clas, method_name, method_signature)
          tree method_sig = build_java_argument_signature (TREE_TYPE (method));
          tree name = DECL_NAME (method);
          if ((TREE_CODE (name) == EXPR_WITH_FILE_LOCATION ?
-              EXPR_WFL_NODE (DECL_NAME (method)) : name) == method_name 
+              EXPR_WFL_NODE (name) : name) == method_name 
              && method_sig == method_signature)
            return method;
        }