OSDN Git Service

2007-07-06 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index e3eb4be..06472ea 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, 2001, 2002, 2003, 2004, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -66,7 +66,9 @@ const char *const tree_code_class_strings[] =
   "unary",
   "binary",
   "statement",
+  "vl_exp",
   "expression",
+  "gimple_stmt"
 };
 
 /* obstack.[ch] explicitly declined to prototype this.  */
@@ -144,20 +146,13 @@ static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
 static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) 
      htab_t value_expr_for_decl;
 
-static GTY ((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
+static GTY ((if_marked ("tree_priority_map_marked_p"), 
+            param_is (struct tree_priority_map)))
   htab_t init_priority_for_decl;
 
 static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
   htab_t restrict_base_for_decl;
 
-struct tree_int_map GTY(())
-{
-  tree from;
-  unsigned short to;
-};
-static unsigned int tree_int_map_hash (const void *);
-static int tree_int_map_eq (const void *, const void *);
-static int tree_int_map_marked_p (const void *);
 static void set_type_quals (tree, int);
 static int type_hash_eq (const void *, const void *);
 static hashval_t type_hash_hash (const void *);
@@ -173,7 +168,7 @@ static unsigned int attribute_hash_list (tree, hashval_t);
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
 
-unsigned char tree_contains_struct[256][64];
+unsigned char tree_contains_struct[MAX_TREE_CODES][64];
 
 /* Number of operands for each OpenMP clause.  */
 unsigned const char omp_clause_num_ops[] =
@@ -226,8 +221,8 @@ init_ttree (void)
 
   value_expr_for_decl = htab_create_ggc (512, tree_map_hash,
                                         tree_map_eq, 0);
-  init_priority_for_decl = htab_create_ggc (512, tree_int_map_hash,
-                                           tree_int_map_eq, 0);
+  init_priority_for_decl = htab_create_ggc (512, tree_priority_map_hash,
+                                           tree_priority_map_eq, 0);
   restrict_base_for_decl = htab_create_ggc (256, tree_map_hash,
                                            tree_map_eq, 0);
 
@@ -345,8 +340,8 @@ decl_assembler_name_equal (tree decl, tree asmname)
 }
 
 /* Compute the number of bytes occupied by a tree with code CODE.
-   This function cannot be used for TREE_VEC, PHI_NODE, or STRING_CST
-   codes, which are of variable length.  */
+   This function cannot be used for nodes that have variable sizes,
+   including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR.  */
 size_t
 tree_code_size (enum tree_code code)
 {
@@ -394,7 +389,7 @@ tree_code_size (enum tree_code code)
     case tcc_unary:       /* a unary arithmetic expression */
     case tcc_binary:      /* a binary arithmetic expression */
       return (sizeof (struct tree_exp)
-             + (TREE_CODE_LENGTH (code) - 1) * sizeof (char *));
+             + (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
 
     case tcc_gimple_stmt:
       return (sizeof (struct gimple_stmt)
@@ -442,7 +437,7 @@ tree_code_size (enum tree_code code)
 }
 
 /* Compute the number of bytes occupied by NODE.  This routine only
-   looks at TREE_CODE, except for PHI_NODE and TREE_VEC nodes.  */
+   looks at TREE_CODE, except for those nodes that have variable sizes.  */
 size_t
 tree_size (tree node)
 {
@@ -459,7 +454,7 @@ tree_size (tree node)
 
     case TREE_VEC:
       return (sizeof (struct tree_vec)
-             + (TREE_VEC_LENGTH (node) - 1) * sizeof(char *));
+             + (TREE_VEC_LENGTH (node) - 1) * sizeof (tree));
 
     case STRING_CST:
       return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
@@ -470,7 +465,11 @@ tree_size (tree node)
                * sizeof (tree));
 
     default:
-      return tree_code_size (code);
+      if (TREE_CODE_CLASS (code) == tcc_vl_exp)
+       return (sizeof (struct tree_exp)
+               + (VL_EXP_OPERAND_LENGTH (node) - 1) * sizeof (tree));
+      else
+       return tree_code_size (code);
     }
 }
 
@@ -779,53 +778,25 @@ build_int_cstu (tree type, unsigned HOST_WIDE_INT low)
 tree
 build_int_cst_type (tree type, HOST_WIDE_INT low)
 {
-  unsigned HOST_WIDE_INT val = (unsigned HOST_WIDE_INT) low;
-  unsigned HOST_WIDE_INT hi, mask;
-  unsigned bits;
-  bool signed_p;
-  bool negative;
-
-  if (!type)
-    type = integer_type_node;
-
-  bits = TYPE_PRECISION (type);
-  signed_p = !TYPE_UNSIGNED (type);
+  unsigned HOST_WIDE_INT low1;
+  HOST_WIDE_INT hi;
 
-  if (bits >= HOST_BITS_PER_WIDE_INT)
-    negative = (low < 0);
-  else
-    {
-      /* If the sign bit is inside precision of LOW, use it to determine
-        the sign of the constant.  */
-      negative = ((val >> (bits - 1)) & 1) != 0;
+  gcc_assert (type);
 
-      /* Mask out the bits outside of the precision of the constant.  */
-      mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
+  fit_double_type (low, low < 0 ? -1 : 0, &low1, &hi, type);
 
-      if (signed_p && negative)
-       val |= ~mask;
-      else
-       val &= mask;
-    }
-
-  /* Determine the high bits.  */
-  hi = (negative ? ~(unsigned HOST_WIDE_INT) 0 : 0);
+  return build_int_cst_wide (type, low1, hi);
+}
 
-  /* For unsigned type we need to mask out the bits outside of the type
-     precision.  */
-  if (!signed_p)
-    {
-      if (bits <= HOST_BITS_PER_WIDE_INT)
-       hi = 0;
-      else
-       {
-         bits -= HOST_BITS_PER_WIDE_INT;
-         mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
-         hi &= mask;
-       }
-    }
+/* Create an INT_CST node of TYPE and value HI:LOW.  The value is truncated
+   and sign extended according to the value range of TYPE.  */
 
-  return build_int_cst_wide (type, val, hi);
+tree
+build_int_cst_wide_type (tree type,
+                        unsigned HOST_WIDE_INT low, HOST_WIDE_INT high)
+{
+  fit_double_type (low, high, &low, &high, type);
+  return build_int_cst_wide (type, low, high);
 }
 
 /* These are the hash table functions for the hash table of INTEGER_CST
@@ -856,10 +827,9 @@ int_cst_hash_eq (const void *x, const void *y)
          && TREE_INT_CST_LOW (xt) == TREE_INT_CST_LOW (yt));
 }
 
-/* Create an INT_CST node of TYPE and value HI:LOW.  If TYPE is NULL,
-   integer_type_node is used.  The returned node is always shared.
-   For small integers we use a per-type vector cache, for larger ones
-   we use a single hash table.  */
+/* Create an INT_CST node of TYPE and value HI:LOW.
+   The returned node is always shared.  For small integers we use a
+   per-type vector cache, for larger ones we use a single hash table.  */
 
 tree
 build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
@@ -1026,7 +996,7 @@ tree
 build_vector (tree type, tree vals)
 {
   tree v = make_node (VECTOR_CST);
-  int over1 = 0, over2 = 0;
+  int over = 0;
   tree link;
 
   TREE_VECTOR_CST_ELTS (v) = vals;
@@ -1041,13 +1011,10 @@ build_vector (tree type, tree vals)
       if (!CONSTANT_CLASS_P (value))
        continue;
 
-      over1 |= TREE_OVERFLOW (value);
-      over2 |= TREE_CONSTANT_OVERFLOW (value);
+      over |= TREE_OVERFLOW (value);
     }
 
-  TREE_OVERFLOW (v) = over1;
-  TREE_CONSTANT_OVERFLOW (v) = over2;
-
+  TREE_OVERFLOW (v) = over;
   return v;
 }
 
@@ -1144,7 +1111,7 @@ build_real (tree type, REAL_VALUE_TYPE d)
 
   TREE_TYPE (v) = type;
   TREE_REAL_CST_PTR (v) = dp;
-  TREE_OVERFLOW (v) = TREE_CONSTANT_OVERFLOW (v) = overflow;
+  TREE_OVERFLOW (v) = overflow;
   return v;
 }
 
@@ -1178,7 +1145,6 @@ build_real_from_int_cst (tree type, tree i)
   v = build_real (type, real_value_from_int_cst (type, i));
 
   TREE_OVERFLOW (v) |= overflow;
-  TREE_CONSTANT_OVERFLOW (v) |= overflow;
   return v;
 }
 
@@ -1227,8 +1193,6 @@ build_complex (tree type, tree real, tree imag)
   TREE_IMAGPART (t) = imag;
   TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real));
   TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag);
-  TREE_CONSTANT_OVERFLOW (t)
-    = TREE_CONSTANT_OVERFLOW (real) | TREE_CONSTANT_OVERFLOW (imag);
   return t;
 }
 
@@ -1818,9 +1782,6 @@ size_in_bytes (tree type)
       return size_zero_node;
     }
 
-  if (TREE_CODE (t) == INTEGER_CST)
-    t = force_fit_type (t, 0, false, false);
-
   return t;
 }
 
@@ -1936,14 +1897,11 @@ expr_align (tree t)
       align1 = TYPE_ALIGN (TREE_TYPE (t));
       return MAX (align0, align1);
 
-    case MODIFY_EXPR:
-      /* FIXME tuples: It is unclear to me if this function, which
-         is only called from ADA, is called on gimple or non gimple
-         trees.  Let's assume it's from gimple trees unless we hit
-         this abort.  */
+    case GIMPLE_MODIFY_STMT:
+      /* We should never ask for the alignment of a gimple statement.  */
       gcc_unreachable ();
 
-    case SAVE_EXPR:         case COMPOUND_EXPR:       case GIMPLE_MODIFY_STMT:
+    case SAVE_EXPR:         case COMPOUND_EXPR:       case MODIFY_EXPR:
     case INIT_EXPR:         case TARGET_EXPR:         case WITH_CLEANUP_EXPR:
     case CLEANUP_POINT_EXPR:
       /* These don't change the alignment of an object.  */
@@ -2212,6 +2170,7 @@ tree_node_structure (tree t)
     case tcc_binary:
     case tcc_expression:
     case tcc_statement:
+    case tcc_vl_exp:
       return TS_EXP;
     case tcc_gimple_stmt:
       return TS_GIMPLE_STATEMENT;
@@ -2293,9 +2252,6 @@ contains_placeholder_p (tree exp)
                  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
                  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
 
-       case CALL_EXPR:
-         return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
-
        default:
          break;
        }
@@ -2311,6 +2267,22 @@ contains_placeholder_p (tree exp)
          return 0;
        }
 
+    case tcc_vl_exp:
+      switch (code)
+       {
+       case CALL_EXPR:
+         {
+           tree arg;
+           call_expr_arg_iterator iter;
+           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+             if (CONTAINS_PLACEHOLDER_P (arg))
+               return 1;
+           return 0;
+         }
+       default:
+         return 0;
+       }
+
     default:
       return 0;
     }
@@ -2518,6 +2490,27 @@ substitute_in_expr (tree exp, tree f, tree r)
          }
        break;
 
+      case tcc_vl_exp:
+       {
+         tree copy = NULL_TREE;
+         int i;
+         int n = TREE_OPERAND_LENGTH (exp);
+         for (i = 1; i < n; i++)
+           {
+             tree op = TREE_OPERAND (exp, i);
+             tree newop = SUBSTITUTE_IN_EXPR (op, f, r);
+             if (newop != op)
+               {
+                 copy = copy_node (exp);
+                 TREE_OPERAND (copy, i) = newop;
+               }
+           }
+         if (copy)
+           new = fold (copy);
+         else
+           return exp;
+       }
+
       default:
        gcc_unreachable ();
       }
@@ -2549,6 +2542,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
                  : (REFERENCE_CLASS_P (elt)
                     || UNARY_CLASS_P (elt)
                     || BINARY_CLASS_P (elt)
+                    || VL_EXP_CLASS_P (elt)
                     || EXPRESSION_CLASS_P (elt))
                  ? TREE_OPERAND (elt, 0) : 0))
        if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
@@ -2561,6 +2555,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
                  : (REFERENCE_CLASS_P (elt)
                     || UNARY_CLASS_P (elt)
                     || BINARY_CLASS_P (elt)
+                    || VL_EXP_CLASS_P (elt)
                     || EXPRESSION_CLASS_P (elt))
                  ? TREE_OPERAND (elt, 0) : 0))
        if (POINTER_TYPE_P (TREE_TYPE (elt))
@@ -2648,6 +2643,28 @@ substitute_placeholder_in_expr (tree exp, tree obj)
          }
        break;
 
+      case tcc_vl_exp:
+       {
+         tree copy = NULL_TREE;
+         int i;
+         int n = TREE_OPERAND_LENGTH (exp);
+         for (i = 1; i < n; i++)
+           {
+             tree op = TREE_OPERAND (exp, i);
+             tree newop = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
+             if (newop != op)
+               {
+                 if (!copy)
+                   copy = copy_node (exp);
+                 TREE_OPERAND (copy, i) = newop;
+               }
+           }
+         if (copy)
+           return fold (copy);
+         else
+           return exp;
+       }
+
       default:
        gcc_unreachable ();
       }
@@ -2773,6 +2790,7 @@ stabilize_reference_1 (tree e)
     case tcc_statement:
     case tcc_expression:
     case tcc_reference:
+    case tcc_vl_exp:
       /* If the expression has side-effects, then encase it in a SAVE_EXPR
         so that it will only be evaluated once.  */
       /* The reference (r) and comparison (<) classes could be handled as
@@ -2969,7 +2987,6 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
 #else
   SET_EXPR_LOCUS (t, NULL);
 #endif
-  TREE_COMPLEXITY (t) = 0;
   TREE_OPERAND (t, 0) = node;
   TREE_BLOCK (t) = NULL_TREE;
   if (node && !TYPE_P (node))
@@ -3043,16 +3060,23 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 
   gcc_assert (TREE_CODE_LENGTH (code) == 2);
 
-  if (code == MODIFY_EXPR && cfun && cfun->gimplified)
-    {
-      /* We should be talking GIMPLE_MODIFY_STMT by now.  */
-      gcc_unreachable ();
-    }
+#if 1
+  /* FIXME tuples: Statement's aren't expressions!  */
+  if (code == GIMPLE_MODIFY_STMT)
+    return build_gimple_modify_stmt_stat (arg0, arg1 PASS_MEM_STAT);
+#else
+  /* Must use build_gimple_modify_stmt to construct GIMPLE_MODIFY_STMTs.  */
+  gcc_assert (code != GIMPLE_MODIFY_STMT);
+#endif
 
-  /* FIXME tuples: For now let's be lazy; later we must rewrite all
-     build2 calls to build2_gimple calls.  */
-  if (TREE_CODE_CLASS (code) == tcc_gimple_stmt)
-    return build2_gimple (code, arg0, arg1);
+  if ((code == MINUS_EXPR || code == PLUS_EXPR || code == MULT_EXPR)
+      && arg0 && arg1 && tt && POINTER_TYPE_P (tt))
+    gcc_assert (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST);
+
+  if (code == POINTER_PLUS_EXPR && arg0 && arg1 && tt)
+    gcc_assert (POINTER_TYPE_P (tt) && POINTER_TYPE_P (TREE_TYPE (arg0))
+               && TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
+               && useless_type_conversion_p (sizetype, TREE_TYPE (arg1)));
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
@@ -3085,31 +3109,18 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 }
 
 
-/* Similar as build2_stat, but for GIMPLE tuples.  For convenience's sake,
-   arguments and return type are trees.  */
+/* Build a GIMPLE_MODIFY_STMT node.  This tree code doesn't have a
+   type, so we can't use build2 (a.k.a. build2_stat).  */
 
 tree
-build2_gimple_stat (enum tree_code code, tree arg0, tree arg1 MEM_STAT_DECL)
+build_gimple_modify_stmt_stat (tree arg0, tree arg1 MEM_STAT_DECL)
 {
-  bool side_effects;
   tree t;
 
-  gcc_assert (TREE_CODE_LENGTH (code) == 2);
-
-  t = make_node_stat (code PASS_MEM_STAT);
-
-  side_effects = TREE_SIDE_EFFECTS (t);
-
+  t = make_node_stat (GIMPLE_MODIFY_STMT PASS_MEM_STAT);
   /* ?? We don't care about setting flags for tuples...  */
   GIMPLE_STMT_OPERAND (t, 0) = arg0;
   GIMPLE_STMT_OPERAND (t, 1) = arg1;
-
-  /* ...except perhaps side_effects and volatility.  ?? */
-  TREE_SIDE_EFFECTS (t) = side_effects;
-  TREE_THIS_VOLATILE (t) = (TREE_CODE_CLASS (code) == tcc_reference
-                           && arg0 && TREE_THIS_VOLATILE (arg0));
-
-
   return t;
 }
 
@@ -3121,36 +3132,26 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   tree t;
 
   gcc_assert (TREE_CODE_LENGTH (code) == 3);
+  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
 
-  side_effects = TREE_SIDE_EFFECTS (t);
+  /* As a special exception, if COND_EXPR has NULL branches, we
+     assume that it is a gimple statement and always consider
+     it to have side effects.  */
+  if (code == COND_EXPR
+      && tt == void_type_node
+      && arg1 == NULL_TREE
+      && arg2 == NULL_TREE)
+    side_effects = true;
+  else
+    side_effects = TREE_SIDE_EFFECTS (t);
 
   PROCESS_ARG(0);
   PROCESS_ARG(1);
   PROCESS_ARG(2);
 
-  if (code == CALL_EXPR && !side_effects)
-    {
-      tree node;
-      int i;
-
-      /* Calls have side-effects, except those to const or
-        pure functions.  */
-      i = call_expr_flags (t);
-      if (!(i & (ECF_CONST | ECF_PURE)))
-       side_effects = 1;
-
-      /* And even those have side-effects if their arguments do.  */
-      else for (node = arg1; node; node = TREE_CHAIN (node))
-       if (TREE_SIDE_EFFECTS (TREE_VALUE (node)))
-         {
-           side_effects = 1;
-           break;
-         }
-    }
-
   TREE_SIDE_EFFECTS (t) = side_effects;
   TREE_THIS_VOLATILE (t)
     = (TREE_CODE_CLASS (code) == tcc_reference
@@ -3256,6 +3257,8 @@ build_nt (enum tree_code code, ...)
   int i;
   va_list p;
 
+  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
   va_start (p, code);
 
   t = make_node (code);
@@ -3267,6 +3270,23 @@ build_nt (enum tree_code code, ...)
   va_end (p);
   return t;
 }
+
+/* Similar to build_nt, but for creating a CALL_EXPR object with
+   ARGLIST passed as a list.  */
+
+tree
+build_nt_call_list (tree fn, tree arglist)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, list_length (arglist) + 3);
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; arglist; arglist = TREE_CHAIN (arglist), i++)
+    CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
+  return t;
+}
 \f
 /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
    We do NOT enter this node in any sort of symbol table.
@@ -3980,18 +4000,25 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
          *no_add_attrs = true;
          return tree_cons (name, args, NULL_TREE);
        }
-      if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
+      if (TREE_CODE (node) == RECORD_TYPE
+         || TREE_CODE (node) == UNION_TYPE)
+       {
+         node = TYPE_NAME (node);
+         if (!node)
+           return NULL_TREE;
+       }
+      else
        {
          warning (OPT_Wattributes, "%qs attribute ignored",
                   IDENTIFIER_POINTER (name));
          *no_add_attrs = true;
+         return NULL_TREE;
        }
-
-      return NULL_TREE;
     }
 
   if (TREE_CODE (node) != FUNCTION_DECL
-      && TREE_CODE (node) != VAR_DECL)
+      && TREE_CODE (node) != VAR_DECL
+      && TREE_CODE (node) != TYPE_DECL)
     {
       *no_add_attrs = true;
       warning (OPT_Wattributes, "%qs attribute ignored",
@@ -4054,6 +4081,22 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
       *no_add_attrs = true;
     }
 
+  /* A dllexport'd entity must have default visibility so that other
+     program units (shared libraries or the main executable) can see
+     it.  A dllimport'd entity must have default visibility so that
+     the linker knows that undefined references within this program
+     unit can be resolved by the dynamic linker.  */
+  if (!*no_add_attrs)
+    {
+      if (DECL_VISIBILITY_SPECIFIED (node)
+         && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT)
+       error ("%qs implies default visibility, but %qD has already "
+              "been declared with a different visibility", 
+              IDENTIFIER_POINTER (name), node);
+      DECL_VISIBILITY (node) = VISIBILITY_DEFAULT;
+      DECL_VISIBILITY_SPECIFIED (node) = 1;
+    }
+
   return NULL_TREE;
 }
 
@@ -4162,7 +4205,11 @@ build_distinct_type_copy (tree type)
   /* Make it its own variant.  */
   TYPE_MAIN_VARIANT (t) = t;
   TYPE_NEXT_VARIANT (t) = 0;
-  
+
+  /* Note that it is now possible for TYPE_MIN_VALUE to be a value
+     whose TREE_TYPE is not t.  This can also happen in the Ada
+     frontend when using subtypes.  */
+
   return t;
 }
 
@@ -4194,18 +4241,18 @@ build_variant_type_copy (tree type)
 /* Return true if the from tree in both tree maps are equal.  */
 
 int
-tree_map_eq (const void *va, const void *vb)
+tree_map_base_eq (const void *va, const void *vb)
 {
-  const struct tree_map  *a = va, *b = vb;
+  const struct tree_map_base  *a = va, *b = vb;
   return (a->from == b->from);
 }
 
 /* Hash a from tree in a tree_map.  */
 
 unsigned int
-tree_map_hash (const void *item)
+tree_map_base_hash (const void *item)
 {
-  return (((const struct tree_map *) item)->hash);
+  return htab_hash_pointer (((const struct tree_map_base *)item)->from);
 }
 
 /* Return true if this tree map structure is marked for garbage collection
@@ -4213,70 +4260,97 @@ tree_map_hash (const void *item)
    structure goes away when the from tree goes away.  */
 
 int
-tree_map_marked_p (const void *p)
+tree_map_base_marked_p (const void *p)
 {
-  tree from = ((struct tree_map *) p)->from;
+  return ggc_marked_p (((struct tree_map_base *) p)->from);
+}
 
-  return ggc_marked_p (from);
+unsigned int
+tree_map_hash (const void *item)
+{
+  return (((const struct tree_map *) item)->hash);
 }
 
-/* Return true if the trees in the tree_int_map *'s VA and VB are equal.  */
+/* Return the initialization priority for DECL.  */
 
-static int
-tree_int_map_eq (const void *va, const void *vb)
+priority_type
+decl_init_priority_lookup (tree decl)
 {
-  const struct tree_int_map  *a = va, *b = vb;
-  return (a->from == b->from);
+  struct tree_priority_map *h;
+  struct tree_map_base in;
+
+  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+  gcc_assert (TREE_CODE (decl) == VAR_DECL
+             ? DECL_HAS_INIT_PRIORITY_P (decl)
+             : DECL_STATIC_CONSTRUCTOR (decl));
+  in.from = decl;
+  h = htab_find (init_priority_for_decl, &in);
+  return h ? h->init : DEFAULT_INIT_PRIORITY;
 }
 
-/* Hash a from tree in the tree_int_map * ITEM.  */
+/* Return the finalization priority for DECL.  */
 
-static unsigned int
-tree_int_map_hash (const void *item)
+priority_type
+decl_fini_priority_lookup (tree decl)
 {
-  return htab_hash_pointer (((const struct tree_int_map *)item)->from);
+  struct tree_priority_map *h;
+  struct tree_map_base in;
+
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+  gcc_assert (DECL_STATIC_DESTRUCTOR (decl));
+  in.from = decl;
+  h = htab_find (init_priority_for_decl, &in);
+  return h ? h->fini : DEFAULT_INIT_PRIORITY;
 }
 
-/* Return true if this tree int map structure is marked for garbage collection
-   purposes.  We simply return true if the from tree_int_map *P's from tree is marked, so that this
-   structure goes away when the from tree goes away.  */
+/* Return the initialization and finalization priority information for
+   DECL.  If there is no previous priority information, a freshly
+   allocated structure is returned.  */
 
-static int
-tree_int_map_marked_p (const void *p)
+static struct tree_priority_map *
+decl_priority_info (tree decl)
 {
-  tree from = ((struct tree_int_map *) p)->from;
+  struct tree_priority_map in;
+  struct tree_priority_map *h;
+  void **loc;
 
-  return ggc_marked_p (from);
+  in.base.from = decl;
+  loc = htab_find_slot (init_priority_for_decl, &in, INSERT);
+  h = *loc;
+  if (!h)
+    {
+      h = GGC_CNEW (struct tree_priority_map);
+      *loc = h;
+      h->base.from = decl;
+      h->init = DEFAULT_INIT_PRIORITY;
+      h->fini = DEFAULT_INIT_PRIORITY;
+    }
+
+  return h;
 }
-/* Lookup an init priority for FROM, and return it if we find one.  */
 
-unsigned short
-decl_init_priority_lookup (tree from)
+/* Set the initialization priority for DECL to PRIORITY.  */
+
+void
+decl_init_priority_insert (tree decl, priority_type priority)
 {
-  struct tree_int_map *h, in;
-  in.from = from;
+  struct tree_priority_map *h;
 
-  h = htab_find_with_hash (init_priority_for_decl, 
-                          &in, htab_hash_pointer (from));
-  if (h)
-    return h->to;
-  return 0;
-}
+  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+  h = decl_priority_info (decl);
+  h->init = priority;
+}  
 
-/* Insert a mapping FROM->TO in the init priority hashtable.  */
+/* Set the finalization priority for DECL to PRIORITY.  */
 
 void
-decl_init_priority_insert (tree from, unsigned short to)
+decl_fini_priority_insert (tree decl, priority_type priority)
 {
-  struct tree_int_map *h;
-  void **loc;
+  struct tree_priority_map *h;
 
-  h = ggc_alloc (sizeof (struct tree_int_map));
-  h->from = from;
-  h->to = to;
-  loc = htab_find_slot_with_hash (init_priority_for_decl, h, 
-                                 htab_hash_pointer (from), INSERT);
-  *(struct tree_int_map **) loc = h;
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+  h = decl_priority_info (decl);
+  h->fini = priority;
 }  
 
 /* Look up a restrict qualified base decl for FROM.  */
@@ -4287,7 +4361,7 @@ decl_restrict_base_lookup (tree from)
   struct tree_map *h;
   struct tree_map in;
 
-  in.from = from;
+  in.base.from = from;
   h = htab_find_with_hash (restrict_base_for_decl, &in,
                           htab_hash_pointer (from));
   return h ? h->to : NULL_TREE;
@@ -4303,7 +4377,7 @@ decl_restrict_base_insert (tree from, tree to)
 
   h = ggc_alloc (sizeof (struct tree_map));
   h->hash = htab_hash_pointer (from);
-  h->from = from;
+  h->base.from = from;
   h->to = to;
   loc = htab_find_slot_with_hash (restrict_base_for_decl, h, h->hash, INSERT);
   *(struct tree_map **) loc = h;
@@ -4351,7 +4425,7 @@ tree
 decl_debug_expr_lookup (tree from)
 {
   struct tree_map *h, in;
-  in.from = from;
+  in.base.from = from;
 
   h = htab_find_with_hash (debug_expr_for_decl, &in, htab_hash_pointer (from));
   if (h)
@@ -4369,7 +4443,7 @@ decl_debug_expr_insert (tree from, tree to)
 
   h = ggc_alloc (sizeof (struct tree_map));
   h->hash = htab_hash_pointer (from);
-  h->from = from;
+  h->base.from = from;
   h->to = to;
   loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT);
   *(struct tree_map **) loc = h;
@@ -4381,7 +4455,7 @@ tree
 decl_value_expr_lookup (tree from)
 {
   struct tree_map *h, in;
-  in.from = from;
+  in.base.from = from;
 
   h = htab_find_with_hash (value_expr_for_decl, &in, htab_hash_pointer (from));
   if (h)
@@ -4399,7 +4473,7 @@ decl_value_expr_insert (tree from, tree to)
 
   h = ggc_alloc (sizeof (struct tree_map));
   h->hash = htab_hash_pointer (from);
-  h->from = from;
+  h->base.from = from;
   h->to = to;
   loc = htab_find_slot_with_hash (value_expr_for_decl, h, h->hash, INSERT);
   *(struct tree_map **) loc = h;
@@ -4963,11 +5037,26 @@ simple_cst_equal (tree t1, tree t2)
       return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
 
     case CALL_EXPR:
-      cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
+      cmp = simple_cst_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2));
       if (cmp <= 0)
        return cmp;
-      return
-       simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+      if (call_expr_nargs (t1) != call_expr_nargs (t2))
+       return 0;
+      {
+       tree arg1, arg2;
+       call_expr_arg_iterator iter1, iter2;
+       for (arg1 = first_call_expr_arg (t1, &iter1),
+              arg2 = first_call_expr_arg (t2, &iter2);
+            arg1 && arg2;
+            arg1 = next_call_expr_arg (&iter1),
+              arg2 = next_call_expr_arg (&iter2))
+         {
+           cmp = simple_cst_equal (arg1, arg2);
+           if (cmp <= 0)
+             return cmp;
+         }
+       return arg1 == arg2;
+      }
 
     case TARGET_EXPR:
       /* Special case: if either target is an unallocated VAR_DECL,
@@ -5231,7 +5320,7 @@ iterative_hash_expr (tree t, hashval_t val)
              val = iterative_hash_hashval_t (two, val);
            }
          else
-           for (i = TREE_CODE_LENGTH (code) - 1; i >= 0; --i)
+           for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
              val = iterative_hash_expr (TREE_OPERAND (t, i), val);
        }
       return val;
@@ -5558,6 +5647,78 @@ get_inner_array_type (tree array)
   return type;
 }
 
+/* Computes the canonical argument types from the argument type list
+   ARGTYPES. 
+
+   Upon return, *ANY_STRUCTURAL_P will be true iff either it was true
+   on entry to this function, or if any of the ARGTYPES are
+   structural.
+
+   Upon return, *ANY_NONCANONICAL_P will be true iff either it was
+   true on entry to this function, or if any of the ARGTYPES are
+   non-canonical.
+
+   Returns a canonical argument list, which may be ARGTYPES when the
+   canonical argument list is unneeded (i.e., *ANY_STRUCTURAL_P is
+   true) or would not differ from ARGTYPES.  */
+
+static tree 
+maybe_canonicalize_argtypes(tree argtypes, 
+                           bool *any_structural_p,
+                           bool *any_noncanonical_p)
+{
+  tree arg;
+  bool any_noncanonical_argtypes_p = false;
+  
+  for (arg = argtypes; arg && !(*any_structural_p); arg = TREE_CHAIN (arg))
+    {
+      if (!TREE_VALUE (arg) || TREE_VALUE (arg) == error_mark_node)
+       /* Fail gracefully by stating that the type is structural.  */
+       *any_structural_p = true;
+      else if (TYPE_STRUCTURAL_EQUALITY_P (TREE_VALUE (arg)))
+       *any_structural_p = true;
+      else if (TYPE_CANONICAL (TREE_VALUE (arg)) != TREE_VALUE (arg)
+              || TREE_PURPOSE (arg))
+       /* If the argument has a default argument, we consider it
+          non-canonical even though the type itself is canonical.
+          That way, different variants of function and method types
+          with default arguments will all point to the variant with
+          no defaults as their canonical type.  */
+        any_noncanonical_argtypes_p = true;
+    }
+
+  if (*any_structural_p)
+    return argtypes;
+
+  if (any_noncanonical_argtypes_p)
+    {
+      /* Build the canonical list of argument types.  */
+      tree canon_argtypes = NULL_TREE;
+      bool is_void = false;
+
+      for (arg = argtypes; arg; arg = TREE_CHAIN (arg))
+        {
+          if (arg == void_list_node)
+            is_void = true;
+          else
+            canon_argtypes = tree_cons (NULL_TREE,
+                                        TYPE_CANONICAL (TREE_VALUE (arg)),
+                                        canon_argtypes);
+        }
+
+      canon_argtypes = nreverse (canon_argtypes);
+      if (is_void)
+        canon_argtypes = chainon (canon_argtypes, void_list_node);
+
+      /* There is a non-canonical type.  */
+      *any_noncanonical_p = true;
+      return canon_argtypes;
+    }
+
+  /* The canonical argument types are the same as ARGTYPES.  */
+  return argtypes;
+}
+
 /* Construct, lay out and return
    the type of functions returning type VALUE_TYPE
    given arguments of types ARG_TYPES.
@@ -5570,6 +5731,8 @@ build_function_type (tree value_type, tree arg_types)
 {
   tree t;
   hashval_t hashcode = 0;
+  bool any_structural_p, any_noncanonical_p;
+  tree canon_argtypes;
 
   if (TREE_CODE (value_type) == FUNCTION_TYPE)
     {
@@ -5582,14 +5745,23 @@ build_function_type (tree value_type, tree arg_types)
   TREE_TYPE (t) = value_type;
   TYPE_ARG_TYPES (t) = arg_types;
 
-  /* We don't have canonicalization of function types, yet. */
-  SET_TYPE_STRUCTURAL_EQUALITY (t);
-
   /* If we already have such a type, use the old one.  */
   hashcode = iterative_hash_object (TYPE_HASH (value_type), hashcode);
   hashcode = type_hash_list (arg_types, hashcode);
   t = type_hash_canon (hashcode, t);
 
+  /* Set up the canonical type. */
+  any_structural_p   = TYPE_STRUCTURAL_EQUALITY_P (value_type);
+  any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type;
+  canon_argtypes = maybe_canonicalize_argtypes (arg_types, 
+                                               &any_structural_p,
+                                               &any_noncanonical_p);
+  if (any_structural_p)
+    SET_TYPE_STRUCTURAL_EQUALITY (t);
+  else if (any_noncanonical_p)
+    TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type),
+                                             canon_argtypes);
+      
   if (!COMPLETE_TYPE_P (t))
     layout_type (t);
   return t;
@@ -5639,6 +5811,8 @@ build_method_type_directly (tree basetype,
   tree t;
   tree ptype;
   int hashcode = 0;
+  bool any_structural_p, any_noncanonical_p;
+  tree canon_argtypes;
 
   /* Make a node of the sort we want.  */
   t = make_node (METHOD_TYPE);
@@ -5652,15 +5826,29 @@ build_method_type_directly (tree basetype,
   argtypes = tree_cons (NULL_TREE, ptype, argtypes);
   TYPE_ARG_TYPES (t) = argtypes;
 
-  /* We don't have canonicalization of method types yet. */
-  SET_TYPE_STRUCTURAL_EQUALITY (t);
-
   /* If we already have such a type, use the old one.  */
   hashcode = iterative_hash_object (TYPE_HASH (basetype), hashcode);
   hashcode = iterative_hash_object (TYPE_HASH (rettype), hashcode);
   hashcode = type_hash_list (argtypes, hashcode);
   t = type_hash_canon (hashcode, t);
 
+  /* Set up the canonical type. */
+  any_structural_p
+    = (TYPE_STRUCTURAL_EQUALITY_P (basetype)
+       || TYPE_STRUCTURAL_EQUALITY_P (rettype));
+  any_noncanonical_p
+    = (TYPE_CANONICAL (basetype) != basetype
+       || TYPE_CANONICAL (rettype) != rettype);
+  canon_argtypes = maybe_canonicalize_argtypes (TREE_CHAIN (argtypes),
+                                               &any_structural_p,
+                                               &any_noncanonical_p);
+  if (any_structural_p)
+    SET_TYPE_STRUCTURAL_EQUALITY (t);
+  else if (any_noncanonical_p)
+    TYPE_CANONICAL (t) 
+      = build_method_type_directly (TYPE_CANONICAL (basetype),
+                                   TYPE_CANONICAL (rettype),
+                                   canon_argtypes);
   if (!COMPLETE_TYPE_P (t))
     layout_type (t);
 
@@ -5782,7 +5970,7 @@ build_complex_type (tree component_type)
        name = 0;
 
       if (name != 0)
-       TYPE_NAME (t) = get_identifier (name);
+       TYPE_NAME (t) = build_decl (TYPE_DECL, get_identifier (name), t);
     }
 
   return build_qualified_type (t, TYPE_QUALS (component_type));
@@ -6009,12 +6197,13 @@ int_fits_type_p (tree c, tree type)
   tree type_low_bound = TYPE_MIN_VALUE (type);
   tree type_high_bound = TYPE_MAX_VALUE (type);
   bool ok_for_low_bound, ok_for_high_bound;
-  tree tmp;
+  unsigned HOST_WIDE_INT low;
+  HOST_WIDE_INT high;
 
   /* If at least one bound of the type is a constant integer, we can check
      ourselves and maybe make a decision. If no such decision is possible, but
      this type is a subtype, try checking against that.  Otherwise, use
-     force_fit_type, which checks against the precision.
+     fit_double_type, which checks against the precision.
 
      Compute the status for each possibly constant bound, and return if we see
      one does not match. Use ok_for_xxx_bound for this purpose, assigning -1
@@ -6069,12 +6258,51 @@ int_fits_type_p (tree c, tree type)
       && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (type)))
     return int_fits_type_p (c, TREE_TYPE (type));
 
-  /* Or to force_fit_type, if nothing else.  */
-  tmp = copy_node (c);
-  TREE_TYPE (tmp) = type;
-  tmp = force_fit_type (tmp, -1, false, false);
-  return TREE_INT_CST_HIGH (tmp) == TREE_INT_CST_HIGH (c)
-         && TREE_INT_CST_LOW (tmp) == TREE_INT_CST_LOW (c);
+  /* Or to fit_double_type, if nothing else.  */
+  low = TREE_INT_CST_LOW (c);
+  high = TREE_INT_CST_HIGH (c);
+  return !fit_double_type (low, high, &low, &high, type);
+}
+
+/* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
+   bounds or is a POINTER_TYPE, the maximum and/or minimum values that can be
+   represented (assuming two's-complement arithmetic) within the bit
+   precision of the type are returned instead.  */
+
+void
+get_type_static_bounds (tree type, mpz_t min, mpz_t max)
+{
+  if (!POINTER_TYPE_P (type) && TYPE_MIN_VALUE (type)
+      && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
+    mpz_set_double_int (min, tree_to_double_int (TYPE_MIN_VALUE (type)),
+                       TYPE_UNSIGNED (type));
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       mpz_set_ui (min, 0);
+      else
+       {
+         double_int mn;
+         mn = double_int_mask (TYPE_PRECISION (type) - 1);
+         mn = double_int_sext (double_int_add (mn, double_int_one),
+                               TYPE_PRECISION (type));
+         mpz_set_double_int (min, mn, false);
+       }
+    }
+
+  if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type) 
+      && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
+    mpz_set_double_int (max, tree_to_double_int (TYPE_MAX_VALUE (type)),
+                       TYPE_UNSIGNED (type));
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type)),
+                           true);
+      else
+       mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type) - 1),
+                           true);
+    }
 }
 
 /* Subprogram of following function.  Called by walk_tree.
@@ -6294,7 +6522,7 @@ get_callee_fndecl (tree call)
 
   /* The first operand to the CALL is the address of the function
      called.  */
-  addr = TREE_OPERAND (call, 0);
+  addr = CALL_EXPR_FN (call);
 
   STRIP_NOPS (addr);
 
@@ -6454,7 +6682,7 @@ get_file_function_name (const char *type)
       clean_symbol_name (q);
 
       sprintf (q + len, "_%08X_%08X", crc32_string (0, name),
-              crc32_string (0, flag_random_seed));
+              crc32_string (0, get_random_seed (false)));
 
       p = q;
     }
@@ -6682,7 +6910,7 @@ tree_contains_struct_check_failed (const tree node,
                                   const char *function)
 {
   internal_error
-    ("tree check: expected tree that contains %qs structure, have %qs  in %s, at %s:%d",
+    ("tree check: expected tree that contains %qs structure, have %qs in %s, at %s:%d",
      TS_ENUM_NAME(en),
      tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
 }
@@ -6713,15 +6941,16 @@ phi_node_elt_check_failed (int idx, int len, const char *file, int line,
 }
 
 /* Similar to above, except that the check is for the bounds of the operand
-   vector of an expression node.  */
+   vector of an expression node EXP.  */
 
 void
-tree_operand_check_failed (int idx, enum tree_code code, const char *file,
+tree_operand_check_failed (int idx, tree exp, const char *file,
                           int line, const char *function)
 {
+  int code = TREE_CODE (exp);
   internal_error
     ("tree check: accessed operand %d of %s with %d operands in %s, at %s:%d",
-     idx + 1, tree_code_name[code], TREE_CODE_LENGTH (code),
+     idx + 1, tree_code_name[code], TREE_OPERAND_LENGTH (exp),
      function, trim_filename (file), line);
 }
 
@@ -6960,21 +7189,10 @@ build_common_tree_nodes_2 (int short_double)
   TYPE_MODE (dfloat128_type_node) = TDmode;
   dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
 
-  complex_integer_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_integer_type_node) = integer_type_node;
-  layout_type (complex_integer_type_node);
-
-  complex_float_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_float_type_node) = float_type_node;
-  layout_type (complex_float_type_node);
-
-  complex_double_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_double_type_node) = double_type_node;
-  layout_type (complex_double_type_node);
-
-  complex_long_double_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
-  layout_type (complex_long_double_type_node);
+  complex_integer_type_node = build_complex_type (integer_type_node);
+  complex_float_type_node = build_complex_type (float_type_node);
+  complex_double_type_node = build_complex_type (double_type_node);
+  complex_long_double_type_node = build_complex_type (long_double_type_node);
 
   {
     tree t = targetm.build_builtin_va_list ();
@@ -7185,11 +7403,18 @@ tree
 reconstruct_complex_type (tree type, tree bottom)
 {
   tree inner, outer;
-
-  if (POINTER_TYPE_P (type))
+  
+  if (TREE_CODE (type) == POINTER_TYPE)
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
+                                          TYPE_REF_CAN_ALIAS_ALL (type));
+    }
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
     {
       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
-      outer = build_pointer_type (inner);
+      outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
+                                            TYPE_REF_CAN_ALIAS_ALL (type));
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -7203,15 +7428,14 @@ reconstruct_complex_type (tree type, tree bottom)
     }
   else if (TREE_CODE (type) == METHOD_TYPE)
     {
-      tree argtypes;
       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
       /* The build_method_type_directly() routine prepends 'this' to argument list,
          so we must compensate by getting rid of it.  */
-      argtypes = TYPE_ARG_TYPES (type);
-      outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
-                                         inner,
-                                         TYPE_ARG_TYPES (type));
-      TYPE_ARG_TYPES (outer) = argtypes;
+      outer 
+       = build_method_type_directly 
+           (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))),
+            inner,
+            TREE_CHAIN (TYPE_ARG_TYPES (type)));
     }
   else
     return bottom;
@@ -7353,6 +7577,149 @@ build_omp_clause (enum omp_clause_code code)
   return t;
 }
 
+/* Set various status flags when building a CALL_EXPR object T.  */
+
+static void
+process_call_operands (tree t)
+{
+  bool side_effects;
+
+  side_effects = TREE_SIDE_EFFECTS (t);
+  if (!side_effects)
+    {
+      int i, n;
+      n = TREE_OPERAND_LENGTH (t);
+      for (i = 1; i < n; i++)
+       {
+         tree op = TREE_OPERAND (t, i);
+         if (op && TREE_SIDE_EFFECTS (op))
+           {
+             side_effects = 1;
+             break;
+           }
+       }
+    }
+  if (!side_effects)
+    {
+      int i;
+
+      /* Calls have side-effects, except those to const or
+        pure functions.  */
+      i = call_expr_flags (t);
+      if (!(i & (ECF_CONST | ECF_PURE)))
+       side_effects = 1;
+    }
+  TREE_SIDE_EFFECTS (t) = side_effects;
+}
+
+/* Build a tcc_vl_exp object with code CODE and room for LEN operands.  LEN
+   includes the implicit operand count in TREE_OPERAND 0, and so must be >= 1.
+   Except for the CODE and operand count field, other storage for the
+   object is initialized to zeros.  */
+
+tree
+build_vl_exp_stat (enum tree_code code, int len MEM_STAT_DECL)
+{
+  tree t;
+  int length = (len - 1) * sizeof (tree) + sizeof (struct tree_exp);
+
+  gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
+  gcc_assert (len >= 1);
+
+#ifdef GATHER_STATISTICS
+  tree_node_counts[(int) e_kind]++;
+  tree_node_sizes[(int) e_kind] += length;
+#endif
+
+  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+
+  memset (t, 0, length);
+
+  TREE_SET_CODE (t, code);
+
+  /* Can't use TREE_OPERAND to store the length because if checking is
+     enabled, it will try to check the length before we store it.  :-P  */
+  t->exp.operands[0] = build_int_cst (sizetype, len);
+
+  return t;
+}
+
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE
+   and FN and a null static chain slot.  ARGLIST is a TREE_LIST of the
+   arguments.  */
+
+tree
+build_call_list (tree return_type, tree fn, tree arglist)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, list_length (arglist) + 3);
+  TREE_TYPE (t) = return_type;
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; arglist; arglist = TREE_CHAIN (arglist), i++)
+    CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
+  process_call_operands (t);
+  return t;
+}
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
+   FN and a null static chain slot.  NARGS is the number of call arguments
+   which are specified as "..." arguments.  */
+
+tree
+build_call_nary (tree return_type, tree fn, int nargs, ...)
+{
+  tree ret;
+  va_list args;
+  va_start (args, nargs);
+  ret = build_call_valist (return_type, fn, nargs, args);
+  va_end (args);
+  return ret;
+}
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
+   FN and a null static chain slot.  NARGS is the number of call arguments
+   which are specified as a va_list ARGS.  */
+
+tree
+build_call_valist (tree return_type, tree fn, int nargs, va_list args)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, nargs + 3);
+  TREE_TYPE (t) = return_type;
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; i < nargs; i++)
+    CALL_EXPR_ARG (t, i) = va_arg (args, tree);
+  process_call_operands (t);
+  return t;
+}
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
+   FN and a null static chain slot.  NARGS is the number of call arguments
+   which are specified as a tree array ARGS.  */
+
+tree
+build_call_array (tree return_type, tree fn, int nargs, tree *args)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, nargs + 3);
+  TREE_TYPE (t) = return_type;
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; i < nargs; i++)
+    CALL_EXPR_ARG (t, i) = args[i];
+  process_call_operands (t);
+  return t;
+}
+
 
 /* Returns true if it is possible to prove that the index of
    an array access REF (an ARRAY_REF expression) falls into the
@@ -7415,17 +7782,6 @@ range_in_array_bounds_p (tree ref)
   return true;
 }
 
-/* Return true if T (assumed to be a DECL) is a global variable.  */
-
-bool
-is_global_var (tree t)
-{
-  if (MTAG_P (t))
-    return (TREE_STATIC (t) || MTAG_GLOBAL (t));
-  else
-    return (TREE_STATIC (t) || DECL_EXTERNAL (t));
-}
-
 /* Return true if T (assumed to be a DECL) must be assigned a memory
    location.  */
 
@@ -7456,7 +7812,7 @@ fields_compatible_p (tree f1, tree f2)
                         DECL_FIELD_OFFSET (f2), OEP_ONLY_CONST))
     return false;
 
-  if (!lang_hooks.types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+  if (!types_compatible_p (TREE_TYPE (f1), TREE_TYPE (f2)))
     return false;
 
   return true;
@@ -7504,43 +7860,21 @@ int_cst_value (tree x)
   return val;
 }
 
-/* Returns the greatest common divisor of A and B, which must be
-   INTEGER_CSTs.  */
+/* If TYPE is an integral type, return an equivalent type which is
+    unsigned iff UNSIGNEDP is true.  If TYPE is not an integral type,
+    return TYPE itself.  */
 
 tree
-tree_fold_gcd (tree a, tree b)
+signed_or_unsigned_type_for (int unsignedp, tree type)
 {
-  tree a_mod_b;
-  tree type = TREE_TYPE (a);
-
-  gcc_assert (TREE_CODE (a) == INTEGER_CST);
-  gcc_assert (TREE_CODE (b) == INTEGER_CST);
-
-  if (integer_zerop (a))
-    return b;
-
-  if (integer_zerop (b))
-    return a;
-
-  if (tree_int_cst_sgn (a) == -1)
-    a = fold_build2 (MULT_EXPR, type, a,
-                    build_int_cst (type, -1));
-
-  if (tree_int_cst_sgn (b) == -1)
-    b = fold_build2 (MULT_EXPR, type, b,
-                    build_int_cst (type, -1));
-
-  while (1)
-    {
-      a_mod_b = fold_build2 (FLOOR_MOD_EXPR, type, a, b);
-
-      if (!TREE_INT_CST_LOW (a_mod_b)
-         && !TREE_INT_CST_HIGH (a_mod_b))
-       return b;
+  tree t = type;
+  if (POINTER_TYPE_P (type))
+    t = size_type_node;
 
-      a = b;
-      b = a_mod_b;
-    }
+  if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
+    return t;
+  
+  return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp);
 }
 
 /* Returns unsigned variant of TYPE.  */
@@ -7548,9 +7882,7 @@ tree_fold_gcd (tree a, tree b)
 tree
 unsigned_type_for (tree type)
 {
-  if (POINTER_TYPE_P (type))
-    return lang_hooks.types.unsigned_type (size_type_node);
-  return lang_hooks.types.unsigned_type (type);
+  return signed_or_unsigned_type_for (1, type);
 }
 
 /* Returns signed variant of TYPE.  */
@@ -7558,9 +7890,7 @@ unsigned_type_for (tree type)
 tree
 signed_type_for (tree type)
 {
-  if (POINTER_TYPE_P (type))
-    return lang_hooks.types.signed_type (size_type_node);
-  return lang_hooks.types.signed_type (type);
+  return signed_or_unsigned_type_for (0, type);
 }
 
 /* Returns the largest value obtainable by casting something in INNER type to
@@ -7793,10 +8123,12 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
       break;
 
     case ARRAY_TYPE:
-      /* Don't follow this nodes's type if a pointer for fear that we'll
-        have infinite recursion.  Those types are uninteresting anyway.  */
-      if (!POINTER_TYPE_P (TREE_TYPE (type))
-         && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE)
+      /* Don't follow this nodes's type if a pointer for fear that
+        we'll have infinite recursion.  If we have a PSET, then we
+        need not fear.  */
+      if (pset
+         || (!POINTER_TYPE_P (TREE_TYPE (type))
+             && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE))
        WALK_SUBTREE (TREE_TYPE (type));
       WALK_SUBTREE (TYPE_DOMAIN (type));
       break;
@@ -8074,7 +8406,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
          int i, len;
 
          /* Walk over all the sub-trees of this operand.  */
-         len = TREE_CODE_LENGTH (code);
+         len = TREE_OPERAND_LENGTH (*tp);
 
          /* Go through the subtrees.  We need to do this in forward order so
             that the scope of a FOR_EXPR is handled properly.  */
@@ -8167,4 +8499,19 @@ generic_tree_type (tree node)
   return &TREE_TYPE (node);
 }
 
+/* Build and return a TREE_LIST of arguments in the CALL_EXPR exp.
+   FIXME: don't use this function.  It exists for compatibility with
+   the old representation of CALL_EXPRs where a list was used to hold the
+   arguments.  Places that currently extract the arglist from a CALL_EXPR
+   ought to be rewritten to use the CALL_EXPR itself.  */
+tree
+call_expr_arglist (tree exp)
+{
+  tree arglist = NULL_TREE;
+  int i;
+  for (i = call_expr_nargs (exp) - 1; i >= 0; i--)
+    arglist = tree_cons (NULL_TREE, CALL_EXPR_ARG (exp, i), arglist);
+  return arglist;
+}
+
 #include "gt-tree.h"