OSDN Git Service

gcc/java:
[pf3gnuchains/gcc-fork.git] / gcc / java / parse.y
index 815b51e..b4facbb 100644 (file)
@@ -1,6 +1,6 @@
 /* Source code parsing and tree node generation for the GNU compiler
    for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
@@ -67,7 +67,6 @@ definitions and other extensions.  */
 #include "zipfile.h"
 #include "convert.h"
 #include "buffer.h"
-#include "xref.h"
 #include "function.h"
 #include "except.h"
 #include "ggc.h"
@@ -354,8 +353,6 @@ static char *string_convert_int_cst (tree);
 int java_error_count;
 /* Number of warning found so far. */
 int java_warning_count;
-/* Tell when not to fold, when doing xrefs */
-int do_not_fold;
 /* Cyclic inheritance report, as it can be set by layout_class */
 const char *cyclic_inheritance_report;
 
@@ -364,6 +361,7 @@ struct parser_ctxt *ctxp;
 
 /* List of things that were analyzed for which code will be generated */
 struct parser_ctxt *ctxp_for_generation = NULL;
+struct parser_ctxt *ctxp_for_generation_last = NULL;
 
 /* binop_lookup maps token to tree_code. It is used where binary
    operations are involved and required by the parser. RDIV_EXPR
@@ -908,16 +906,10 @@ interface_type_list:
 class_body:
        OCB_TK CCB_TK
                {
-                 /* Store the location of the `}' when doing xrefs */
-                 if (flag_emit_xref)
-                   DECL_END_SOURCE_LINE (GET_CPC ()) = $2.location;
                  $$ = GET_CPC ();
                }
 |      OCB_TK class_body_declarations CCB_TK
                {
-                 /* Store the location of the `}' when doing xrefs */
-                 if (flag_emit_xref)
-                   DECL_END_SOURCE_LINE (GET_CPC ()) = $3.location;
                  $$ = GET_CPC ();
                }
 ;
@@ -1393,9 +1385,6 @@ block_end:
        CCB_TK
                {
                  maybe_absorb_scoping_blocks ();
-                 /* Store the location of the `}' when doing xrefs */
-                 if (current_function_decl && flag_emit_xref)
-                   DECL_END_SOURCE_LINE (current_function_decl) = $1.location;
                  $$ = exit_block ();
                  if (!BLOCK_SUBBLOCKS ($$))
                    BLOCK_SUBBLOCKS ($$) = build_java_empty_stmt ();
@@ -2777,8 +2766,12 @@ java_pop_parser_context (int generate)
      do is to just update a list of class names.  */
   if (generate)
     {
-      ctxp->next = ctxp_for_generation;
-      ctxp_for_generation = ctxp;
+      if (ctxp_for_generation_last == NULL)
+        ctxp_for_generation = ctxp;
+      else
+        ctxp_for_generation_last->next = ctxp;
+      ctxp->next = NULL;
+      ctxp_for_generation_last = ctxp;
     }
 
   /* And restore those of the previous context */
@@ -3118,7 +3111,7 @@ yyerror (const char *msgid)
                 code_from_source, strlen (code_from_source));
   remainder = obstack_finish (&temporary_obstack);
   if (do_warning)
-    warning ("%s.\n%s", msgid, remainder);
+    warning (0, "%s.\n%s", msgid, remainder);
   else
     error ("%s.\n%s", msgid, remainder);
 
@@ -3718,7 +3711,7 @@ resolve_inner_class (htab_t circularity_hash, tree cl, tree *enclosing,
         break;
 
       if (TREE_CODE (local_super) == POINTER_TYPE)
-        local_super = do_resolve_class (NULL, local_super, NULL, NULL);
+        local_super = do_resolve_class (NULL, NULL, local_super, NULL, NULL);
       else
        local_super = TYPE_NAME (local_super);
 
@@ -3780,7 +3773,7 @@ find_as_inner_class (tree enclosing, tree name, tree cl)
          acc = merge_qualified_name (acc,
                                      EXPR_WFL_NODE (TREE_PURPOSE (qual)));
          BUILD_PTR_FROM_NAME (ptr, acc);
-         decl = do_resolve_class (NULL_TREE, ptr, NULL_TREE, cl);
+         decl = do_resolve_class (NULL_TREE, NULL_TREE, ptr, NULL_TREE, cl);
        }
 
       /* A NULL qual and a decl means that the search ended
@@ -3886,11 +3879,7 @@ maybe_create_class_interface_decl (tree decl, tree raw_name,
   DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (cl);
 #else
   DECL_SOURCE_FILE (decl) = EXPR_WFL_FILENAME (cl);
-  /* If we're emitting xrefs, store the line/col number information */
-  if (flag_emit_xref)
-    DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (cl);
-  else
-    DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
+  DECL_SOURCE_LINE (decl) = EXPR_WFL_LINENO (cl);
 #endif
   CLASS_FROM_SOURCE_P (TREE_TYPE (decl)) = 1;
   CLASS_PARSED_P (TREE_TYPE (decl)) = 1;
@@ -4193,17 +4182,18 @@ create_class (int flags, tree id, tree super, tree interfaces)
      virtual function table in java.lang.object.  */
   TYPE_VFIELD (TREE_TYPE (decl)) = TYPE_VFIELD (object_type_node);
 
+  /* We keep the compilation unit imports in the class so that
+     they can be used later to resolve type dependencies that
+     aren't necessary to solve now. */
+  TYPE_IMPORT_LIST (TREE_TYPE (decl)) = ctxp->import_list;
+  TYPE_IMPORT_DEMAND_LIST (TREE_TYPE (decl)) = ctxp->import_demand_list;
+
   /* Add the private this$<n> field, Replicate final locals still in
      scope as private final fields mangled like val$<local_name>.
      This does not occur for top level (static) inner classes. */
   if (PURE_INNER_CLASS_DECL_P (decl))
     add_inner_class_fields (decl, current_function_decl);
 
-  /* If doing xref, store the location at which the inherited class
-     (if any) was seen. */
-  if (flag_emit_xref && super)
-    DECL_INHERITED_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (super);
-
   /* Eventually sets the @deprecated tag flag */
   CHECK_DEPRECATED (decl);
 
@@ -4495,10 +4485,7 @@ register_fields (int flags, tree type, tree variable_list)
 #ifdef USE_MAPPED_LOCATION
       input_location = EXPR_LOCATION (cl);
 #else
-      if (flag_emit_xref)
-       input_line = EXPR_WFL_LINECOL (cl);
-      else
-       input_line = EXPR_WFL_LINENO (cl);
+      input_line = EXPR_WFL_LINENO (cl);
 #endif
       field_decl = add_field (class_type, current_name, real_type, flags);
       CHECK_DEPRECATED_NO_RESET (field_decl);
@@ -4895,17 +4882,6 @@ method_header (int flags, tree type, tree mdecl, tree throws)
   /* Eventually set the @deprecated tag flag */
   CHECK_DEPRECATED (meth);
 
-  /* If doing xref, store column and line number information instead
-     of the line number only. */
-  if (flag_emit_xref)
-    {
-#ifdef USE_MAPPED_LOCATION
-      DECL_SOURCE_LOCATION (meth) = EXPR_LOCATION (id);
-#else
-      DECL_SOURCE_LINE (meth) = EXPR_WFL_LINECOL (id);
-#endif
-    }
-
   return meth;
 }
 
@@ -4971,8 +4947,7 @@ finish_method_declaration (tree method_body)
   exit_block ();
   /* Merge last line of the function with first line, directly in the
      function decl. It will be used to emit correct debug info. */
-  if (!flag_emit_xref)
-    DECL_FUNCTION_LAST_LINE (current_function_decl) = ctxp->last_ccb_indent1;
+  DECL_FUNCTION_LAST_LINE (current_function_decl) = ctxp->last_ccb_indent1;
 
   /* Since function's argument's list are shared, reset the
      ARG_FINAL_P parameter that might have been set on some of this
@@ -5719,12 +5694,6 @@ java_complete_class (void)
     {
       jdep *dep;
 
-      /* We keep the compilation unit imports in the class so that
-        they can be used later to resolve type dependencies that
-        aren't necessary to solve now. */
-      TYPE_IMPORT_LIST (TREE_TYPE (cclass)) = ctxp->import_list;
-      TYPE_IMPORT_DEMAND_LIST (TREE_TYPE (cclass)) = ctxp->import_demand_list;
-
       for (dep = CLASSD_FIRST (cclassd); dep; dep = JDEP_CHAIN (dep))
        {
          tree decl;
@@ -5875,7 +5844,7 @@ resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
     WFL_STRIP_BRACKET (cl, cl);
 
   /* 2- Resolve the bare type */
-  if (!(resolved_type_decl = do_resolve_class (enclosing, class_type,
+  if (!(resolved_type_decl = do_resolve_class (enclosing, NULL_TREE, class_type,
                                               decl, cl)))
     return NULL_TREE;
   resolved_type = TREE_TYPE (resolved_type_decl);
@@ -5898,7 +5867,8 @@ resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
    and (but it doesn't really matter) qualify_and_find.  */
 
 tree
-do_resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
+do_resolve_class (tree enclosing, tree import_type, tree class_type, tree decl,
+                 tree cl)
 {
   tree new_class_decl = NULL_TREE, super = NULL_TREE;
   tree saved_enclosing_type = enclosing ? TREE_TYPE (enclosing) : NULL_TREE;
@@ -5915,7 +5885,7 @@ do_resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
       if (split_qualified_name (&left, &right, TYPE_NAME (class_type)) == 0)
        {
          BUILD_PTR_FROM_NAME (left_type, left);
-         q = do_resolve_class (enclosing, left_type, decl, cl);
+         q = do_resolve_class (enclosing, import_type, left_type, decl, cl);
          if (q)
            {
              enclosing = q;
@@ -5960,8 +5930,11 @@ do_resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
        return new_class_decl;
     }
 
-  /* 1- Check for the type in single imports. This will change
-     TYPE_NAME() if something relevant is found */
+  /* 1- Check for the type in single imports.  Look at enclosing classes and,
+     if we're laying out a superclass, at the import list for the subclass.
+     This will change TYPE_NAME() if something relevant is found. */
+  if (import_type && TYPE_IMPORT_LIST (import_type))
+    find_in_imports (import_type, class_type);
   find_in_imports (saved_enclosing_type, class_type);
 
   /* 2- And check for the type in the current compilation unit */
@@ -5983,8 +5956,14 @@ do_resolve_class (tree enclosing, tree class_type, tree decl, tree cl)
   /* 4- Check the import on demands. Don't allow bar.baz to be
      imported from foo.* */
   if (!QUALIFIED_P (TYPE_NAME (class_type)))
-    if (find_in_imports_on_demand (saved_enclosing_type, class_type))
-      return NULL_TREE;
+    {
+      if (import_type
+         && TYPE_IMPORT_DEMAND_LIST (import_type)
+         && find_in_imports_on_demand (import_type, class_type))
+        return NULL_TREE;
+      if (find_in_imports_on_demand (saved_enclosing_type, class_type))
+        return NULL_TREE;
+    }
 
   /* If found in find_in_imports_on_demand, the type has already been
      loaded. */
@@ -6738,10 +6717,6 @@ check_throws_clauses (tree method, tree method_wfl, tree found)
 {
   tree mthrows;
 
-  /* Can't check these things with class loaded from bytecode. FIXME */
-  if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (found)))
-    return;
-
   for (mthrows = DECL_FUNCTION_THROWS (method);
        mthrows; mthrows = TREE_CHAIN (mthrows))
     {
@@ -6955,14 +6930,14 @@ process_imports (void)
       tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
       char *original_name;
 
-      original_name = xmemdup (IDENTIFIER_POINTER (to_be_found),
-                              IDENTIFIER_LENGTH (to_be_found),
-                              IDENTIFIER_LENGTH (to_be_found) + 1);
-
       /* Don't load twice something already defined. */
       if (IDENTIFIER_CLASS_VALUE (to_be_found))
        continue;
 
+      original_name = xmemdup (IDENTIFIER_POINTER (to_be_found),
+                              IDENTIFIER_LENGTH (to_be_found),
+                              IDENTIFIER_LENGTH (to_be_found) + 1);
+
       while (1)
        {
          tree left;
@@ -7010,8 +6985,12 @@ process_imports (void)
 static void
 find_in_imports (tree enclosing_type, tree class_type)
 {
-  tree import = (enclosing_type ? TYPE_IMPORT_LIST (enclosing_type) :
-                ctxp->import_list);
+  tree import;
+  if (enclosing_type && TYPE_IMPORT_LIST (enclosing_type))
+    import = TYPE_IMPORT_LIST (enclosing_type);
+  else
+    import = ctxp->import_list;
+
   while (import)
     {
       if (TREE_VALUE (import) == TYPE_NAME (class_type))
@@ -7169,12 +7148,16 @@ static int
 find_in_imports_on_demand (tree enclosing_type, tree class_type)
 {
   tree class_type_name = TYPE_NAME (class_type);
-  tree import = (enclosing_type ? TYPE_IMPORT_DEMAND_LIST (enclosing_type) :
-                 ctxp->import_demand_list);
   tree cl = NULL_TREE;
   int seen_once = -1;  /* -1 when not set, 1 if seen once, >1 otherwise. */
   int to_return = -1;  /* -1 when not set, 0 or 1 otherwise */
   tree node;
+  tree import;
+
+  if (enclosing_type && TYPE_IMPORT_DEMAND_LIST (enclosing_type))
+    import = TYPE_IMPORT_DEMAND_LIST (enclosing_type);
+  else
+    import = ctxp->import_demand_list;
 
   for (; import; import = TREE_CHAIN (import))
     {
@@ -7517,16 +7500,6 @@ declare_local_variables (int modifier, tree type, tree vlist)
       DECL_FINAL (decl) = final_p;
       BLOCK_CHAIN_DECL (decl);
 
-      /* If doing xreferencing, replace the line number with the WFL
-         compound value */
-#ifdef USE_MAPPED_LOCATION
-      if (flag_emit_xref)
-       DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (wfl);
-#else
-      if (flag_emit_xref)
-       DECL_SOURCE_LINE (decl) = EXPR_WFL_LINECOL (wfl);
-#endif
-
       /* Don't try to use an INIT statement when an error was found */
       if (init && java_error_count)
        init = NULL_TREE;
@@ -7707,8 +7680,7 @@ source_end_java_method (void)
     BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl)) = NULL_TREE;
 
   if (BLOCK_EXPR_BODY (DECL_FUNCTION_BODY (fndecl))
-      && ! flag_emit_class_files
-      && ! flag_emit_xref)
+      && ! flag_emit_class_files)
     finish_method (fndecl);
 
   current_function_decl = NULL_TREE;
@@ -7869,8 +7841,6 @@ java_complete_expand_classes (void)
 {
   tree current;
 
-  do_not_fold = flag_emit_xref;
-
   for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
     if (!INNER_CLASS_DECL_P (current))
       java_complete_expand_class (current);
@@ -8144,7 +8114,7 @@ maybe_yank_clinit (tree mdecl)
 
   /* Now we analyze the method body and look for something that
      isn't a MODIFY_EXPR */
-  if (!IS_EMPTY_STMT (bbody) && analyze_clinit_body (type, bbody))
+  if (bbody && !IS_EMPTY_STMT (bbody) && analyze_clinit_body (type, bbody))
     return 0;
 
   /* Get rid of <clinit> in the class' list of methods */
@@ -8249,7 +8219,7 @@ java_complete_expand_method (tree mdecl)
       htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
                     attach_init_test_initialization_flags, block_body);
 
-      if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
+      if (! METHOD_NATIVE (mdecl))
        {
          check_for_initialization (block_body, mdecl);
 
@@ -8279,8 +8249,7 @@ java_complete_expand_method (tree mdecl)
      an error_mark_node here. */
   if (block_body != error_mark_node
       && (block_body == NULL_TREE || CAN_COMPLETE_NORMALLY (block_body))
-      && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE
-      && !flag_emit_xref)
+      && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
     missing_return_error (current_function_decl);
 
   /* See if we can get rid of <clinit> if MDECL happens to be <clinit> */
@@ -8296,7 +8265,7 @@ java_complete_expand_method (tree mdecl)
   if (currently_caught_type_list)
     abort ();
 
-  /* Restore the copy of the list of exceptions if emitting xrefs. */
+  /* Restore the copy of the list of exceptions. */
   DECL_FUNCTION_THROWS (mdecl) = exception_copy;
 }
 
@@ -9282,10 +9251,10 @@ java_expand_classes (void)
 #endif
 
   /* If we've found error at that stage, don't try to generate
-     anything, unless we're emitting xrefs or checking the syntax only
+     anything, unless we're checking the syntax only
      (but not using -fsyntax-only for the purpose of generating
-     bytecode. */
-  if (java_error_count && !flag_emit_xref
+     bytecode).  */
+  if (java_error_count
       && (!flag_syntax_only && !flag_emit_class_files))
     return;
 
@@ -9331,8 +9300,6 @@ java_expand_classes (void)
          output_class = current_class = TREE_TYPE (TREE_VALUE (current));
          if (flag_emit_class_files)
            write_classfile (current_class);
-         if (flag_emit_xref)
-           expand_xref (current_class);
          else if (! flag_syntax_only)
            java_expand_method_bodies (current_class);
        }
@@ -9619,7 +9586,7 @@ resolve_field_access (tree qual_wfl, tree *field_decl, tree *field_type)
   /* Resolve the LENGTH field of an array here */
   if (DECL_P (decl) && DECL_NAME (decl) == length_identifier_node
       && type_found && TYPE_ARRAY_P (type_found)
-      && ! flag_emit_class_files && ! flag_emit_xref)
+      && ! flag_emit_class_files)
     {
       tree length = build_java_array_length_access (where_found);
       field_ref = length;
@@ -9645,7 +9612,7 @@ resolve_field_access (tree qual_wfl, tree *field_decl, tree *field_type)
       if (!type_found)
        type_found = DECL_CONTEXT (decl);
       is_static = FIELD_STATIC (decl);
-      field_ref = build_field_ref ((is_static && !flag_emit_xref?
+      field_ref = build_field_ref ((is_static ?
                                    NULL_TREE : where_found),
                                   type_found, DECL_NAME (decl));
       if (field_ref == error_mark_node)
@@ -9658,7 +9625,6 @@ resolve_field_access (tree qual_wfl, tree *field_decl, tree *field_type)
         looks like `field.ref', where `field' is a static field in an
         interface we implement.  */
       if (!flag_emit_class_files
-         && !flag_emit_xref
          && TREE_CODE (where_found) == VAR_DECL
          && FIELD_STATIC (where_found))
        {
@@ -10485,7 +10451,7 @@ patch_method_invocation (tree patch, tree primary, tree where, int from_super,
       if (TREE_CODE (resolved) == VAR_DECL && FIELD_STATIC (resolved)
          && FIELD_FINAL (resolved)
          && !inherits_from_p (DECL_CONTEXT (resolved), current_class)
-         && !flag_emit_class_files && !flag_emit_xref)
+         && !flag_emit_class_files)
        resolved = build_class_init (DECL_CONTEXT (resolved), resolved);
 
       if (resolved == error_mark_node)
@@ -10964,7 +10930,7 @@ patch_invoke (tree patch, tree method, tree args)
   if (TREE_CODE (t) == POINTER_TYPE && !CLASS_LOADED_P (TREE_TYPE (t)))
     resolve_and_layout (TREE_TYPE (t), NULL);
 
-  if (flag_emit_class_files || flag_emit_xref)
+  if (flag_emit_class_files)
     func = method;
   else
     {
@@ -11030,7 +10996,7 @@ patch_invoke (tree patch, tree method, tree args)
       tree c1, saved_new, new;
       tree alloc_node;
 
-      if (flag_emit_class_files || flag_emit_xref)
+      if (flag_emit_class_files)
        {
          TREE_TYPE (patch) = build_pointer_type (class);
          return patch;
@@ -11577,8 +11543,7 @@ java_complete_tree (tree node)
 {
   node = java_complete_lhs (node);
   if (JDECL_P (node) && CLASS_FINAL_VARIABLE_P (node)
-      && DECL_INITIAL (node) != NULL_TREE
-      && !flag_emit_xref)
+      && DECL_INITIAL (node) != NULL_TREE)
     {
       tree value = fold_constant_for_init (node, node);
       if (value != NULL_TREE)
@@ -11780,7 +11745,7 @@ java_complete_lhs (tree node)
               && DECL_INITIAL (cn))
        cn = fold_constant_for_init (DECL_INITIAL (cn), cn);
 
-      if (!TREE_CONSTANT (cn) && !flag_emit_xref)
+      if (!TREE_CONSTANT (cn))
        {
          EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);
          parse_error_context (node, "Constant expression required");
@@ -11965,17 +11930,9 @@ java_complete_lhs (tree node)
       if (!EXPR_WFL_NODE (node) /* Or a PRIMARY flag ? */
          || TREE_CODE (EXPR_WFL_NODE (node)) == IDENTIFIER_NODE)
        {
-         tree wfl = node;
          node = resolve_expression_name (node, NULL);
          if (node == error_mark_node)
            return node;
-         /* Keep line number information somewhere were it doesn't
-            disrupt the completion process. */
-         if (flag_emit_xref && TREE_CODE (node) != CALL_EXPR)
-           {
-             EXPR_WFL_NODE (wfl) = TREE_OPERAND (node, 1);
-             TREE_OPERAND (node, 1) = wfl;
-           }
          CAN_COMPLETE_NORMALLY (node) = 1;
        }
       else
@@ -12291,11 +12248,6 @@ java_complete_lhs (tree node)
     case INSTANCEOF_EXPR:
       wfl_op1 = TREE_OPERAND (node, 0);
       COMPLETE_CHECK_OP_0 (node);
-      if (flag_emit_xref)
-       {
-         TREE_TYPE (node) = boolean_type_node;
-         return node;
-       }
       return patch_binop (node, wfl_op1, TREE_OPERAND (node, 1));
 
     case UNARY_PLUS_EXPR:
@@ -12325,14 +12277,14 @@ java_complete_lhs (tree node)
       TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1);
       if (TREE_OPERAND (node, 0) == error_mark_node)
        return error_mark_node;
-      if (!flag_emit_class_files && !flag_emit_xref)
+      if (!flag_emit_class_files)
        TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
       /* The same applies to wfl_op2 */
       wfl_op2 = TREE_OPERAND (node, 1);
       TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2);
       if (TREE_OPERAND (node, 1) == error_mark_node)
        return error_mark_node;
-      if (!flag_emit_class_files && !flag_emit_xref)
+      if (!flag_emit_class_files)
        TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
       return patch_array_ref (node);
 
@@ -12897,7 +12849,6 @@ patch_assignment (tree node, tree wfl_op1)
 
   /* 10.10: Array Store Exception runtime check */
   if (!flag_emit_class_files
-      && !flag_emit_xref
       && lvalue_from_array
       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type)))
     {
@@ -13798,7 +13749,9 @@ patch_binop (tree node, tree wfl_op1, tree wfl_op2)
       /* Types have to be either references or the null type. If
          they're references, it must be possible to convert either
          type to the other by casting conversion. */
-      else if (op1 == null_pointer_node || op2 == null_pointer_node
+      else if ((op1 == null_pointer_node && op2 == null_pointer_node)
+               || (op1 == null_pointer_node && JREFERENCE_TYPE_P (op2_type))
+               || (JREFERENCE_TYPE_P (op1_type) && op2 == null_pointer_node)
               || (JREFERENCE_TYPE_P (op1_type) && JREFERENCE_TYPE_P (op2_type)
                   && (valid_ref_assignconv_cast_p (op1_type, op2_type, 1)
                       || valid_ref_assignconv_cast_p (op2_type,
@@ -13835,9 +13788,6 @@ patch_binop (tree node, tree wfl_op1, tree wfl_op2)
   TREE_TYPE (node) = prom_type;
   TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
 
-  if (flag_emit_xref)
-    return node;
-
   /* fold does not respect side-effect order as required for Java but not C.
    * Also, it sometimes create SAVE_EXPRs which are bad when emitting
    * bytecode.
@@ -13982,9 +13932,6 @@ build_string_concatenation (tree op1, tree op2)
   tree result;
   int side_effects = TREE_SIDE_EFFECTS (op1) | TREE_SIDE_EFFECTS (op2);
 
-  if (flag_emit_xref)
-    return build2 (PLUS_EXPR, string_type_node, op1, op2);
-
   /* Try to do some static optimization */
   if ((result = string_constant_concatenation (op1, op2)))
     return result;
@@ -14030,8 +13977,7 @@ build_string_concatenation (tree op1, tree op2)
       /* OP1 is no longer the last node holding a crafted StringBuffer */
       IS_CRAFTED_STRING_BUFFER_P (op1) = 0;
       /* Create a node for `{new...,xxx}.append (op2)' */
-      if (op2)
-       op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
+      op1 = make_qualified_primary (op1, BUILD_APPEND (op2), 0);
     }
 
   /* Mark the last node holding a crafted StringBuffer */
@@ -14599,7 +14545,7 @@ patch_array_ref (tree node)
 
   array_type = TYPE_ARRAY_ELEMENT (array_type);
 
-  if (flag_emit_class_files || flag_emit_xref)
+  if (flag_emit_class_files)
     {
       TREE_OPERAND (node, 0) = array;
       TREE_OPERAND (node, 1) = index;
@@ -15762,14 +15708,6 @@ patch_synchronized_statement (tree node, tree wfl_op1)
       return error_mark_node;
     }
 
-  if (flag_emit_xref)
-    {
-      TREE_OPERAND (node, 0) = expr;
-      TREE_OPERAND (node, 1) = java_complete_tree (block);
-      CAN_COMPLETE_NORMALLY (node) = 1;
-      return node;
-    }
-
   /* Generate a try-finally for the synchronized statement, except
      that the handler that catches all throw exception calls
      _Jv_MonitorExit and then rethrow the exception.
@@ -15894,12 +15832,9 @@ patch_throw_statement (tree node, tree wfl_op1)
       return error_mark_node;
     }
 
-  if (! flag_emit_class_files && ! flag_emit_xref)
+  if (! flag_emit_class_files)
     BUILD_THROW (node, expr);
 
-  /* If doing xrefs, keep the location where the `throw' was seen. */
-  if (flag_emit_xref)
-    EXPR_WFL_LINECOL (node) = EXPR_WFL_LINECOL (wfl_op1);
   return node;
 }
 
@@ -16045,8 +15980,10 @@ patch_conditional_expr (tree node, tree wfl_cond, tree wfl_op1)
   tree t1, t2, patched;
   int error_found = 0;
 
-  /* Operands of ?: might be StringBuffers crafted as a result of a
-     string concatenation. Obtain a descent operand here.  */
+  /* The condition and operands of ?: might be StringBuffers crafted
+     as a result of a string concatenation.  Obtain decent ones here.  */
+  if ((patched = patch_string (cond)))
+    TREE_OPERAND (node, 0) = cond = patched;
   if ((patched = patch_string (op1)))
     TREE_OPERAND (node, 1) = op1 = patched;
   if ((patched = patch_string (op2)))
@@ -16152,7 +16089,7 @@ static tree
 maybe_build_class_init_for_field (tree decl, tree expr)
 {
   tree clas = DECL_CONTEXT (decl);
-  if (flag_emit_class_files || flag_emit_xref)
+  if (flag_emit_class_files)
     return expr;
 
   if (TREE_CODE (decl) == VAR_DECL && FIELD_STATIC (decl)