OSDN Git Service

* exp_pakd.adb (Create_Packed_Array_Type): Always use a modular type
[pf3gnuchains/gcc-fork.git] / gcc / java / lang.c
index 3f2af64..22fe4ff 100644 (file)
@@ -1,12 +1,12 @@
 /* Java(TM) language-specific utility routines.
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008 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, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, 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.
@@ -46,6 +45,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "tree-dump.h"
 #include "opts.h"
 #include "options.h"
+#include "except.h"
 
 static bool java_init (void);
 static void java_finish (void);
@@ -54,59 +54,23 @@ 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 *, struct pointer_set_t *);
+static void put_decl_node (tree, int);
+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_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 (const_tree);
-static void java_clear_binding_stack (void);
+static bool java_decl_ok_for_sibcall (const_tree);
+
+static enum classify_record java_classify_record (tree type);
+
+static tree java_eh_personality (void);
 
 #ifndef TARGET_OBJECT_SUFFIX
 # define TARGET_OBJECT_SUFFIX ".o"
 #endif
 
-/* Table indexed by tree code giving a string containing a character
-   classifying the tree code.  Possibilities are
-   t, d, s, c, r, <, 1 and 2.  See java/java-tree.def for details.  */
-
-#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
-
-const enum tree_code_class tree_code_type[] = {
-#include "tree.def"
-  tcc_exceptional,
-#include "java-tree.def"
-};
-#undef DEFTREECODE
-
-/* Table indexed by tree code giving number of expression
-   operands beyond the fixed part of the node structure.
-   Not used for types or decls.  */
-
-#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
-
-const unsigned char tree_code_length[] = {
-#include "tree.def"
-  0,
-#include "java-tree.def"
-};
-#undef DEFTREECODE
-
-/* Names of tree components.
-   Used for printing out the tree and error messages.  */
-#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
-
-const char *const tree_code_name[] = {
-#include "tree.def"
-  "@@dummy",
-#include "java-tree.def"
-};
-#undef DEFTREECODE
-
 /* Table of machine-independent attributes.  */
 const struct attribute_spec java_attribute_table[] =
 {
@@ -150,8 +114,7 @@ static int dependency_tracking = 0;
 #define DEPEND_TARGET_SET 4
 #define DEPEND_FILE_ALREADY_SET 8
 
-struct language_function GTY(())
-{
+struct GTY(()) language_function {
   int unused;
 };
 
@@ -169,8 +132,6 @@ struct language_function GTY(())
 #define LANG_HOOKS_POST_OPTIONS java_post_options
 #undef LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE java_parse_file
-#undef LANG_HOOKS_MARK_ADDRESSABLE
-#define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
 #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
@@ -182,6 +143,8 @@ struct language_function GTY(())
 #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_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
@@ -189,29 +152,23 @@ 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
 
+#undef LANG_HOOKS_EH_PERSONALITY
+#define LANG_HOOKS_EH_PERSONALITY java_eh_personality
+
+#undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP
+#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP  true
+
 /* Each front end provides its own.  */
-const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
 /*
  * process java-specific compiler command-line options
@@ -266,7 +223,7 @@ java_handle_option (size_t scode, const char *arg, int value)
       flag_wall = value;
       /* When -Wall given, enable -Wunused.  We do this because the C
         compiler does it, and people expect it.  */
-      set_Wunused (value);
+      warn_unused = value;
       break;
 
     case OPT_fenable_assertions_:
@@ -397,17 +354,20 @@ put_decl_string (const char *str, int len)
       else
        {
          decl_buflen *= 2;
-         decl_buf = xrealloc (decl_buf, decl_buflen);
+         decl_buf = XRESIZEVAR (char, decl_buf, decl_buflen);
        }
     }
   strcpy (decl_buf + decl_bufpos, str);
   decl_bufpos += len;
 }
 
-/* Append to decl_buf a printable name for NODE. */
+/* Append to decl_buf a printable name for NODE.
+   Depending on VERBOSITY, more information about NODE
+   is printed. Read the comments of decl_printable_name in
+   langhooks.h for more.  */
 
 static void
-put_decl_node (tree node)
+put_decl_node (tree node, int verbosity)
 {
   int was_pointer = 0;
   if (TREE_CODE (node) == POINTER_TYPE)
@@ -419,17 +379,32 @@ put_decl_node (tree node)
     {
       if (TREE_CODE (node) == FUNCTION_DECL)
        {
+         if (verbosity == 0 && DECL_NAME (node))
+         /* We have been instructed to just print the bare name
+            of the function.  */
+           {
+             put_decl_node (DECL_NAME (node), 0);
+             return;
+           }
+
          /* We want to print the type the DECL belongs to. We don't do
             that when we handle constructors. */
          if (! DECL_CONSTRUCTOR_P (node)
-             && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node))
+             && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node)
+              /* We want to print qualified DECL names only
+                 if verbosity is higher than 1.  */
+              && verbosity >= 1)
            {
-             put_decl_node (TYPE_NAME (DECL_CONTEXT (node)));
+             put_decl_node (TYPE_NAME (DECL_CONTEXT (node)),
+                               verbosity);
              put_decl_string (".", 1);
            }
          if (! DECL_CONSTRUCTOR_P (node))
-           put_decl_node (DECL_NAME (node));
-         if (TREE_TYPE (node) != NULL_TREE)
+           put_decl_node (DECL_NAME (node), verbosity);
+         if (TREE_TYPE (node) != NULL_TREE
+              /* We want to print function parameters only if verbosity
+                 is higher than 2.  */
+              && verbosity >= 2)
            {
              int i = 0;
              tree args = TYPE_ARG_TYPES (TREE_TYPE (node));
@@ -440,19 +415,22 @@ put_decl_node (tree node)
                {
                  if (i > 0)
                    put_decl_string (",", 1);
-                 put_decl_node (TREE_VALUE (args));
+                 put_decl_node (TREE_VALUE (args), verbosity);
                }
              put_decl_string (")", 1);
            }
        }
       else
-       put_decl_node (DECL_NAME (node));
+       put_decl_node (DECL_NAME (node), verbosity);
     }
   else if (TYPE_P (node) && TYPE_NAME (node) != NULL_TREE)
     {
-      if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node))
+      if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node)
+          /* Print detailed array information only if verbosity is higher
+            than 2.  */
+          && verbosity >= 2)
        {
-         put_decl_node (TYPE_ARRAY_ELEMENT (node));
+         put_decl_node (TYPE_ARRAY_ELEMENT (node), verbosity);
          put_decl_string("[]", 2);
        }
       else if (node == promoted_byte_type_node)
@@ -466,7 +444,7 @@ put_decl_node (tree node)
       else if (node == void_type_node && was_pointer)
        put_decl_string ("null", 4);
       else
-       put_decl_node (TYPE_NAME (node));
+       put_decl_node (TYPE_NAME (node), verbosity);
     }
   else if (TREE_CODE (node) == IDENTIFIER_NODE)
     put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node));
@@ -483,10 +461,7 @@ const char *
 lang_printable_name (tree decl, int v)
 {
   decl_bufpos = 0;
-  if (v == 0 && TREE_CODE (decl) == FUNCTION_DECL)
-    put_decl_node (DECL_NAME (decl));
-  else
-    put_decl_node (decl);
+  put_decl_node (decl, v);
   put_decl_string ("", 1);
   return decl_buf;
 }
@@ -498,7 +473,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)
@@ -565,10 +541,6 @@ 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;
@@ -580,11 +552,12 @@ java_post_options (const char **pfilename)
 {
   const char *filename = *pfilename;
 
-  /* Use tree inlining.  */
-  if (!flag_no_inline)
-    flag_no_inline = 1;
-  if (flag_inline_functions)
-    flag_inline_trees = 2;
+  /* Excess precision other than "fast" requires front-end
+     support.  */
+  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
+      && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
+    sorry ("-fexcess-precision=standard for Java");
+  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
 
   /* An absolute requirement: if we're not using indirect dispatch, we
      must always verify everything.  */
@@ -614,7 +587,7 @@ java_post_options (const char **pfilename)
     {
       if (dependency_tracking)
        {
-         char *dot;
+         const char *dot;
 
          /* If the target is set and the output filename is set, then
             there's no processing to do here.  Otherwise we must
@@ -658,10 +631,8 @@ 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
+  linemap_add (line_table, LC_ENTER, false, filename, 0);
+  linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
 
   /* Initialize the compiler back end.  */
   return false;
@@ -689,45 +660,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,
-                                 struct pointer_set_t *pset ATTRIBUTE_UNUSED)
-{
-  enum tree_code code;
-  tree result;
-
-#define WALK_SUBTREE(NODE)                             \
-  do                                                   \
-    {                                                  \
-      result = walk_tree (&(NODE), func, data, pset);  \
-      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
@@ -884,8 +816,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;
@@ -939,68 +869,38 @@ 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
-         && DECL_INLINE (decl));
+          && !DECL_UNINLINABLE (decl));
 }
 
-/* Given a call_expr, try to figure out what its target might be.  In
-   the case of an indirection via the atable, search for the decl.  If
-   the decl is external, we return NULL.  If we don't, the optimizer
-   will replace the indirection with a direct call, which undoes the
-   purpose of the atable indirection.  */
-static tree
-java_get_callee_fndecl (const_tree call_expr)
+static enum classify_record
+java_classify_record (tree type)
 {
-  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 = CALL_EXPR_FN (call_expr);
-  STRIP_NOPS (method);
-  if (TREE_CODE (method) != ARRAY_REF)
-    return NULL;
-  table = TREE_OPERAND (method, 0);
-  if (! DECL_LANG_SPECIFIC(table)
-      || !DECL_OWNER (table)
-      || TYPE_ATABLE_DECL (DECL_OWNER (table)) != table)
-    return NULL;
-
-  atable_methods = TYPE_ATABLE_METHODS (DECL_OWNER (table));
-  index = TREE_INT_CST_LOW (TREE_OPERAND (method, 1));
-
-  /* FIXME: Replace this for loop with a hash table lookup.  */
-  for (element = atable_methods; element; element = TREE_CHAIN (element))
-    {
-      if (index == 1)
-       {
-         tree purpose = TREE_PURPOSE (element);
-         if (TREE_CODE (purpose) == FUNCTION_DECL
-             && ! DECL_EXTERNAL (purpose))
-           return purpose;
-         else
-           return NULL;
-       }
-      --index;
-    }
+  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 NULL;
+  return RECORD_IS_CLASS;
 }
 
+static GTY(()) tree java_eh_personality_decl;
 
-/* Clear the binding stack.  */
-static void
-java_clear_binding_stack (void)
+static tree
+java_eh_personality (void)
 {
-  while (!global_bindings_p ())
-    poplevel (0, 0, 0);
+  if (!java_eh_personality_decl)
+    java_eh_personality_decl
+      = build_personality_function (USING_SJLJ_EXCEPTIONS
+                                   ? "__gcj_personality_sj0"
+                                   : "__gcj_personality_v0");
+
+  return java_eh_personality_decl;
 }
 
 #include "gt-java-lang.h"