OSDN Git Service

Update email address for self.
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 69615e1..1353f32 100644 (file)
@@ -37,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "system.h"
 #include "flags.h"
 #include "tree.h"
+#include "real.h"
 #include "tm_p.h"
 #include "function.h"
 #include "obstack.h"
@@ -47,8 +48,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "langhooks.h"
 
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
 /* obstack.[ch] explicitly declined to prototype this.  */
 extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj));
 
@@ -56,6 +55,7 @@ extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj));
 
 struct obstack permanent_obstack;
 
+#ifdef GATHER_STATISTICS
 /* Statistics-gathering stuff.  */
 typedef enum
 {
@@ -95,6 +95,7 @@ static const char * const tree_node_kind_names[] = {
   "lang_decl kinds",
   "lang_type kinds"
 };
+#endif /* GATHER_STATISTICS */
 
 /* Unique id for next decl created.  */
 static int next_decl_uid;
@@ -104,7 +105,7 @@ static int next_type_uid = 1;
 /* Since we cannot rehash a type after it is in the table, we have to
    keep the hash code.  */
 
-struct type_hash
+struct type_hash GTY(())
 {
   unsigned long hash;
   tree type;
@@ -120,18 +121,17 @@ struct type_hash
    same table, they are completely independent, and the hash code is
    computed differently for each of these.  */
 
-htab_t type_hash_table;
+static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash)))
+     htab_t type_hash_table;
 
 static void set_type_quals PARAMS ((tree, int));
 static void append_random_chars PARAMS ((char *));
-static int type_hash_eq PARAMS ((const void*, const void*));
-static unsigned int type_hash_hash PARAMS ((const void*));
+static int type_hash_eq PARAMS ((const void *, const void *));
+static unsigned int type_hash_hash PARAMS ((const void *));
 static void print_type_hash_statistics PARAMS((void));
 static void finish_vector_type PARAMS((tree));
 static tree make_vector PARAMS ((enum machine_mode, tree, int));
 static int type_hash_marked_p PARAMS ((const void *));
-static void type_hash_mark PARAMS ((const void *));
-static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
@@ -146,10 +146,6 @@ init_obstacks ()
   /* Initialize the hash table of types.  */
   type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
                                 type_hash_eq, 0);
-  ggc_add_deletable_htab (type_hash_table, type_hash_marked_p,
-                         type_hash_mark);
-  ggc_add_tree_root (global_trees, TI_MAX);
-  ggc_add_tree_root (integer_types, itk_none);
 }
 
 \f
@@ -233,12 +229,12 @@ tree_size (node)
 
     case 'x':  /* something random, like an identifier.  */
       {
-         size_t length;
-         length = (sizeof (struct tree_common)
-                   + TREE_CODE_LENGTH (code) * sizeof (char *));
-         if (code == TREE_VEC)
-           length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *);
-         return length;
+       size_t length;
+       length = (sizeof (struct tree_common)
+                 + TREE_CODE_LENGTH (code) * sizeof (char *));
+       if (code == TREE_VEC)
+         length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *);
+       return length;
       }
 
     default:
@@ -263,12 +259,12 @@ make_node (code)
   tree_node_kind kind;
 #endif
   struct tree_common ttmp;
-  
+
   /* We can't allocate a TREE_VEC without knowing how many elements
      it will have.  */
   if (code == TREE_VEC)
     abort ();
-  
+
   TREE_SET_CODE ((tree)&ttmp, code);
   length = tree_size ((tree)&ttmp);
 
@@ -494,7 +490,7 @@ build_vector (type, vals)
       over1 |= TREE_OVERFLOW (value);
       over2 |= TREE_CONSTANT_OVERFLOW (value);
     }
-  
+
   TREE_OVERFLOW (v) = over1;
   TREE_CONSTANT_OVERFLOW (v) = over2;
 
@@ -509,6 +505,7 @@ build_real (type, d)
      REAL_VALUE_TYPE d;
 {
   tree v;
+  REAL_VALUE_TYPE *dp;
   int overflow = 0;
 
   /* Check for valid float value for this type on this target machine;
@@ -518,8 +515,11 @@ build_real (type, d)
 #endif
 
   v = make_node (REAL_CST);
+  dp = ggc_alloc (sizeof (REAL_VALUE_TYPE));
+  memcpy (dp, &d, sizeof (REAL_VALUE_TYPE));
+
   TREE_TYPE (v) = type;
-  TREE_REAL_CST (v) = d;
+  TREE_REAL_CST_PTR (v) = dp;
   TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow;
   return v;
 }
@@ -556,20 +556,11 @@ build_real_from_int_cst (type, i)
 {
   tree v;
   int overflow = TREE_OVERFLOW (i);
-  REAL_VALUE_TYPE d;
-
-  v = make_node (REAL_CST);
-  TREE_TYPE (v) = type;
 
-  d = real_value_from_int_cst (type, i);
+  v = build_real (type, real_value_from_int_cst (type, i));
 
-  /* Check for valid float value for this type on this target machine.  */
-#ifdef CHECK_FLOAT_VALUE
-  CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow);
-#endif
-
-  TREE_REAL_CST (v) = d;
-  TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow;
+  TREE_OVERFLOW (v) |= overflow;
+  TREE_CONSTANT_OVERFLOW (v) |= overflow;
   return v;
 }
 
@@ -618,11 +609,11 @@ make_tree_vec (len)
      int len;
 {
   tree t;
-  int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec);
+  int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
 
 #ifdef GATHER_STATISTICS
-  tree_node_counts[(int)vec_kind]++;
-  tree_node_sizes[(int)vec_kind] += length;
+  tree_node_counts[(int) vec_kind]++;
+  tree_node_sizes[(int) vec_kind] += length;
 #endif
 
   t = ggc_alloc_tree (length);
@@ -896,6 +887,22 @@ real_twop (expr)
              && real_zerop (TREE_IMAGPART (expr))));
 }
 
+/* Return 1 if EXPR is the real constant minus one.  */
+
+int
+real_minus_onep (expr)
+     tree expr;
+{
+  STRIP_NOPS (expr);
+
+  return ((TREE_CODE (expr) == REAL_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
+          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconstm1))
+         || (TREE_CODE (expr) == COMPLEX_CST
+             && real_minus_onep (TREE_REALPART (expr))
+             && real_zerop (TREE_IMAGPART (expr))));
+}
+
 /* Nonzero if EXP is a constant or a cast of a constant.  */
 
 int
@@ -1063,8 +1070,8 @@ chainon (op1, op2)
       TREE_CHAIN (t1) = op2;
 #ifdef ENABLE_TREE_CHECKING
       for (t2 = op2; t2; t2 = TREE_CHAIN (t2))
-        if (t2 == t1)
-          abort ();  /* Circularity created.  */
+       if (t2 == t1)
+         abort ();  /* Circularity created.  */
 #endif
       return op1;
     }
@@ -1349,12 +1356,13 @@ staticp (arg)
     case FUNCTION_DECL:
       /* Nested functions aren't static, since taking their address
         involves a trampoline.  */
-      return (decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
-       && ! DECL_NON_ADDR_CONST_P (arg);
+      return ((decl_function_context (arg) == 0 || DECL_NO_STATIC_CHAIN (arg))
+             && ! DECL_NON_ADDR_CONST_P (arg));
 
     case VAR_DECL:
-      return (TREE_STATIC (arg) || DECL_EXTERNAL (arg))
-       && ! DECL_NON_ADDR_CONST_P (arg);
+      return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
+             && ! DECL_THREAD_LOCAL (arg)
+             && ! DECL_NON_ADDR_CONST_P (arg));
 
     case CONSTRUCTOR:
       return TREE_STATIC (arg);
@@ -1514,6 +1522,44 @@ first_rtl_op (code)
     }
 }
 
+/* Return which tree structure is used by T.  */
+
+enum tree_node_structure_enum
+tree_node_structure (t)
+     tree t;
+{
+  enum tree_code code = TREE_CODE (t);
+  
+  switch (TREE_CODE_CLASS (code))
+    {
+    case 'd':  return TS_DECL;
+    case 't':  return TS_TYPE;
+    case 'b':  return TS_BLOCK;
+    case 'r': case '<': case '1': case '2': case 'e': case 's': 
+      return TS_EXP;
+    default:  /* 'c' and 'x' */
+      break;
+    }
+  switch (code)
+    {
+      /* 'c' cases.  */
+    case INTEGER_CST:          return TS_INT_CST;
+    case REAL_CST:             return TS_REAL_CST;
+    case COMPLEX_CST:          return TS_COMPLEX;
+    case VECTOR_CST:           return TS_VECTOR;
+    case STRING_CST:           return TS_STRING;
+      /* 'x' cases.  */
+    case ERROR_MARK:           return TS_COMMON;
+    case IDENTIFIER_NODE:      return TS_IDENTIFIER;
+    case TREE_LIST:            return TS_LIST;
+    case TREE_VEC:             return TS_VEC;
+    case PLACEHOLDER_EXPR:     return TS_COMMON;
+
+    default:
+      abort ();
+    }
+}
+
 /* Perform any modifications to EXPR required when it is unsaved.  Does
    not recurse into EXPR's subtrees.  */
 
@@ -2313,7 +2359,7 @@ build1 (code, type, node)
 #endif
 
 #ifdef ENABLE_CHECKING
-  if (TREE_CODE_CLASS (code) == '2' 
+  if (TREE_CODE_CLASS (code) == '2'
       || TREE_CODE_CLASS (code) == '<'
       || TREE_CODE_LENGTH (code) != 1)
     abort ();
@@ -2498,7 +2544,7 @@ tree
 build_type_attribute_variant (ttype, attribute)
      tree ttype, attribute;
 {
-  if ( ! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
+  if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
     {
       unsigned int hashcode;
       tree ntype;
@@ -2570,12 +2616,6 @@ default_insert_attributes (decl, attr_ptr)
 {
 }
 
-/* Default value of targetm.attribute_table that is empty.  */
-const struct attribute_spec default_target_attribute_table[] =
-{
-  { NULL, 0, 0, false, false, false, NULL }
-};
-
 /* Default value of targetm.function_attribute_inlinable_p that always
    returns false.  */
 bool
@@ -3037,41 +3077,6 @@ type_hash_marked_p (p)
   return ggc_marked_p (type) || TYPE_SYMTAB_POINTER (type);
 }
 
-/* Mark the entry in the type hash table the type it points to is marked.
-   Also mark the type in case we are considering this entry "marked" by
-   virtue of TYPE_SYMTAB_POINTER being set.  */
-
-static void
-type_hash_mark (p)
-     const void *p;
-{
-  ggc_mark (p);
-  ggc_mark_tree (((struct type_hash *) p)->type);
-}
-
-/* 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 ()
 {
@@ -3105,8 +3110,8 @@ int
 attribute_list_equal (l1, l2)
      tree l1, l2;
 {
-   return attribute_list_contained (l1, l2)
-         && attribute_list_contained (l2, l1);
+  return attribute_list_contained (l1, l2)
+        && attribute_list_contained (l2, l1);
 }
 
 /* Given two lists of attributes, return true if list L2 is
@@ -3236,7 +3241,20 @@ tree_int_cst_lt (t1, t2)
   if (t1 == t2)
     return 0;
 
-  if (! TREE_UNSIGNED (TREE_TYPE (t1)))
+  if (TREE_UNSIGNED (TREE_TYPE (t1)) != TREE_UNSIGNED (TREE_TYPE (t2)))
+    {
+      int t1_sgn = tree_int_cst_sgn (t1);
+      int t2_sgn = tree_int_cst_sgn (t2);
+
+      if (t1_sgn < t2_sgn)
+       return 1;
+      else if (t1_sgn > t2_sgn)
+       return 0;
+      /* Otherwise, both are non-negative, so we compare them as
+        unsigned just in case one of them would overflow a signed
+        type.  */
+    }
+  else if (! TREE_UNSIGNED (TREE_TYPE (t1)))
     return INT_CST_LT (t1, t2);
 
   return INT_CST_LT_UNSIGNED (t1, t2);
@@ -3253,7 +3271,7 @@ tree_int_cst_compare (t1, t2)
     return -1;
   else if (tree_int_cst_lt (t2, t1))
     return 1;
-  else 
+  else
     return 0;
 }
 
@@ -3781,6 +3799,32 @@ build_function_type (value_type, arg_types)
   return t;
 }
 
+/* Build a function type.  The RETURN_TYPE is the type retured by the
+   function.  If additional arguments are provided, they are
+   additional argument types.  The list of argument types must always
+   be terminated by NULL_TREE.  */
+
+tree
+build_function_type_list VPARAMS ((tree return_type, ...))
+{
+  tree t, args, last;
+
+  VA_OPEN (p, return_type);
+  VA_FIXEDARG (p, tree, return_type);
+
+  t = va_arg (p, tree);
+  for (args = NULL_TREE; t != NULL_TREE; t = va_arg (p, tree))
+    args = tree_cons (NULL_TREE, t, args);
+
+  last = args;
+  args = nreverse (args);
+  TREE_CHAIN (last) = void_list_node;
+  args = build_function_type (return_type, args);
+
+  VA_CLOSE (p);
+  return args;
+}
+
 /* Construct, lay out and return the type of methods belonging to class
    BASETYPE and whose arguments and values are described by TYPE.
    If that type exists already, reuse it.
@@ -4204,6 +4248,9 @@ decl_type_context (decl)
 
   while (context)
     {
+      if (TREE_CODE (context) == NAMESPACE_DECL)
+       return NULL_TREE;
+
       if (TREE_CODE (context) == RECORD_TYPE
          || TREE_CODE (context) == UNION_TYPE
          || TREE_CODE (context) == QUAL_UNION_TYPE)
@@ -4400,7 +4447,7 @@ clean_symbol_name (p)
           ))
       *p = '_';
 }
-  
+
 /* Generate a name for a function unique to this translation unit.
    TYPE is some string to identify the purpose of this function to the
    linker or collect2.  */
@@ -4757,6 +4804,8 @@ build_common_tree_nodes_2 (short_double)
     = make_vector (V4SImode, unsigned_intSI_type_node, 1);
   unsigned_V2SI_type_node
     = make_vector (V2SImode, unsigned_intSI_type_node, 1);
+  unsigned_V2DI_type_node
+    = make_vector (V2DImode, unsigned_intDI_type_node, 1);
   unsigned_V4HI_type_node
     = make_vector (V4HImode, unsigned_intHI_type_node, 1);
   unsigned_V8QI_type_node
@@ -4770,10 +4819,12 @@ build_common_tree_nodes_2 (short_double)
   V4SF_type_node = make_vector (V4SFmode, float_type_node, 0);
   V4SI_type_node = make_vector (V4SImode, intSI_type_node, 0);
   V2SI_type_node = make_vector (V2SImode, intSI_type_node, 0);
+  V2DI_type_node = make_vector (V2DImode, intDI_type_node, 0);
   V4HI_type_node = make_vector (V4HImode, intHI_type_node, 0);
   V8QI_type_node = make_vector (V8QImode, intQI_type_node, 0);
   V8HI_type_node = make_vector (V8HImode, intHI_type_node, 0);
   V2SF_type_node = make_vector (V2SFmode, float_type_node, 0);
+  V2DF_type_node = make_vector (V2DFmode, double_type_node, 0);
   V16QI_type_node = make_vector (V16QImode, intQI_type_node, 0);
 }
 
@@ -4821,20 +4872,22 @@ initializer_zerop (init)
     case CONSTRUCTOR:
       {
        if (AGGREGATE_TYPE_P (TREE_TYPE (init)))
-       {
-         tree aggr_init = TREE_OPERAND (init, 1);
-         
-         while (aggr_init)
-           {
-             if (! initializer_zerop (TREE_VALUE (aggr_init)))
-               return false;
-             aggr_init = TREE_CHAIN (aggr_init);
-           }
-         return true;
-       }
+         {
+           tree aggr_init = TREE_OPERAND (init, 1);
+
+           while (aggr_init)
+             {
+               if (! initializer_zerop (TREE_VALUE (aggr_init)))
+                 return false;
+               aggr_init = TREE_CHAIN (aggr_init);
+             }
+           return true;
+         }
        return false;
       }
     default:
       return false;
     }
 }
+
+#include "gt-tree.h"