OSDN Git Service

(fold, COND_EXPR case): All simplified results
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 4eea2c9..5f57d43 100644 (file)
@@ -1,5 +1,5 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
-   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -33,12 +33,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    by all passes of the compiler.  */
 
 #include "config.h"
-#include <stdio.h>
 #include "flags.h"
-#include "function.h"
 #include "tree.h"
+#include "function.h"
 #include "obstack.h"
 #include "gvarargs.h"
+#include <stdio.h>
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
@@ -195,16 +195,45 @@ char **tree_code_name;
 /* Statistics-gathering stuff.  */
 typedef enum
 {
-  d_kind, t_kind, s_kind, r_kind, e_kind, c_kind,
-  id_kind, op_id_kind, perm_list_kind, temp_list_kind,
-  vec_kind, x_kind, lang_decl, lang_type, all_kinds
+  d_kind,
+  t_kind,
+  b_kind,
+  s_kind,
+  r_kind,
+  e_kind,
+  c_kind,
+  id_kind,
+  op_id_kind,
+  perm_list_kind,
+  temp_list_kind,
+  vec_kind,
+  x_kind,
+  lang_decl,
+  lang_type,
+  all_kinds
 } tree_node_kind;
+
 int tree_node_counts[(int)all_kinds];
 int tree_node_sizes[(int)all_kinds];
 int id_string_size = 0;
-char *tree_node_kind_names[] = { "decls", "types", "stmts", "refs", "exprs", "constants",
-                                "identifiers", "op_identifiers", "perm_tree_lists", "temp_tree_lists",
-                                "vecs", "random kinds", "lang_decl kinds", "lang_type kinds" };
+
+char *tree_node_kind_names[] = {
+  "decls",
+  "types",
+  "blocks",
+  "stmts",
+  "refs",
+  "exprs",
+  "constants",
+  "identifiers",
+  "op_identifiers",
+  "perm_tree_lists",
+  "temp_tree_lists",
+  "vecs",
+  "random kinds",
+  "lang_decl kinds",
+  "lang_type kinds"
+};
 
 /* Hash table for uniquizing IDENTIFIER_NODEs by name.  */
 
@@ -216,6 +245,8 @@ static int do_identifier_warnings;
 
 /* Unique id for next decl created.  */
 static int next_decl_uid;
+/* Unique id for next type created.  */
+static int next_type_uid = 1;
 
 extern char *mode_name[];
 
@@ -495,19 +526,13 @@ rtl_in_current_obstack ()
   rtl_obstack = current_obstack;
 }
 
-/* Temporarily allocate rtl from saveable_obstack.  Return 1 if we were
-   previously allocating it from current_obstack.  */
+/* Start allocating rtl from saveable_obstack.  Intended to be used after
+   a call to push_obstacks_nochange.  */
 
-int
+void
 rtl_in_saveable_obstack ()
 {
-  if (rtl_obstack == current_obstack)
-    {
-      rtl_obstack = saveable_obstack;
-      return 1;
-    }
-  else
-    return 0;
+  rtl_obstack = saveable_obstack;
 }
 \f
 /* Allocate SIZE bytes in the current obstack
@@ -537,7 +562,7 @@ obfree (ptr)
 
 char *
 permalloc (size)
-     long size;
+     int size;
 {
   return (char *) obstack_alloc (&permanent_obstack, size);
 }
@@ -774,6 +799,16 @@ make_node (code)
        obstack = all_types_permanent ? &permanent_obstack : saveable_obstack;
       break;
 
+    case 'b':  /* a lexical block */
+#ifdef GATHER_STATISTICS
+      kind = b_kind;
+#endif
+      length = sizeof (struct tree_block);
+      /* All BLOCK nodes are put where we can preserve them if nec.  */
+      if (obstack != &permanent_obstack)
+       obstack = saveable_obstack;
+      break;
+
     case 's':  /* an expression with side effects */
 #ifdef GATHER_STATISTICS
       kind = s_kind;
@@ -793,10 +828,8 @@ make_node (code)
     usual_kind:
 #endif
       obstack = expression_obstack;
-      /* All BLOCK nodes are put where we can preserve them if nec.
-        Also their potential controllers.  */
-      if ((code == BLOCK || code == BIND_EXPR)
-         && obstack != &permanent_obstack)
+      /* All BIND_EXPR nodes are put where we can preserve them if nec.  */
+      if (code == BIND_EXPR && obstack != &permanent_obstack)
        obstack = saveable_obstack;
       length = sizeof (struct tree_exp)
        + (tree_code_length[(int) code] - 1) * sizeof (char *);
@@ -807,13 +840,21 @@ make_node (code)
       kind = c_kind;
 #endif
       obstack = expression_obstack;
-      /* We can't use tree_code_length for this, since the number of words
-        is machine-dependent due to varying alignment of `double'.  */
-      if (code == REAL_CST)
-       {
-         length = sizeof (struct tree_real_cst);
-         break;
-       }
+
+      /* We can't use tree_code_length for INTEGER_CST, since the number of
+        words is machine-dependent due to varying length of HOST_WIDE_INT,
+        which might be wider than a pointer (e.g., long long).  Similarly
+        for REAL_CST, since the number of words is machine-dependent due
+        to varying size and alignment of `double'.  */
+
+      if (code == INTEGER_CST)
+       length = sizeof (struct tree_int_cst);
+      else if (code == REAL_CST)
+       length = sizeof (struct tree_real_cst);
+      else
+       length = sizeof (struct tree_common)
+         + tree_code_length[(int) code] * sizeof (char *);
+      break;
 
     case 'x':  /* something random, like an identifier.  */
 #ifdef GATHER_STATISTICS
@@ -840,8 +881,12 @@ make_node (code)
   tree_node_sizes[(int)kind] += length;
 #endif
 
+  /* Clear a word at a time.  */
   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
     ((int *) t)[i] = 0;
+  /* Clear any extra bytes.  */
+  for (i = length / sizeof (int) * sizeof (int); i < length; i++)
+    ((char *) t)[i] = 0;
 
   TREE_SET_CODE (t, code);
   if (obstack == &permanent_obstack)
@@ -857,17 +902,15 @@ make_node (code)
     case 'd':
       if (code != FUNCTION_DECL)
        DECL_ALIGN (t) = 1;
+      DECL_IN_SYSTEM_HEADER (t)
+       = in_system_header && (obstack == &permanent_obstack);
       DECL_SOURCE_LINE (t) = lineno;
       DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
       DECL_UID (t) = next_decl_uid++;
       break;
 
     case 't':
-      {
-       static unsigned next_type_uid = 1;
-
-       TYPE_UID (t) = next_type_uid++;
-      }
+      TYPE_UID (t) = next_type_uid++;
       TYPE_ALIGN (t) = 1;
       TYPE_MAIN_VARIANT (t) = t;
       break;
@@ -902,8 +945,12 @@ copy_node (node)
       length = sizeof (struct tree_type);
       break;
 
+    case 'b':  /* a lexical block node */
+      length = sizeof (struct tree_block);
+      break;
+
     case 'r':  /* a reference */
-    case 'e':  /* a expression */
+    case 'e':  /* an expression */
     case 's':  /* an expression with side effects */
     case '<':  /* a comparison expression */
     case '1':  /* a unary arithmetic expression */
@@ -930,13 +977,19 @@ copy_node (node)
 
   t = (tree) obstack_alloc (current_obstack, length);
 
-  for (i = ((length + sizeof (int) - 1) / sizeof (int)) - 1;
-       i >= 0;
-       i--)
+  for (i = (length / sizeof (int)) - 1; i >= 0; i--)
     ((int *) t)[i] = ((int *) node)[i];
+  /* Clear any extra bytes.  */
+  for (i = length / sizeof (int) * sizeof (int); i < length; i++)
+    ((char *) t)[i] = ((char *) node)[i];
 
   TREE_CHAIN (t) = 0;
 
+  if (TREE_CODE_CLASS (code) == 'd')
+    DECL_UID (t) = next_decl_uid++;
+  else if (TREE_CODE_CLASS (code) == 't')
+    TYPE_UID (t) = next_type_uid++;
+
   TREE_PERMANENT (t) = (current_obstack == &permanent_obstack);
 
   return t;
@@ -1055,11 +1108,13 @@ set_identifier_size (size)
 \f
 /* Return a newly constructed INTEGER_CST node whose constant value
    is specified by the two ints LOW and HI.
-   The TREE_TYPE is set to `int'.  */
+   The TREE_TYPE is set to `int'. 
+
+   This function should be used via the `build_int_2' macro.  */
 
 tree
-build_int_2 (low, hi)
-     int low, hi;
+build_int_2_wide (low, hi)
+     HOST_WIDE_INT low, hi;
 {
   register tree t = make_node (INTEGER_CST);
   TREE_INT_CST_LOW (t) = low;
@@ -1099,23 +1154,34 @@ real_value_from_int_cst (i)
      tree i;
 {
   REAL_VALUE_TYPE d;
+  REAL_VALUE_TYPE e;
+  /* Some 386 compilers mishandle unsigned int to float conversions,
+     so introduce a temporary variable E to avoid those bugs.  */
+
 #ifdef REAL_ARITHMETIC
-  REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
+  if (! TREE_UNSIGNED (TREE_TYPE (i)))
+    REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
+  else
+    REAL_VALUE_FROM_UNSIGNED_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
 #else /* not REAL_ARITHMETIC */
-  if (TREE_INT_CST_HIGH (i) < 0)
+  if (TREE_INT_CST_HIGH (i) < 0 && ! TREE_UNSIGNED (TREE_TYPE (i)))
     {
       d = (double) (~ TREE_INT_CST_HIGH (i));
-      d *= ((double) (1 << (HOST_BITS_PER_INT / 2))
-           * (double) (1 << (HOST_BITS_PER_INT / 2)));
-      d += (double) (unsigned) (~ TREE_INT_CST_LOW (i));
+      e = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
+           * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
+      d *= e;
+      e = (double) (unsigned HOST_WIDE_INT) (~ TREE_INT_CST_LOW (i));
+      d += e;
       d = (- d - 1.0);
     }
   else
     {
-      d = (double) TREE_INT_CST_HIGH (i);
-      d *= ((double) (1 << (HOST_BITS_PER_INT / 2))
-           * (double) (1 << (HOST_BITS_PER_INT / 2)));
-      d += (double) (unsigned) TREE_INT_CST_LOW (i);
+      d = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (i);
+      e = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
+           * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
+      d *= e;
+      e = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (i);
+      d += e;
     }
 #endif /* not REAL_ARITHMETIC */
   return d;
@@ -1135,7 +1201,7 @@ build_real_from_int_cst (type, i)
   v = make_node (REAL_CST);
   TREE_TYPE (v) = type;
 
-  d = real_value_from_int_cst (i);
+  d = REAL_VALUE_TRUNCATE (TYPE_MODE (type), real_value_from_int_cst (i));
   /* Check for valid float value for this type on this target machine;
      if not, can print error message and store a valid value in D.  */
 #ifdef CHECK_FLOAT_VALUE
@@ -1175,6 +1241,7 @@ build_complex (real, imag)
   register tree t = make_node (COMPLEX_CST);
   TREE_REALPART (t) = real;
   TREE_IMAGPART (t) = imag;
+  TREE_TYPE (t) = build_complex_type (TREE_TYPE (real));
   return t;
 }
 
@@ -1195,12 +1262,9 @@ make_tree_vec (len)
 
   t = (tree) obstack_alloc (obstack, length);
 
-  TREE_TYPE (t) = 0;
-  TREE_CHAIN (t) = 0;
-  for (i = (length / sizeof (int)) - 1;
-       i >= sizeof (struct tree_common) / sizeof (int) - 1;
-       i--)
+  for (i = (length / sizeof (int)) - 1; i >= 0; i--)
     ((int *) t)[i] = 0;
+
   TREE_SET_CODE (t, TREE_VEC);
   TREE_VEC_LENGTH (t) = len;
   if (obstack == &permanent_obstack)
@@ -1215,8 +1279,7 @@ int
 integer_zerop (expr)
      tree expr;
 {
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   return (TREE_CODE (expr) == INTEGER_CST
          && TREE_INT_CST_LOW (expr) == 0
@@ -1229,8 +1292,7 @@ int
 integer_onep (expr)
      tree expr;
 {
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   return (TREE_CODE (expr) == INTEGER_CST
          && TREE_INT_CST_LOW (expr) == 1
@@ -1247,8 +1309,7 @@ integer_all_onesp (expr)
   register int prec;
   register int uns;
 
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
@@ -1258,27 +1319,27 @@ integer_all_onesp (expr)
     return TREE_INT_CST_LOW (expr) == -1 && TREE_INT_CST_HIGH (expr) == -1;
 
   prec = TYPE_PRECISION (TREE_TYPE (expr));
-  if (prec >= HOST_BITS_PER_INT)
+  if (prec >= HOST_BITS_PER_WIDE_INT)
     {
       int high_value, shift_amount;
 
-      shift_amount = prec - HOST_BITS_PER_INT;
+      shift_amount = prec - HOST_BITS_PER_WIDE_INT;
 
-      if (shift_amount > HOST_BITS_PER_INT)
+      if (shift_amount > HOST_BITS_PER_WIDE_INT)
        /* Can not handle precisions greater than twice the host int size.  */
        abort ();
-      else if (shift_amount == HOST_BITS_PER_INT)
+      else if (shift_amount == HOST_BITS_PER_WIDE_INT)
        /* Shifting by the host word size is undefined according to the ANSI
           standard, so we must handle this as a special case.  */
        high_value = -1;
       else
-       high_value = (1 << shift_amount) - 1;
+       high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1;
 
       return TREE_INT_CST_LOW (expr) == -1
        && TREE_INT_CST_HIGH (expr) == high_value;
     }
   else
-    return TREE_INT_CST_LOW (expr) == (1 << prec) - 1;
+    return TREE_INT_CST_LOW (expr) == ((HOST_WIDE_INT) 1 << prec) - 1;
 }
 
 /* Return 1 if EXPR is an integer constant that is a power of 2 (i.e., has only
@@ -1288,10 +1349,9 @@ int
 integer_pow2p (expr)
      tree expr;
 {
-  int high, low;
+  HOST_WIDE_INT high, low;
 
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
@@ -1312,8 +1372,7 @@ int
 real_zerop (expr)
      tree expr;
 {
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   return (TREE_CODE (expr) == REAL_CST
          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0));
@@ -1325,8 +1384,7 @@ int
 real_onep (expr)
      tree expr;
 {
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   return (TREE_CODE (expr) == REAL_CST
          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1));
@@ -1338,8 +1396,7 @@ int
 real_twop (expr)
      tree expr;
 {
-  while (TREE_CODE (expr) == NON_LVALUE_EXPR)
-    expr = TREE_OPERAND (expr, 0);
+  STRIP_NOPS (expr);
 
   return (TREE_CODE (expr) == REAL_CST
          && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2));
@@ -1351,6 +1408,7 @@ int
 really_constant_p (exp)
      tree exp;
 {
+  /* This is not quite the same as STRIP_NOPS.  It does more.  */
   while (TREE_CODE (exp) == NOP_EXPR
         || TREE_CODE (exp) == CONVERT_EXPR
         || TREE_CODE (exp) == NON_LVALUE_EXPR)
@@ -1453,6 +1511,7 @@ chainon (op1, op2)
     {
       for (t = op1; TREE_CHAIN (t); t = TREE_CHAIN (t))
        if (t == op2) abort (); /* Circularity being created */
+      if (t == op2) abort ();  /* Circularity being created */
       TREE_CHAIN (t) = op2;
       return op1;
     }
@@ -1559,11 +1618,12 @@ tree_cons (purpose, value, chain)
   tree_node_sizes[(int)x_kind] += sizeof (struct tree_list);
 #endif
 
-  ((int *)node)[(sizeof (struct tree_common)/sizeof (int)) - 1] = 0;
+  for (i = (sizeof (struct tree_common) / sizeof (int)) - 1; i >= 0; i--)
+    ((int *) node)[i] = 0;
+
   TREE_SET_CODE (node, TREE_LIST);
   if (current_obstack == &permanent_obstack)
     TREE_PERMANENT (node) = 1;
-  TREE_TYPE (node) = 0;
 #endif
 
   TREE_CHAIN (node) = chain;
@@ -1641,16 +1701,21 @@ tree
 size_in_bytes (type)
      tree type;
 {
+  tree t;
+
   if (type == error_mark_node)
     return integer_zero_node;
   type = TYPE_MAIN_VARIANT (type);
   if (TYPE_SIZE (type) == 0)
     {
-      incomplete_type_error (0, type);
+      incomplete_type_error (NULL_TREE, type);
       return integer_zero_node;
     }
-  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
-                    size_int (BITS_PER_UNIT));
+  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+                 size_int (BITS_PER_UNIT));
+  if (TREE_CODE (t) == INTEGER_CST)
+    force_fit_type (t, 0);
+  return t;
 }
 
 /* Return the size of TYPE (in bytes) as an integer,
@@ -1660,7 +1725,7 @@ int
 int_size_in_bytes (type)
      tree type;
 {
-  int size;
+  unsigned int size;
   if (type == error_mark_node)
     return 0;
   type = TYPE_MAIN_VARIANT (type);
@@ -1668,22 +1733,28 @@ int_size_in_bytes (type)
     return -1;
   if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
     return -1;
+  if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0)
+    {
+      tree t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+                          size_int (BITS_PER_UNIT));
+      return TREE_INT_CST_LOW (t);
+    }
   size = TREE_INT_CST_LOW (TYPE_SIZE (type));
   return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
 }
-
-/* Return, as an INTEGER_CST node, the number of elements for
-   TYPE (which is an ARRAY_TYPE) minus one. 
-   This counts only elements of the top array.  */
+\f
+/* Return, as a tree node, the number of elements for TYPE (which is an
+   ARRAY_TYPE) minus one. This counts only elements of the top array.  */
 
 tree
 array_type_nelts (type)
      tree type;
 {
   tree index_type = TYPE_DOMAIN (type);
-  return (tree_int_cst_equal (TYPE_MIN_VALUE (index_type), integer_zero_node)
+
+  return (integer_zerop (TYPE_MIN_VALUE (index_type))
          ? TYPE_MAX_VALUE (index_type)
-         : fold (build (MINUS_EXPR, integer_type_node,
+         : fold (build (MINUS_EXPR, TREE_TYPE (TYPE_MAX_VALUE (index_type)),
                         TYPE_MAX_VALUE (index_type),
                         TYPE_MIN_VALUE (index_type))));
 }
@@ -1700,7 +1771,7 @@ staticp (arg)
     case VAR_DECL:
     case FUNCTION_DECL:
     case CONSTRUCTOR:
-      return TREE_STATIC (arg) || TREE_EXTERNAL (arg);
+      return TREE_STATIC (arg) || DECL_EXTERNAL (arg);
 
     case STRING_CST:
       return 1;
@@ -1747,7 +1818,7 @@ save_expr (expr)
       || TREE_CODE (t) == SAVE_EXPR)
     return t;
 
-  t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL);
+  t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL_TREE);
 
   /* This expression might be placed ahead of a jump to ensure that the
      value was computed on both sides of the jump.  So make sure it isn't
@@ -1864,6 +1935,7 @@ stabilize_reference_1 (e)
     case 'x':
     case 't':
     case 'd':
+    case 'b':
     case '<':
     case 's':
     case 'e':
@@ -1882,6 +1954,14 @@ stabilize_reference_1 (e)
       return e;
       
     case '2':
+      /* Division is slow and tends to be compiled with jumps,
+        especially the division by powers of 2 that is often
+        found inside of an array reference.  So do it just once.  */
+      if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
+         || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
+         || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
+         || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
+       return save_expr (e);
       /* Recursively stabilize each operand.  */
       result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
                         stabilize_reference_1 (TREE_OPERAND (e, 1)));
@@ -2001,13 +2081,10 @@ build1 (code, type, node)
   tree_node_sizes[(int)kind] += length;
 #endif
 
-  TREE_TYPE (t) = type;
-  TREE_CHAIN (t) = 0;
-
-  for (i = (length / sizeof (int)) - 2;
-       i >= sizeof (struct tree_common) / sizeof (int) - 1;
-       i--)
+  for (i = (length / sizeof (int)) - 1; i >= 0; i--)
     ((int *) t)[i] = 0;
+
+  TREE_TYPE (t) = type;
   TREE_SET_CODE (t, code);
 
   if (obstack == &permanent_obstack)
@@ -2131,9 +2208,7 @@ build_decl (code, name, type)
 \f
 /* BLOCK nodes are used to represent the structure of binding contours
    and declarations, once those contours have been exited and their contents
-   compiled.  This information is used for outputting debugging info.
-   A BLOCK may have a "controller" which is a BIND_EXPR node.
-   Then the BLOCK is ignored unless the controller has the TREE_USED flag.  */
+   compiled.  This information is used for outputting debugging info.  */
 
 tree
 build_block (vars, tags, subblocks, supercontext, chain)
@@ -2205,6 +2280,34 @@ build_type_variant (type, constp, volatilep)
   return t;
 }
 
+/* Give TYPE a new main variant: NEW_MAIN.
+   This is the right thing to do only when something else
+   about TYPE is modified in place.  */
+
+tree
+change_main_variant (type, new_main)
+     tree type, new_main;
+{
+  tree t;
+  tree omain = TYPE_MAIN_VARIANT (type);
+
+  /* Remove TYPE from the TYPE_NEXT_VARIANT chain of its main variant.  */
+  if (TYPE_NEXT_VARIANT (omain) == type)
+    TYPE_NEXT_VARIANT (omain) = TYPE_NEXT_VARIANT (type);
+  else
+    for (t = TYPE_NEXT_VARIANT (omain); t && TYPE_NEXT_VARIANT (t);
+        t = TYPE_NEXT_VARIANT (t))
+      if (TYPE_NEXT_VARIANT (t) == type)
+       {
+         TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (type);
+         break;
+       }
+
+  TYPE_MAIN_VARIANT (type) = new_main;
+  TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (new_main);
+  TYPE_NEXT_VARIANT (new_main) = type;
+}
+
 /* Create a new variant of TYPE, equivalent but distinct.
    This is so the caller can modify it.  */
 
@@ -2255,7 +2358,7 @@ struct type_hash *type_hash_table[TYPE_HASH_SIZE];
 
 /* Here is how primitive or already-canonicalized types' hash
    codes are made.  */
-#define TYPE_HASH(TYPE) ((int) (TYPE) & 0777777)
+#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
 
 /* Compute a hash code for a list of types (chain of TREE_LIST nodes
    with types in the TREE_VALUE slots), by adding the hash codes
@@ -2529,42 +2632,36 @@ simple_cst_equal (t1, t2)
        return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
       return 0;
 
-    case BIT_FIELD_REF:
-      return (simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
-             && simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1))
-             && simple_cst_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t2, 2)));
-
     case VAR_DECL:
     case PARM_DECL:
     case CONST_DECL:
     case FUNCTION_DECL:
       return 0;
+    }
 
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-    case MULT_EXPR:
-    case TRUNC_DIV_EXPR:
-    case TRUNC_MOD_EXPR:
-    case LSHIFT_EXPR:
-    case RSHIFT_EXPR:
-      cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      if (cmp <= 0)
-       return cmp;
-      return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
-
-    case NEGATE_EXPR:
-    case ADDR_EXPR:
-    case REFERENCE_EXPR:
-    case INDIRECT_REF:
-      return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
+  /* This general rule works for most tree codes.
+     All exceptions should be handled above.  */
 
-    default:
-#if 0
-      return lang_simple_cst_equal (t1, t2);
-#else
-      return -1;
-#endif
+  switch (TREE_CODE_CLASS (code1))
+    {
+      int i;
+    case '1':
+    case '2':
+    case '<':
+    case 'e':
+    case 'r':
+    case 's':
+      cmp = 1;
+      for (i=0; i<tree_code_length[(int) code1]; ++i)
+       {
+         cmp = simple_cst_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
+         if (cmp <= 0)
+           return cmp;
+       }
+      return cmp;
     }
+
+  return -1;
 }
 \f
 /* Constructors for pointer, array and function types.
@@ -2628,39 +2725,61 @@ build_index_type (maxval)
   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
   if (TREE_CODE (maxval) == INTEGER_CST)
     {
-      int maxint = TREE_INT_CST_LOW (maxval);
-      return type_hash_canon (maxint > 0 ? maxint : - maxint, itype);
+      int maxint = (int) TREE_INT_CST_LOW (maxval);
+      /* If the domain should be empty, make sure the maxval
+        remains -1 and is not spoiled by truncation.  */
+      if (INT_CST_LT (maxval, integer_zero_node))
+       {
+         TYPE_MAX_VALUE (itype) = build_int_2 (-1, -1);
+         TREE_TYPE (TYPE_MAX_VALUE (itype)) = sizetype;
+       }
+      return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
     }
   else
     return itype;
 }
 
-/* Just like build_index_type, but takes lowval and highval instead
-   of just highval (maxval). */
+/* Create a range of some discrete type TYPE (an INTEGER_TYPE,
+   ENUMERAL_TYPE, BOOLEAN_TYPE, or CHAR_TYPE), with
+   low bound LOWVAL and high bound HIGHVAL.
+   if TYPE==NULL_TREE, sizetype is used. */
 
 tree
-build_index_2_type (lowval,highval)
-     tree lowval, highval;
+build_range_type (type, lowval, highval)
+     tree type, lowval, highval;
 {
   register tree itype = make_node (INTEGER_TYPE);
-  TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
-  TYPE_MIN_VALUE (itype) = convert (sizetype, lowval);
-  TYPE_MAX_VALUE (itype) = convert (sizetype, highval);
-  TYPE_MODE (itype) = TYPE_MODE (sizetype);
-  TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
-  TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
+  TREE_TYPE (itype) = type;
+  if (type == NULL_TREE)
+    type = sizetype;
+  TYPE_PRECISION (itype) = TYPE_PRECISION (type);
+  TYPE_MIN_VALUE (itype) = convert (type, lowval);
+  TYPE_MAX_VALUE (itype) = convert (type, highval);
+  TYPE_MODE (itype) = TYPE_MODE (type);
+  TYPE_SIZE (itype) = TYPE_SIZE (type);
+  TYPE_ALIGN (itype) = TYPE_ALIGN (type);
   if ((TREE_CODE (lowval) == INTEGER_CST)
       && (TREE_CODE (highval) == INTEGER_CST))
     {
-      int highint = TREE_INT_CST_LOW (highval);
-      int lowint = TREE_INT_CST_LOW (lowval);
-      int maxint = highint - lowint;
-      return type_hash_canon (maxint > 0 ? maxint : - maxint, itype);
+      HOST_WIDE_INT highint = TREE_INT_CST_LOW (highval);
+      HOST_WIDE_INT lowint = TREE_INT_CST_LOW (lowval);
+      int maxint = (int) (highint - lowint);
+      return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
     }
   else
     return itype;
 }
 
+/* Just like build_index_type, but takes lowval and highval instead
+   of just highval (maxval). */
+
+tree
+build_index_2_type (lowval,highval)
+     tree lowval, highval;
+{
+  return build_range_type (NULL_TREE, lowval, highval);
+}
+
 /* Return nonzero iff ITYPE1 and ITYPE2 are equal (in the LISP sense).
    Needed because when index types are not hashed, equal index types
    built at different times appear distinct, even though structurally,
@@ -2713,11 +2832,22 @@ build_array_type (elt_type, index_type)
   TYPE_DOMAIN (t) = index_type;
 
   if (index_type == 0)
-    return t;
+    {
+      return t;
+    }
 
   hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type);
   t = type_hash_canon (hashcode, t);
 
+#if 0 /* This led to crashes, because it could put a temporary node
+        on the TYPE_NEXT_VARIANT chain of a permanent one.  */
+  /* The main variant of an array type should always
+     be an array whose element type is the main variant.  */
+  if (elt_type != TYPE_MAIN_VARIANT (elt_type))
+    change_main_variant (t, build_array_type (TYPE_MAIN_VARIANT (elt_type),
+                                             index_type));
+#endif
+
   if (TYPE_SIZE (t) == 0)
     layout_type (t);
   return t;
@@ -2737,10 +2867,9 @@ build_function_type (value_type, arg_types)
   register tree t;
   int hashcode;
 
-  if (TREE_CODE (value_type) == FUNCTION_TYPE
-      || TREE_CODE (value_type) == ARRAY_TYPE)
+  if (TREE_CODE (value_type) == FUNCTION_TYPE)
     {
-      error ("function return type cannot be function or array");
+      error ("function return type cannot be function");
       value_type = integer_type_node;
     }
 
@@ -2818,7 +2947,8 @@ build_method_type (basetype, type)
      which is "this".  Put it into the list of argument types.  */
 
   TYPE_ARG_TYPES (t)
-    = tree_cons (NULL, build_pointer_type (basetype), TYPE_ARG_TYPES (type));
+    = tree_cons (NULL_TREE,
+                build_pointer_type (basetype), TYPE_ARG_TYPES (type));
 
   /* If we already have such a type, use the old one and free this one.  */
   hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
@@ -2830,10 +2960,9 @@ build_method_type (basetype, type)
   return t;
 }
 
-/* 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.
-   TYPE must be a FUNCTION_TYPE node.  */
+/* Construct, lay out and return the type of offsets to a value
+   of type TYPE, within an object of type BASETYPE.
+   If a suitable offset type exists already, reuse it.  */
 
 tree
 build_offset_type (basetype, type)
@@ -3033,7 +3162,14 @@ get_narrower (op, unsignedp_ptr)
            break;
          first = 0;
        }
-      /* A change in nominal type can always be stripped.  */
+      else /* bitschange == 0 */
+       {
+         /* A change in nominal type can always be stripped, but we must
+            preserve the unsignedness.  */
+         if (first)
+           uns = TREE_UNSIGNED (TREE_TYPE (op));
+         first = 0;
+       }
 
       win = op;
     }
@@ -3095,10 +3231,12 @@ int_fits_type_p (c, type)
 {
   if (TREE_UNSIGNED (type))
     return (!INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c)
-           && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type)));
+           && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))
+           && (TREE_INT_CST_HIGH (c) >= 0 || TREE_UNSIGNED (TREE_TYPE (c))));
   else
     return (!INT_CST_LT (TYPE_MAX_VALUE (type), c)
-           && !INT_CST_LT (c, TYPE_MIN_VALUE (type)));
+           && !INT_CST_LT (c, TYPE_MIN_VALUE (type))
+           && (TREE_INT_CST_HIGH (c) >= 0 || !TREE_UNSIGNED (TREE_TYPE (c))));
 }
 
 /* Return the innermost context enclosing DECL that is
@@ -3136,7 +3274,7 @@ decl_function_context (decl)
 }
 
 /* Return the innermost context enclosing DECL that is
-   a RECORD_TYPE or UNION_TYPE, or zero if none.
+   a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE, or zero if none.
    TYPE_DECLs and FUNCTION_DECLs are transparent to this function.  */
 
 tree
@@ -3148,7 +3286,8 @@ decl_type_context (decl)
   while (context)
     {
       if (TREE_CODE (context) == RECORD_TYPE
-         || TREE_CODE (context) == UNION_TYPE)
+         || TREE_CODE (context) == UNION_TYPE
+         || TREE_CODE (context) == QUAL_UNION_TYPE)
        return context;
       if (TREE_CODE (context) == TYPE_DECL
          || TREE_CODE (context) == FUNCTION_DECL)