OSDN Git Service

* lang.c (java_classify_record): Don't return
[pf3gnuchains/gcc-fork.git] / gcc / java / lang.c
index b9429a1..4dc1f19 100644 (file)
@@ -1,12 +1,12 @@
 /* Java(TM) language-specific utility routines.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+   2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.
 
 Java and all Java-based marks are trademarks or registered trademarks
 of Sun Microsystems, Inc. in the United States and other countries.
@@ -39,7 +38,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "langhooks.h"
 #include "langhooks-def.h"
 #include "flags.h"
-#include "xref.h"
 #include "ggc.h"
 #include "diagnostic.h"
 #include "tree-inline.h"
@@ -56,18 +54,18 @@ static bool java_post_options (const char **);
 static int java_handle_option (size_t scode, const char *arg, int value);
 static void put_decl_string (const char *, int);
 static void put_decl_node (tree);
-static void java_print_error_function (diagnostic_context *, const char *);
-static tree java_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
-                                             void *, void *);
+static void java_print_error_function (diagnostic_context *, const char *,
+                                      diagnostic_info *);
 static int merge_init_test_initialization (void * *, void *);
 static int inline_init_test_initialization (void * *, void *);
-static bool java_can_use_bit_fields_p (void);
 static bool java_dump_tree (void *, tree);
 static void dump_compound_expr (dump_info_p, tree);
-static bool java_decl_ok_for_sibcall (tree);
-static tree java_get_callee_fndecl (tree);
+static bool java_decl_ok_for_sibcall (const_tree);
+static tree java_get_callee_fndecl (const_tree);
 static void java_clear_binding_stack (void);
 
+static enum classify_record java_classify_record (tree type);
+
 #ifndef TARGET_OBJECT_SUFFIX
 # define TARGET_OBJECT_SUFFIX ".o"
 #endif
@@ -78,9 +76,9 @@ static void java_clear_binding_stack (void);
 
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
 
-const char tree_code_type[] = {
+const enum tree_code_class tree_code_type[] = {
 #include "tree.def"
-  'x',
+  tcc_exceptional,
 #include "java-tree.def"
 };
 #undef DEFTREECODE
@@ -109,32 +107,37 @@ const char *const tree_code_name[] = {
 };
 #undef DEFTREECODE
 
+/* Table of machine-independent attributes.  */
+const struct attribute_spec java_attribute_table[] =
+{
+ { "nonnull",                0, -1, false, true, true,
+                             NULL },
+  { NULL,                     0, 0, false, false, false, NULL }
+};
+
 /* Used to avoid printing error messages with bogus function
    prototypes.  Starts out false.  */
 static bool inhibit_error_function_printing;
 
-int compiling_from_source;
-
 const char *resource_name;
 
-/* When nonzero, we emit xref strings. Values of the flag for xref
-   backends are defined in xref_flag_table, xref.c.  */
-
-int flag_emit_xref = 0;
-
 /* When nonzero, -Wall was turned on.  */
 int flag_wall = 0;
 
-/* The encoding of the source file.  */
-const char *current_encoding = NULL;
+/* When nonzero, report use of deprecated classes, methods, or fields.  */
+int flag_deprecated = 1;
+
+/* When zero, don't optimize static class initialization. This flag shouldn't
+   be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
+/* FIXME: Make this work with gimplify.  */
+/* int flag_optimize_sci = 0;  */
+
+/* Don't attempt to verify invocations.  */
+int flag_verify_invocations = 0; 
 
 /* When nonzero, print extra version information.  */
 static int v_flag = 0;
 
-/* Set nonzero if the user specified -finline-functions on the command
-   line.  */
-int flag_really_inline = 0;
-
 JCF *current_jcf;
 
 /* Variable controlling how dependency tracking is enabled in
@@ -168,27 +171,19 @@ struct language_function GTY(())
 #define LANG_HOOKS_PARSE_FILE java_parse_file
 #undef LANG_HOOKS_MARK_ADDRESSABLE
 #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
-#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
-#define LANG_HOOKS_TRUTHVALUE_CONVERSION java_truthvalue_conversion
 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL java_dup_lang_specific_decl
 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
 #define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name
 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
 #define LANG_HOOKS_PRINT_ERROR_FUNCTION        java_print_error_function
-#undef LANG_HOOKS_CAN_USE_BIT_FIELDS_P
-#define LANG_HOOKS_CAN_USE_BIT_FIELDS_P java_can_use_bit_fields_p
 
 #undef LANG_HOOKS_TYPE_FOR_MODE
 #define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode
 #undef LANG_HOOKS_TYPE_FOR_SIZE
 #define LANG_HOOKS_TYPE_FOR_SIZE java_type_for_size
-#undef LANG_HOOKS_SIGNED_TYPE
-#define LANG_HOOKS_SIGNED_TYPE java_signed_type
-#undef LANG_HOOKS_UNSIGNED_TYPE
-#define LANG_HOOKS_UNSIGNED_TYPE java_unsigned_type
-#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
-#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type
+#undef LANG_HOOKS_CLASSIFY_RECORD
+#define LANG_HOOKS_CLASSIFY_RECORD java_classify_record
 
 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
@@ -196,21 +191,21 @@ struct language_function GTY(())
 #undef LANG_HOOKS_GIMPLIFY_EXPR
 #define LANG_HOOKS_GIMPLIFY_EXPR java_gimplify_expr
 
-#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
-#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
-
 #undef LANG_HOOKS_DECL_OK_FOR_SIBCALL
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall
 
 #undef LANG_HOOKS_GET_CALLEE_FNDECL
 #define LANG_HOOKS_GET_CALLEE_FNDECL java_get_callee_fndecl
 
-#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
-#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION java_expand_body
-
 #undef LANG_HOOKS_CLEAR_BINDING_STACK
 #define LANG_HOOKS_CLEAR_BINDING_STACK java_clear_binding_stack
 
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
+
+#undef LANG_HOOKS_ATTRIBUTE_TABLE
+#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
+
 /* Each front end provides its own.  */
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
@@ -265,8 +260,6 @@ java_handle_option (size_t scode, const char *arg, int value)
 
     case OPT_Wall:
       flag_wall = value;
-      flag_redundant = value;
-      flag_extraneous_semicolon = value;
       /* When -Wall given, enable -Wunused.  We do this because the C
         compiler does it, and people expect it.  */
       set_Wunused (value);
@@ -300,6 +293,7 @@ java_handle_option (size_t scode, const char *arg, int value)
       jcf_path_bootclasspath_arg (arg);
       break;
 
+    case OPT_faux_classpath:
     case OPT_fclasspath_:
     case OPT_fCLASSPATH_:
       jcf_path_classpath_arg (arg);
@@ -315,30 +309,29 @@ java_handle_option (size_t scode, const char *arg, int value)
       break;
 
     case OPT_fencoding_:
-      current_encoding = arg;
+      /* Nothing.  */
       break;
 
     case OPT_fextdirs_:
       jcf_path_extdirs_arg (arg);
       break;
 
-    case OPT_finline_functions:
-      flag_inline_functions = value;
-      flag_really_inline = value;
-      break;
-
     case OPT_foutput_class_dir_:
-      jcf_write_base_directory = arg;
+      /* FIXME: remove; this is handled by ecj1 now.  */
       break;
 
     case OPT_version:
       v_flag = 1;
       break;
       
+    case OPT_fsource_filename_:
+      java_read_sourcefilenames (arg);
+      break;
+      
     default:
       if (cl_options[code].flags & CL_Java)
        break;
-      abort();
+      gcc_unreachable ();
     }
 
   return 1;
@@ -350,25 +343,13 @@ FILE *finput;
 static bool
 java_init (void)
 {
-#if 0
-  extern int flag_minimal_debug;
-  flag_minimal_debug = 0;
-#endif
-
-  if (flag_inline_functions)
-    flag_inline_trees = 1;
-
   /* FIXME: Indirect dispatch isn't yet compatible with static class
      init optimization.  */
   if (flag_indirect_dispatch)
     always_initialize_class_p = true;
 
-  /* Force minimum function alignment if g++ uses the least significant
-     bit of function pointers to store the virtual bit. This is required
-     to keep vtables compatible.  */
-  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
-      && force_align_functions_log < 1)
-    force_align_functions_log = 1;
+  if (!flag_indirect_dispatch)
+    flag_indirect_classes = false;
 
   jcf_path_seal (v_flag);
 
@@ -407,7 +388,7 @@ put_decl_string (const char *str, int len)
       if (decl_buf == NULL)
        {
          decl_buflen = len + 100;
-         decl_buf = xmalloc (decl_buflen);
+         decl_buf = XNEWVEC (char, decl_buflen);
        }
       else
        {
@@ -430,8 +411,7 @@ put_decl_node (tree node)
       node = TREE_TYPE (node);
       was_pointer = 1;
     }
-  if (TREE_CODE_CLASS (TREE_CODE (node)) == 'd'
-      && DECL_NAME (node) != NULL_TREE)
+  if (DECL_P (node) && DECL_NAME (node) != NULL_TREE)
     {
       if (TREE_CODE (node) == FUNCTION_DECL)
        {
@@ -464,8 +444,7 @@ put_decl_node (tree node)
       else
        put_decl_node (DECL_NAME (node));
     }
-  else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't'
-      && TYPE_NAME (node) != NULL_TREE)
+  else if (TYPE_P (node) && TYPE_NAME (node) != NULL_TREE)
     {
       if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node))
        {
@@ -515,7 +494,8 @@ static GTY(()) tree last_error_function_context;
 static GTY(()) tree last_error_function;
 static void
 java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
-                          const char *file)
+                          const char *file,
+                          diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
 {
   /* Don't print error messages with bogus function prototypes.  */
   if (inhibit_error_function_printing)
@@ -528,7 +508,7 @@ java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
        fprintf (stderr, "%s: ", file);
 
       last_error_function_context = DECL_CONTEXT (current_function_decl);
-      fprintf (stderr, "In class `%s':\n",
+      fprintf (stderr, "In class '%s':\n",
               lang_printable_name (last_error_function_context, 0));
     }
   if (last_error_function != current_function_decl)
@@ -541,7 +521,7 @@ java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
       else
        {
          const char *name = lang_printable_name (current_function_decl, 2);
-         fprintf (stderr, "In %s `%s':\n",
+         fprintf (stderr, "In %s '%s':\n",
                   (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor"
                    : "method"),
                   name);
@@ -582,19 +562,15 @@ java_init_options (unsigned int argc ATTRIBUTE_UNUSED,
   /* Java requires left-to-right evaluation of subexpressions.  */
   flag_evaluation_order = 1;
 
+  /* Unit at a time is disabled for Java because it is considered
+     too expensive.  */
+  no_unit_at_a_time_default = 1;
+
   jcf_path_init ();
 
   return CL_Java;
 }
 
-static bool
-java_can_use_bit_fields_p (void)
-{
-  /* The bit-field optimizations cause problems when generating class
-     files.  */
-  return flag_emit_class_files ? false : true;
-}
-
 /* Post-switch processing.  */
 static bool
 java_post_options (const char **pfilename)
@@ -605,9 +581,20 @@ java_post_options (const char **pfilename)
   if (!flag_no_inline)
     flag_no_inline = 1;
   if (flag_inline_functions)
+    flag_inline_trees = 2;
+
+  /* An absolute requirement: if we're not using indirect dispatch, we
+     must always verify everything.  */
+  if (! flag_indirect_dispatch)
+    flag_verify_invocations = true;
+
+  if (flag_reduced_reflection)
     {
-      flag_inline_trees = 2;
-      flag_inline_functions = 0;
+      if (flag_indirect_dispatch)
+        error ("-findirect-dispatch is incompatible "
+               "with -freduced-reflection");
+      if (flag_jni)
+        error ("-fjni is incompatible with -freduced-reflection");
     }
 
   /* Open input file.  */
@@ -637,7 +624,7 @@ java_post_options (const char **pfilename)
                error ("couldn't determine target name for dependency tracking");
              else
                {
-                 char *buf = xmalloc (dot - filename +
+                 char *buf = XNEWVEC (char, dot - filename +
                                       3 + sizeof (TARGET_OBJECT_SUFFIX));
                  strncpy (buf, filename, dot - filename);
 
@@ -647,8 +634,6 @@ java_post_options (const char **pfilename)
                     target name here.  */
                  if ((dependency_tracking & DEPEND_TARGET_SET))
                    ; /* Nothing.  */
-                 else if (flag_emit_class_files)
-                   jcf_dependency_set_target (NULL);
                  else
                    {
                      strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX);
@@ -670,6 +655,10 @@ java_post_options (const char **pfilename)
            }
        }
     }
+#ifdef USE_MAPPED_LOCATION
+  linemap_add (line_table, LC_ENTER, false, filename, 0);
+  linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
+#endif
 
   /* Initialize the compiler back end.  */
   return false;
@@ -697,45 +686,6 @@ decl_constant_value (tree decl)
   return decl;
 }
 
-/* Walk the language specific tree nodes during inlining.  */
-
-static tree
-java_tree_inlining_walk_subtrees (tree *tp ATTRIBUTE_UNUSED,
-                                 int *subtrees ATTRIBUTE_UNUSED,
-                                 walk_tree_fn func ATTRIBUTE_UNUSED,
-                                 void *data ATTRIBUTE_UNUSED,
-                                 void *htab ATTRIBUTE_UNUSED)
-{
-  enum tree_code code;
-  tree result;
-
-#define WALK_SUBTREE(NODE)                             \
-  do                                                   \
-    {                                                  \
-      result = walk_tree (&(NODE), func, data, htab);  \
-      if (result)                                      \
-       return result;                                  \
-    }                                                  \
-  while (0)
-
-  tree t = *tp;
-  if (!t)
-    return NULL_TREE;
-
-  code = TREE_CODE (t);
-  switch (code)
-    {
-    case BLOCK:
-      WALK_SUBTREE (BLOCK_EXPR_BODY (t));
-      return NULL_TREE;
-
-    default:
-      return NULL_TREE;
-    }
-
-  #undef WALK_SUBTREE
-}
-
 /* Every call to a static constructor has an associated boolean
    variable which is in the outermost scope of the calling method.
    This variable is used to avoid multiple calls to the static
@@ -775,8 +725,7 @@ merge_init_test_initialization (void **entry, void *x)
   /* See if we have remapped this declaration.  If we haven't there's
      a bug in the inliner.  */
   n = splay_tree_lookup (decl_map, (splay_tree_key) ite->value);
-  if (! n)
-    abort ();
+  gcc_assert (n);
 
   /* Create a new entry for the class and its remapped boolean
      variable.  If we already have a mapping for this class we've
@@ -793,7 +742,7 @@ merge_init_test_initialization (void **entry, void *x)
   does this by setting the DECL_INITIAL of the init_test_decl for that
   class, and no initializations are emitted for that class.
 
-  However, what if the method that is suppoed to do the initialization
+  However, what if the method that is supposed to do the initialization
   is itself inlined in the caller?  When expanding the called method
   we'll assume that the class initialization has already been done,
   because the DECL_INITIAL of the init_test_decl is set.
@@ -868,13 +817,6 @@ dump_compound_expr (dump_info_p di, tree t)
          dump_compound_expr (di, TREE_OPERAND (t, i));
          break;
 
-       case EXPR_WITH_FILE_LOCATION:
-           {
-             tree wfl_node = EXPR_WFL_NODE (TREE_OPERAND (t, i));
-             dump_child ("expr", wfl_node);
-             break;
-           }
-
        default:
          dump_child ("expr", TREE_OPERAND (t, i));
        }
@@ -900,8 +842,6 @@ java_dump_tree (void *dump_info, tree t)
        dump_string (di, "extern");
       else
        dump_string (di, "static");
-      if (DECL_LANG_SPECIFIC (t))
-       dump_child ("body", DECL_FUNCTION_BODY (t));
       if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
        dump_child ("inline body", DECL_SAVED_TREE (t));
       return true;
@@ -918,16 +858,6 @@ java_dump_tree (void *dump_info, tree t)
       dump_child ("label", TREE_OPERAND (t, 0));
       return true;
 
-    case LABELED_BLOCK_EXPR:
-      dump_child ("label", TREE_OPERAND (t, 0));
-      dump_child ("block", TREE_OPERAND (t, 1));
-      return true;
-
-    case EXIT_BLOCK_EXPR:
-      dump_child ("block", TREE_OPERAND (t, 0));
-      dump_child ("val", TREE_OPERAND (t, 1));
-      return true;
-
     case BLOCK:
       if (BLOCK_EXPR_BODY (t))
        {
@@ -965,9 +895,10 @@ java_dump_tree (void *dump_info, tree t)
    SecurityManager.getClassContext().  */
 
 static bool
-java_decl_ok_for_sibcall (tree decl)
+java_decl_ok_for_sibcall (const_tree decl)
 {
-  return decl != NULL && DECL_CONTEXT (decl) == output_class;
+  return (decl != NULL && DECL_CONTEXT (decl) == output_class
+         && DECL_INLINE (decl));
 }
 
 /* Given a call_expr, try to figure out what its target might be.  In
@@ -976,15 +907,19 @@ java_decl_ok_for_sibcall (tree decl)
    will replace the indirection with a direct call, which undoes the
    purpose of the atable indirection.  */
 static tree
-java_get_callee_fndecl (tree call_expr)
+java_get_callee_fndecl (const_tree call_expr)
 {
   tree method, table, element, atable_methods;
 
   HOST_WIDE_INT index;
 
+  /* FIXME: This is disabled because we end up passing calls through
+     the PLT, and we do NOT want to do that.  */
+  return NULL;
+
   if (TREE_CODE (call_expr) != CALL_EXPR)
     return NULL;
-  method = TREE_OPERAND (call_expr, 0);
+  method = CALL_EXPR_FN (call_expr);
   STRIP_NOPS (method);
   if (TREE_CODE (method) != ARRAY_REF)
     return NULL;
@@ -1024,4 +959,18 @@ java_clear_binding_stack (void)
     poplevel (0, 0, 0);
 }
 
+static enum classify_record
+java_classify_record (tree type)
+{
+  if (! CLASS_P (type))
+    return RECORD_IS_STRUCT;
+
+  /* ??? GDB does not support DW_TAG_interface_type as of December,
+     2007.  Re-enable this at a later time.  */
+  if (0 && CLASS_INTERFACE (TYPE_NAME (type)))
+    return RECORD_IS_INTERFACE;
+
+  return RECORD_IS_CLASS;
+}
+
 #include "gt-java-lang.h"