OSDN Git Service

* simplify-rtx.c (simplify_subreg): Fix verification of
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index dcacdaf..2461c9b 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -44,7 +44,6 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "hashtab.h"
 #include "output.h"
-#include "defaults.h"
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
@@ -170,6 +169,7 @@ static unsigned int type_hash_hash PARAMS ((const void*));
 static void print_type_hash_statistics PARAMS((void));
 static int mark_hash_entry PARAMS((void **, void *));
 static void finish_vector_type PARAMS((tree));
+static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
 /* If non-null, these are language-specific helper functions for
    unsave_expr_now.  If present, LANG_UNSAVE is called before its
@@ -182,10 +182,44 @@ void (*lang_unsave_expr_now) PARAMS ((tree));
 /* If non-null, these are language-specific helper functions for
    unsafe_for_reeval.  Return negative to not handle some tree.  */
 int (*lang_unsafe_for_reeval) PARAMS ((tree));
+
+/* Set the DECL_ASSEMBLER_NAME for a node.  If it is the sort of thing
+   that the assembler should talk about, set DECL_ASSEMBLER_NAME to an
+   appropriate IDENTIFIER_NODE.  Otherwise, set it to the
+   ERROR_MARK_NODE to ensure that the assembler does not talk about
+   it.  */
+void (*lang_set_decl_assembler_name)     PARAMS ((tree));
 \f
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
 \f
+/* Set the DECL_ASSEMBLER_NAME for DECL.  */
+void
+set_decl_assembler_name (decl)
+     tree decl;
+{
+  /* The language-independent code should never use the
+     DECL_ASSEMBLER_NAME for lots of DECLs.  Only FUNCTION_DECLs and
+     VAR_DECLs for variables with static storage duration need a real
+     DECL_ASSEMBLER_NAME.  */
+  if (TREE_CODE (decl) == FUNCTION_DECL
+      || (TREE_CODE (decl) == VAR_DECL 
+         && (TREE_STATIC (decl) 
+             || DECL_EXTERNAL (decl) 
+             || TREE_PUBLIC (decl))))
+    /* By default, assume the name to use in assembly code is the
+       same as that used in the source language.  (That's correct
+       for C, and GCC used to set DECL_ASSEMBLER_NAME to the same
+       value as DECL_NAME in build_decl, so this choice provides
+       backwards compatibility with existing front-ends.  */
+    SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+  else
+    /* Nobody should ever be asking for the DECL_ASSEMBLER_NAME of
+       these DECLs -- unless they're in language-dependent code, in
+       which case lang_set_decl_assembler_name should handle things.  */
+    abort ();
+}
+\f
 /* Init the principal obstacks.  */
 
 void
@@ -199,26 +233,9 @@ init_obstacks ()
   ggc_add_root (&type_hash_table, 1, sizeof type_hash_table, mark_type_hash);
   ggc_add_tree_root (global_trees, TI_MAX);
   ggc_add_tree_root (integer_types, itk_none);
-}
 
-void
-gcc_obstack_init (obstack)
-     struct obstack *obstack;
-{
-  /* Let particular systems override the size of a chunk.  */
-#ifndef OBSTACK_CHUNK_SIZE
-#define OBSTACK_CHUNK_SIZE 0
-#endif
-  /* Let them override the alloc and free routines too.  */
-#ifndef OBSTACK_CHUNK_ALLOC
-#define OBSTACK_CHUNK_ALLOC xmalloc
-#endif
-#ifndef OBSTACK_CHUNK_FREE
-#define OBSTACK_CHUNK_FREE free
-#endif
-  _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0,
-                 (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
-                 (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
+  /* Set lang_set_decl_set_assembler_name to a default value.  */
+  lang_set_decl_assembler_name = set_decl_assembler_name;
 }
 
 \f
@@ -468,10 +485,7 @@ make_lang_type (code)
 }
 \f
 /* Return a new node with the same contents as NODE except that its
-   TREE_CHAIN is zero and it has a fresh uid.  Unlike make_node, this
-   function always performs the allocation on the CURRENT_OBSTACK;
-   it's up to the caller to pick the right obstack before calling this
-   function.  */
+   TREE_CHAIN is zero and it has a fresh uid.  */
 
 tree
 copy_node (node)
@@ -1504,6 +1518,7 @@ staticp (arg)
 #endif
 
     case ARRAY_REF:
+    case ARRAY_RANGE_REF:
       if (TREE_CODE (TYPE_SIZE (TREE_TYPE (arg))) == INTEGER_CST
          && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST)
        return staticp (TREE_OPERAND (arg, 0));
@@ -2195,6 +2210,12 @@ stabilize_reference (ref)
                         stabilize_reference_1 (TREE_OPERAND (ref, 1)));
       break;
 
+    case ARRAY_RANGE_REF:
+      result = build_nt (ARRAY_RANGE_REF,
+                        stabilize_reference (TREE_OPERAND (ref, 0)),
+                        stabilize_reference_1 (TREE_OPERAND (ref, 1)));
+      break;
+
     case COMPOUND_EXPR:
       /* We cannot wrap the first expression in a SAVE_EXPR, as then
         it wouldn't be ignored.  This matters when dealing with
@@ -2326,6 +2347,7 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
   register int length;
   register int i;
   int fro;
+  int constant;
 
   VA_START (p, tt);
 
@@ -2344,6 +2366,13 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
      to do this.  */
   fro = first_rtl_op (code);
 
+  /* Expressions without side effects may be constant if their
+     arguments are as well.  */
+  constant = (TREE_CODE_CLASS (code) == '<'
+             || TREE_CODE_CLASS (code) == '1'
+             || TREE_CODE_CLASS (code) == '2'
+             || TREE_CODE_CLASS (code) == 'c');
+
   if (length == 2)
     {
       /* This is equivalent to the loop below, but faster.  */
@@ -2359,6 +2388,8 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
            TREE_SIDE_EFFECTS (t) = 1;
          if (!TREE_READONLY (arg0))
            TREE_READONLY (t) = 0;
+         if (!TREE_CONSTANT (arg0))
+           constant = 0;
        }
 
       if (arg1 && fro > 1)
@@ -2367,6 +2398,8 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
            TREE_SIDE_EFFECTS (t) = 1;
          if (!TREE_READONLY (arg1))
            TREE_READONLY (t) = 0;
+         if (!TREE_CONSTANT (arg1))
+           constant = 0;
        }
     }
   else if (length == 1)
@@ -2393,10 +2426,14 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
            {
              if (TREE_SIDE_EFFECTS (operand))
                TREE_SIDE_EFFECTS (t) = 1;
+             if (!TREE_CONSTANT (operand))
+               constant = 0;
            }
        }
     }
   va_end (p);
+
+  TREE_CONSTANT (t) = constant;
   return t;
 }
 
@@ -2423,6 +2460,13 @@ build1 (code, type, node)
     kind = e_kind;
 #endif
 
+#ifdef ENABLE_CHECKING
+  if (TREE_CODE_CLASS (code) == '2' 
+      || TREE_CODE_CLASS (code) == '<'
+      || TREE_CODE_LENGTH (code) != 1)
+    abort ();
+#endif /* ENABLE_CHECKING */
+
   length = sizeof (struct tree_exp);
 
   t = ggc_alloc_tree (length);
@@ -2462,6 +2506,8 @@ build1 (code, type, node)
       break;
 
     default:
+      if (TREE_CODE_CLASS (code) == '1' && node && TREE_CONSTANT (node))
+       TREE_CONSTANT (t) = 1;
       break;
     }
 
@@ -2500,36 +2546,6 @@ build_nt VPARAMS ((enum tree_code code, ...))
   return t;
 }
 
-/* Similar to `build_nt', except we build
-   on the temp_decl_obstack, regardless.  */
-
-tree
-build_parse_node VPARAMS ((enum tree_code code, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  enum tree_code code;
-#endif
-  va_list p;
-  register tree t;
-  register int length;
-  register int i;
-
-  VA_START (p, code);
-
-#ifndef ANSI_PROTOTYPES
-  code = va_arg (p, enum tree_code);
-#endif
-
-  t = make_node (code);
-  length = TREE_CODE_LENGTH (code);
-
-  for (i = 0; i < length; i++)
-    TREE_OPERAND (t, i) = va_arg (p, tree);
-
-  va_end (p);
-  return t;
-}
-
 #if 0
 /* Commented out because this wants to be done very
    differently.  See cp-lex.c.  */
@@ -2565,7 +2581,6 @@ build_decl (code, name, type)
    as the type can suppress useless errors in the use of this variable.  */
 
   DECL_NAME (t) = name;
-  DECL_ASSEMBLER_NAME (t) = name;
   TREE_TYPE (t) = type;
 
   if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL)
@@ -2965,31 +2980,47 @@ set_type_quals (type, type_quals)
   TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
 }
 
-/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for
-   the same kind of data as TYPE describes.  Variants point to the
-   "main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT,
-   and it points to a chain of other variants so that duplicate
-   variants are never made.  Only main variants should ever appear as
-   types of expressions.  */
+/* Return a version of the TYPE, qualified as indicated by the
+   TYPE_QUALS, if one exists.  If no qualified version exists yet,
+   return NULL_TREE.  */
 
 tree
-build_qualified_type (type, type_quals)
+get_qualified_type (type, type_quals)
      tree type;
      int type_quals;
 {
-  register tree t;
+  tree t;
 
   /* Search the chain of variants to see if there is already one there just
      like the one we need to have.  If so, use that existing one.  We must
      preserve the TYPE_NAME, since there is code that depends on this.  */
-
   for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type))
       return t;
 
-  /* We need a new one.  */
-  t = build_type_copy (type);
-  set_type_quals (t, type_quals);
+  return NULL_TREE;
+}
+
+/* Like get_qualified_type, but creates the type if it does not
+   exist.  This function never returns NULL_TREE.  */
+
+tree
+build_qualified_type (type, type_quals)
+     tree type;
+     int type_quals;
+{
+  tree t;
+
+  /* See if we already have the appropriate qualified variant.  */
+  t = get_qualified_type (type, type_quals);
+
+  /* If not, build it.  */
+  if (!t)
+    {
+      t = build_type_copy (type);
+      set_type_quals (t, type_quals);
+    }
+
   return t;
 }
 
@@ -3184,6 +3215,29 @@ mark_type_hash (arg)
   htab_traverse (t, mark_hash_entry, 0);
 }
 
+/* Mark the hashtable slot pointed to by ENTRY (which is really a
+   `tree**') for GC.  */
+
+static int
+mark_tree_hashtable_entry (entry, data)
+     void **entry;
+     void *data ATTRIBUTE_UNUSED;
+{
+  ggc_mark_tree ((tree) *entry);
+  return 1;
+}
+
+/* Mark ARG (which is really a htab_t whose slots are trees) for 
+   GC.  */
+
+void
+mark_tree_hashtable (arg)
+     void *arg;
+{
+  htab_t t = *(htab_t *) arg;
+  htab_traverse (t, mark_tree_hashtable_entry, 0);
+}
+
 static void
 print_type_hash_statistics ()
 {
@@ -3287,6 +3341,28 @@ type_list_equal (l1, l2)
   return t1 == t2;
 }
 
+/* Returns the number of arguments to the FUNCTION_TYPE or METHOD_TYPE
+   given by TYPE.  If the argument list accepts variable arguments,
+   then this function counts only the ordinary arguments.  */
+
+int
+type_num_arguments (type)
+     tree type;
+{
+  int i = 0;
+  tree t;
+
+  for (t = TYPE_ARG_TYPES (type); t; t = TREE_CHAIN (t))
+    /* If the function does not take a variable number of arguments,
+       the last element in the list will have type `void'.  */
+    if (VOID_TYPE_P (TREE_VALUE (t)))
+      break;
+    else
+      ++i;
+
+  return i;
+}
+
 /* Nonzero if integer constants T1 and T2
    represent the same constant value.  */
 
@@ -3503,10 +3579,10 @@ simple_cst_equal (t1, t2)
         as being equivalent to anything.  */
       if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
           && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
-          && DECL_RTL (TREE_OPERAND (t1, 0)) == 0)
+          && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
          || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
              && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
-             && DECL_RTL (TREE_OPERAND (t2, 0)) == 0))
+             && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
        cmp = 1;
       else
        cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
@@ -4397,15 +4473,7 @@ dump_tree_statistics ()
 \f
 #define FILE_FUNCTION_PREFIX_LEN 9
 
-#ifndef NO_DOLLAR_IN_LABEL
-#define FILE_FUNCTION_FORMAT "_GLOBAL_$%s$%s"
-#else /* NO_DOLLAR_IN_LABEL */
-#ifndef NO_DOT_IN_LABEL
-#define FILE_FUNCTION_FORMAT "_GLOBAL_.%s.%s"
-#else /* NO_DOT_IN_LABEL */
 #define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"
-#endif /* NO_DOT_IN_LABEL */
-#endif /* NO_DOLLAR_IN_LABEL */
 
 /* Appends 6 random characters to TEMPLATE to (hopefully) avoid name
    clashes in cases where we can't reliably choose a unique name.
@@ -4554,26 +4622,27 @@ get_set_constructor_bits (init, buffer, bit_size)
   int i;
   tree vals;
   HOST_WIDE_INT domain_min
-    = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (init))));
+    = tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (init))), 0);
   tree non_const_bits = NULL_TREE;
+
   for (i = 0; i < bit_size; i++)
     buffer[i] = 0;
 
   for (vals = TREE_OPERAND (init, 1);
        vals != NULL_TREE; vals = TREE_CHAIN (vals))
     {
-      if (TREE_CODE (TREE_VALUE (vals)) != INTEGER_CST
+      if (!host_integerp (TREE_VALUE (vals), 0)
          || (TREE_PURPOSE (vals) != NULL_TREE
-             && TREE_CODE (TREE_PURPOSE (vals)) != INTEGER_CST))
+             && !host_integerp (TREE_PURPOSE (vals), 0)))
        non_const_bits
          = tree_cons (TREE_PURPOSE (vals), TREE_VALUE (vals), non_const_bits);
       else if (TREE_PURPOSE (vals) != NULL_TREE)
        {
          /* Set a range of bits to ones.  */
          HOST_WIDE_INT lo_index
-           = TREE_INT_CST_LOW (TREE_PURPOSE (vals)) - domain_min;
+           = tree_low_cst (TREE_PURPOSE (vals), 0) - domain_min;
          HOST_WIDE_INT hi_index
-           = TREE_INT_CST_LOW (TREE_VALUE (vals)) - domain_min;
+           = tree_low_cst (TREE_VALUE (vals), 0) - domain_min;
 
          if (lo_index < 0 || lo_index >= bit_size
              || hi_index < 0 || hi_index >= bit_size)
@@ -4585,7 +4654,7 @@ get_set_constructor_bits (init, buffer, bit_size)
        {
          /* Set a single bit to one.  */
          HOST_WIDE_INT index
-           = TREE_INT_CST_LOW (TREE_VALUE (vals)) - domain_min;
+           = tree_low_cst (TREE_VALUE (vals), 0) - domain_min;
          if (index < 0 || index >= bit_size)
            {
              error ("invalid initializer for bit string");
@@ -4647,9 +4716,9 @@ tree_check_failed (node, code, file, line, function)
      int line;
      const char *function;
 {
-  error ("Tree check: expected %s, have %s",
-        tree_code_name[code], tree_code_name[TREE_CODE (node)]);
-  fancy_abort (file, line, function);
+  internal_error ("Tree check: expected %s, have %s in %s, at %s:%d",
+                 tree_code_name[code], tree_code_name[TREE_CODE (node)],
+                 function, trim_filename (file), line);
 }
 
 /* Similar to above, except that we check for a class of tree
@@ -4663,10 +4732,10 @@ tree_class_check_failed (node, cl, file, line, function)
      int line;
      const char *function;
 {
-  error ("Tree check: expected class '%c', have '%c' (%s)",
-        cl, TREE_CODE_CLASS (TREE_CODE (node)),
-        tree_code_name[TREE_CODE (node)]);
-  fancy_abort (file, line, function);
+  internal_error
+    ("Tree check: expected class '%c', have '%c' (%s) in %s, at %s:%d",
+     cl, TREE_CODE_CLASS (TREE_CODE (node)),
+     tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
 }
 
 #endif /* ENABLE_TREE_CHECKING */
@@ -4735,17 +4804,13 @@ build_common_tree_nodes (signed_char)
   intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
   intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
   intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode));
-#if HOST_BITS_PER_WIDE_INT >= 64
   intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode));
-#endif
 
   unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode));
   unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode));
   unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
   unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
-#if HOST_BITS_PER_WIDE_INT >= 64
   unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
-#endif
 }
 
 /* Call this function after calling build_common_tree_nodes and set_sizetype.
@@ -4758,6 +4823,7 @@ build_common_tree_nodes_2 (short_double)
   /* Define these next since types below may used them.  */
   integer_zero_node = build_int_2 (0, 0);
   integer_one_node = build_int_2 (1, 0);
+  integer_minus_one_node = build_int_2 (-1, -1);
 
   size_zero_node = size_int (0);
   size_one_node = size_int (1);
@@ -4812,11 +4878,20 @@ build_common_tree_nodes_2 (short_double)
   TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
   layout_type (complex_long_double_type_node);
 
-#ifdef BUILD_VA_LIST_TYPE
-  BUILD_VA_LIST_TYPE (va_list_type_node);
-#else
-  va_list_type_node = build_type_copy (ptr_type_node);
-#endif
+  {
+    tree t;
+    BUILD_VA_LIST_TYPE (t);
+
+    /* Many back-ends define record types without seting TYPE_NAME.
+       If we copied the record type here, we'd keep the original
+       record type without a name.  This breaks name mangling.  So,
+       don't copy record types and let c_common_nodes_and_builtins()
+       declare the type to be __builtin_va_list.  */
+    if (TREE_CODE (t) != RECORD_TYPE)
+      t = build_type_copy (t);
+
+    va_list_type_node = t;
+  }
 
   V4SF_type_node = make_node (VECTOR_TYPE);
   TREE_TYPE (V4SF_type_node) = float_type_node;