OSDN Git Service

* tree.c (max_int_size_in_bytes): New function, inspired from
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 21e681c..cbf4cc5 100644 (file)
@@ -1,6 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -16,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 /* This file contains the low level primitives for operating on tree nodes,
    including allocation, list operations, interning of identifiers,
@@ -93,9 +94,11 @@ static const char * const tree_node_kind_names[] = {
   "binfos",
   "phi_nodes",
   "ssa names",
+  "constructors",
   "random kinds",
   "lang_decl kinds",
-  "lang_type kinds"
+  "lang_type kinds",
+  "omp clauses"
 };
 #endif /* GATHER_STATISTICS */
 
@@ -131,12 +134,37 @@ static GTY (()) tree int_cst_node;
 static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
      htab_t int_cst_hash_table;
 
+/* General tree->tree mapping  structure for use in hash tables.  */
+
+
+static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) 
+     htab_t debug_expr_for_decl;
+
+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)))
+  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 *);
 static hashval_t int_cst_hash_hash (const void *);
 static int int_cst_hash_eq (const void *, const void *);
 static void print_type_hash_statistics (void);
+static void print_debug_expr_statistics (void);
+static void print_value_expr_statistics (void);
 static tree make_vector_type (tree, int, enum machine_mode);
 static int type_hash_marked_p (const void *);
 static unsigned int type_hash_list (tree, hashval_t);
@@ -144,6 +172,45 @@ 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];
+
+/* Number of operands for each OpenMP clause.  */
+unsigned const char omp_clause_num_ops[] =
+{
+  0, /* OMP_CLAUSE_ERROR  */
+  1, /* OMP_CLAUSE_PRIVATE  */
+  1, /* OMP_CLAUSE_SHARED  */
+  1, /* OMP_CLAUSE_FIRSTPRIVATE  */
+  1, /* OMP_CLAUSE_LASTPRIVATE  */
+  4, /* OMP_CLAUSE_REDUCTION  */
+  1, /* OMP_CLAUSE_COPYIN  */
+  1, /* OMP_CLAUSE_COPYPRIVATE  */
+  1, /* OMP_CLAUSE_IF  */
+  1, /* OMP_CLAUSE_NUM_THREADS  */
+  1, /* OMP_CLAUSE_SCHEDULE  */
+  0, /* OMP_CLAUSE_NOWAIT  */
+  0, /* OMP_CLAUSE_ORDERED  */
+  0  /* OMP_CLAUSE_DEFAULT  */
+};
+
+const char * const omp_clause_code_name[] =
+{
+  "error_clause",
+  "private",
+  "shared",
+  "firstprivate",
+  "lastprivate",
+  "reduction",
+  "copyin",
+  "copyprivate",
+  "if",
+  "num_threads",
+  "schedule",
+  "nowait",
+  "ordered",
+  "default"
+};
 \f
 /* Init tree.c.  */
 
@@ -153,9 +220,79 @@ init_ttree (void)
   /* Initialize the hash table of types.  */
   type_hash_table = htab_create_ggc (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
                                     type_hash_eq, 0);
+
+  debug_expr_for_decl = htab_create_ggc (512, tree_map_hash,
+                                        tree_map_eq, 0);
+
+  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);
+  restrict_base_for_decl = htab_create_ggc (256, tree_map_hash,
+                                           tree_map_eq, 0);
+
   int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash,
                                        int_cst_hash_eq, NULL);
+  
   int_cst_node = make_node (INTEGER_CST);
+
+  tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON] = 1;
+  tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_NON_COMMON] = 1;
+  tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON] = 1;
+  
+
+  tree_contains_struct[CONST_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[VAR_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[PARM_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[RESULT_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[FUNCTION_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[TYPE_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[LABEL_DECL][TS_DECL_COMMON] = 1;
+  tree_contains_struct[FIELD_DECL][TS_DECL_COMMON] = 1;
+
+
+  tree_contains_struct[CONST_DECL][TS_DECL_WRTL] = 1;
+  tree_contains_struct[VAR_DECL][TS_DECL_WRTL] = 1;
+  tree_contains_struct[PARM_DECL][TS_DECL_WRTL] = 1;
+  tree_contains_struct[RESULT_DECL][TS_DECL_WRTL] = 1;
+  tree_contains_struct[FUNCTION_DECL][TS_DECL_WRTL] = 1;
+  tree_contains_struct[LABEL_DECL][TS_DECL_WRTL] = 1; 
+
+  tree_contains_struct[CONST_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[VAR_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[PARM_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[RESULT_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[FUNCTION_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[TYPE_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[LABEL_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[FIELD_DECL][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[STRUCT_FIELD_TAG][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[NAME_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
+  tree_contains_struct[SYMBOL_MEMORY_TAG][TS_DECL_MINIMAL] = 1;
+
+  tree_contains_struct[STRUCT_FIELD_TAG][TS_MEMORY_TAG] = 1;
+  tree_contains_struct[NAME_MEMORY_TAG][TS_MEMORY_TAG] = 1;
+  tree_contains_struct[SYMBOL_MEMORY_TAG][TS_MEMORY_TAG] = 1;
+
+  tree_contains_struct[STRUCT_FIELD_TAG][TS_STRUCT_FIELD_TAG] = 1;
+
+  tree_contains_struct[VAR_DECL][TS_DECL_WITH_VIS] = 1;
+  tree_contains_struct[FUNCTION_DECL][TS_DECL_WITH_VIS] = 1;
+  tree_contains_struct[TYPE_DECL][TS_DECL_WITH_VIS] = 1;
+  tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_WITH_VIS] = 1;
+  
+  tree_contains_struct[VAR_DECL][TS_VAR_DECL] = 1;
+  tree_contains_struct[FIELD_DECL][TS_FIELD_DECL] = 1;
+  tree_contains_struct[PARM_DECL][TS_PARM_DECL] = 1;
+  tree_contains_struct[LABEL_DECL][TS_LABEL_DECL] = 1;
+  tree_contains_struct[RESULT_DECL][TS_RESULT_DECL] = 1;
+  tree_contains_struct[CONST_DECL][TS_CONST_DECL] = 1;
+  tree_contains_struct[TYPE_DECL][TS_TYPE_DECL] = 1;
+  tree_contains_struct[FUNCTION_DECL][TS_FUNCTION_DECL] = 1;
+
+  lang_hooks.init_ts ();
 }
 
 \f
@@ -167,7 +304,7 @@ decl_assembler_name (tree decl)
 {
   if (!DECL_ASSEMBLER_NAME_SET_P (decl))
     lang_hooks.set_decl_assembler_name (decl);
-  return DECL_CHECK (decl)->decl.assembler_name;
+  return DECL_WITH_VIS_CHECK (decl)->decl_with_vis.assembler_name;
 }
 
 /* Compute the number of bytes occupied by a tree with code CODE.
@@ -179,7 +316,34 @@ tree_code_size (enum tree_code code)
   switch (TREE_CODE_CLASS (code))
     {
     case tcc_declaration:  /* A decl node */
-      return sizeof (struct tree_decl);
+      {
+       switch (code)
+         {
+         case FIELD_DECL:
+           return sizeof (struct tree_field_decl);
+         case PARM_DECL:
+           return sizeof (struct tree_parm_decl);
+         case VAR_DECL:
+           return sizeof (struct tree_var_decl);
+         case LABEL_DECL:
+           return sizeof (struct tree_label_decl);
+         case RESULT_DECL:
+           return sizeof (struct tree_result_decl);
+         case CONST_DECL:
+           return sizeof (struct tree_const_decl);
+         case TYPE_DECL:
+           return sizeof (struct tree_type_decl);
+         case FUNCTION_DECL:
+           return sizeof (struct tree_function_decl);
+         case NAME_MEMORY_TAG:
+         case SYMBOL_MEMORY_TAG:
+           return sizeof (struct tree_memory_tag);
+         case STRUCT_FIELD_TAG:
+           return sizeof (struct tree_struct_field_tag);
+         default:
+           return sizeof (struct tree_decl_non_common);
+         }
+      }
 
     case tcc_type:  /* a type node */
       return sizeof (struct tree_type);
@@ -215,6 +379,7 @@ tree_code_size (enum tree_code code)
        case PLACEHOLDER_EXPR:  return sizeof (struct tree_common);
 
        case TREE_VEC:
+       case OMP_CLAUSE:
        case PHI_NODE:          gcc_unreachable ();
 
        case SSA_NAME:          return sizeof (struct tree_ssa_name);
@@ -222,6 +387,7 @@ tree_code_size (enum tree_code code)
        case STATEMENT_LIST:    return sizeof (struct tree_statement_list);
        case BLOCK:             return sizeof (struct tree_block);
        case VALUE_HANDLE:      return sizeof (struct tree_value_handle);
+       case CONSTRUCTOR:       return sizeof (struct tree_constructor);
 
        default:
          return lang_hooks.tree_size (code);
@@ -255,6 +421,11 @@ tree_size (tree node)
     case STRING_CST:
       return sizeof (struct tree_string) + TREE_STRING_LENGTH (node) - 1;
 
+    case OMP_CLAUSE:
+      return (sizeof (struct tree_omp_clause)
+             + (omp_clause_num_ops[OMP_CLAUSE_CODE (node)] - 1)
+               * sizeof (tree));
+
     default:
       return tree_code_size (code);
     }
@@ -262,8 +433,9 @@ tree_size (tree node)
 
 /* Return a newly allocated node of code CODE.  For decl and type
    nodes, some other fields are initialized.  The rest of the node is
-   initialized to zero.  This function cannot be used for PHI_NODE or
-   TREE_VEC nodes, which is enforced by asserts in tree_code_size.
+   initialized to zero.  This function cannot be used for PHI_NODE,
+   TREE_VEC or OMP_CLAUSE nodes, which is enforced by asserts in
+   tree_code_size.
 
    Achoo!  I got a code in the node.  */
 
@@ -312,7 +484,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
          kind = id_kind;
          break;
 
-       case TREE_VEC:;
+       case TREE_VEC:
          kind = vec_kind;
          break;
 
@@ -332,6 +504,10 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
          kind = b_kind;
          break;
 
+       case CONSTRUCTOR:
+         kind = constr_kind;
+         break;
+
        default:
          kind = x_kind;
          break;
@@ -347,9 +523,9 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
 #endif
 
   if (code == IDENTIFIER_NODE)
-    t = ggc_alloc_zone_stat (length, &tree_id_zone PASS_MEM_STAT);
+    t = ggc_alloc_zone_pass_stat (length, &tree_id_zone);
   else
-    t = ggc_alloc_zone_stat (length, &tree_zone PASS_MEM_STAT);
+    t = ggc_alloc_zone_pass_stat (length, &tree_zone);
 
   memset (t, 0, length);
 
@@ -362,20 +538,24 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
       break;
 
     case tcc_declaration:
-      if (code != FUNCTION_DECL)
-       DECL_ALIGN (t) = 1;
-      DECL_USER_ALIGN (t) = 0;
-      DECL_IN_SYSTEM_HEADER (t) = in_system_header;
+      if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
+       DECL_IN_SYSTEM_HEADER (t) = in_system_header;
+      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
+       {
+         if (code != FUNCTION_DECL)
+           DECL_ALIGN (t) = 1;
+         DECL_USER_ALIGN (t) = 0;        
+         /* We have not yet computed the alias set for this declaration.  */
+         DECL_POINTER_ALIAS_SET (t) = -1;
+       }
       DECL_SOURCE_LOCATION (t) = input_location;
       DECL_UID (t) = next_decl_uid++;
 
-      /* We have not yet computed the alias set for this declaration.  */
-      DECL_POINTER_ALIAS_SET (t) = -1;
       break;
 
     case tcc_type:
       TYPE_UID (t) = next_type_uid++;
-      TYPE_ALIGN (t) = char_type_node ? TYPE_ALIGN (char_type_node) : 0;
+      TYPE_ALIGN (t) = BITS_PER_UNIT;
       TYPE_USER_ALIGN (t) = 0;
       TYPE_MAIN_VARIANT (t) = t;
 
@@ -433,7 +613,7 @@ copy_node_stat (tree node MEM_STAT_DECL)
   gcc_assert (code != STATEMENT_LIST);
 
   length = tree_size (node);
-  t = ggc_alloc_zone_stat (length, &tree_zone PASS_MEM_STAT);
+  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
   memcpy (t, node, length);
 
   TREE_CHAIN (t) = 0;
@@ -442,7 +622,25 @@ copy_node_stat (tree node MEM_STAT_DECL)
   t->common.ann = 0;
 
   if (TREE_CODE_CLASS (code) == tcc_declaration)
-    DECL_UID (t) = next_decl_uid++;
+    {
+      DECL_UID (t) = next_decl_uid++;
+      if ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL)
+         && DECL_HAS_VALUE_EXPR_P (node))
+       {
+         SET_DECL_VALUE_EXPR (t, DECL_VALUE_EXPR (node));
+         DECL_HAS_VALUE_EXPR_P (t) = 1;
+       }
+      if (TREE_CODE (node) == VAR_DECL && DECL_HAS_INIT_PRIORITY_P (node))
+       {
+         SET_DECL_INIT_PRIORITY (t, DECL_INIT_PRIORITY (node));
+         DECL_HAS_INIT_PRIORITY_P (t) = 1;
+       }
+      if (TREE_CODE (node) == VAR_DECL && DECL_BASED_ON_RESTRICT_P (node))
+       {
+         SET_DECL_RESTRICT_BASE (t, DECL_GET_RESTRICT_BASE (node));
+         DECL_BASED_ON_RESTRICT_P (t) = 1;
+       }
+    }
   else if (TREE_CODE_CLASS (code) == tcc_type)
     {
       TYPE_UID (t) = next_type_uid++;
@@ -518,7 +716,7 @@ 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;
+  unsigned HOST_WIDE_INT hi, mask;
   unsigned bits;
   bool signed_p;
   bool negative;
@@ -538,10 +736,12 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
       negative = ((val >> (bits - 1)) & 1) != 0;
 
       /* Mask out the bits outside of the precision of the constant.  */
+      mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
+
       if (signed_p && negative)
-       val = val | ((~(unsigned HOST_WIDE_INT) 0) << bits);
+       val |= ~mask;
       else
-       val = val & ~((~(unsigned HOST_WIDE_INT) 0) << bits);
+       val &= mask;
     }
 
   /* Determine the high bits.  */
@@ -556,7 +756,8 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
       else
        {
          bits -= HOST_BITS_PER_WIDE_INT;
-         hi = hi & ~((~(unsigned HOST_WIDE_INT) 0) << bits);
+         mask = (((unsigned HOST_WIDE_INT) 2) << (bits - 1)) - 1;
+         hi &= mask;
        }
     }
 
@@ -626,7 +827,6 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
       break;
 
     case INTEGER_TYPE:
-    case CHAR_TYPE:
     case OFFSET_TYPE:
       if (TYPE_UNSIGNED (type))
        {
@@ -753,7 +953,7 @@ cst_and_fits_in_hwi (tree x)
 }
 
 /* Return a new VECTOR_CST node whose type is TYPE and whose values
-   are in a list pointed by VALS.  */
+   are in a list pointed to by VALS.  */
 
 tree
 build_vector (tree type, tree vals)
@@ -780,27 +980,81 @@ build_vector (tree type, tree vals)
   return v;
 }
 
+/* Return a new VECTOR_CST node whose type is TYPE and whose values
+   are extracted from V, a vector of CONSTRUCTOR_ELT.  */
+
+tree
+build_vector_from_ctor (tree type, VEC(constructor_elt,gc) *v)
+{
+  tree list = NULL_TREE;
+  unsigned HOST_WIDE_INT idx;
+  tree value;
+
+  FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
+    list = tree_cons (NULL_TREE, value, list);
+  return build_vector (type, nreverse (list));
+}
+
 /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
-   are in a list pointed to by VALS.  */
+   are in the VEC pointed to by VALS.  */
 tree
-build_constructor (tree type, tree vals)
+build_constructor (tree type, VEC(constructor_elt,gc) *vals)
 {
   tree c = make_node (CONSTRUCTOR);
   TREE_TYPE (c) = type;
   CONSTRUCTOR_ELTS (c) = vals;
+  return c;
+}
+
+/* Build a CONSTRUCTOR node made of a single initializer, with the specified
+   INDEX and VALUE.  */
+tree
+build_constructor_single (tree type, tree index, tree value)
+{
+  VEC(constructor_elt,gc) *v;
+  constructor_elt *elt;
+  tree t;
+
+  v = VEC_alloc (constructor_elt, gc, 1);
+  elt = VEC_quick_push (constructor_elt, v, NULL);
+  elt->index = index;
+  elt->value = value;
+
+  t = build_constructor (type, v);
+  TREE_CONSTANT (t) = TREE_CONSTANT (value);
+  return t;
+}
+
+
+/* Return a new CONSTRUCTOR node whose type is TYPE and whose values
+   are in a list pointed to by VALS.  */
+tree
+build_constructor_from_list (tree type, tree vals)
+{
+  tree t, val;
+  VEC(constructor_elt,gc) *v = NULL;
+  bool constant_p = true;
 
-  /* ??? May not be necessary.  Mirrors what build does.  */
   if (vals)
     {
-      TREE_SIDE_EFFECTS (c) = TREE_SIDE_EFFECTS (vals);
-      TREE_READONLY (c) = TREE_READONLY (vals);
-      TREE_CONSTANT (c) = TREE_CONSTANT (vals);
-      TREE_INVARIANT (c) = TREE_INVARIANT (vals);
+      v = VEC_alloc (constructor_elt, gc, list_length (vals));
+      for (t = vals; t; t = TREE_CHAIN (t))
+       {
+         constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
+         val = TREE_VALUE (t);
+         elt->index = TREE_PURPOSE (t);
+         elt->value = val;
+         if (!TREE_CONSTANT (val))
+           constant_p = false;
+       }
     }
 
-  return c;
+  t = build_constructor (type, v);
+  TREE_CONSTANT (t) = constant_p;
+  return t;
 }
 
+
 /* Return a new REAL_CST node whose type is TYPE and value is D.  */
 
 tree
@@ -878,6 +1132,8 @@ build_string (int len, const char *str)
 
   memset (s, 0, sizeof (struct tree_common));
   TREE_SET_CODE (s, STRING_CST);
+  TREE_CONSTANT (s) = 1;
+  TREE_INVARIANT (s) = 1;
   TREE_STRING_LENGTH (s) = len;
   memcpy ((char *) TREE_STRING_POINTER (s), str, len);
   ((char *) TREE_STRING_POINTER (s))[len] = '\0';
@@ -918,7 +1174,7 @@ make_tree_binfo_stat (unsigned base_binfos MEM_STAT_DECL)
   tree_node_sizes[(int) binfo_kind] += length;
 #endif
 
-  t = ggc_alloc_zone_stat (length, &tree_zone PASS_MEM_STAT);
+  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
 
   memset (t, 0, offsetof (struct tree_binfo, base_binfos));
 
@@ -943,7 +1199,7 @@ make_tree_vec_stat (int len MEM_STAT_DECL)
   tree_node_sizes[(int) vec_kind] += length;
 #endif
 
-  t = ggc_alloc_zone_stat (length, &tree_zone PASS_MEM_STAT);
+  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
 
   memset (t, 0, length);
 
@@ -962,7 +1218,6 @@ integer_zerop (tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == INTEGER_CST
-          && ! TREE_CONSTANT_OVERFLOW (expr)
           && TREE_INT_CST_LOW (expr) == 0
           && TREE_INT_CST_HIGH (expr) == 0)
          || (TREE_CODE (expr) == COMPLEX_CST
@@ -979,7 +1234,6 @@ integer_onep (tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == INTEGER_CST
-          && ! TREE_CONSTANT_OVERFLOW (expr)
           && TREE_INT_CST_LOW (expr) == 1
           && TREE_INT_CST_HIGH (expr) == 0)
          || (TREE_CODE (expr) == COMPLEX_CST
@@ -1003,14 +1257,15 @@ integer_all_onesp (tree expr)
       && integer_zerop (TREE_IMAGPART (expr)))
     return 1;
 
-  else if (TREE_CODE (expr) != INTEGER_CST
-          || TREE_CONSTANT_OVERFLOW (expr))
+  else if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
 
   uns = TYPE_UNSIGNED (TREE_TYPE (expr));
+  if (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
+      && TREE_INT_CST_HIGH (expr) == -1)
+    return 1;
   if (!uns)
-    return (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
-           && TREE_INT_CST_HIGH (expr) == -1);
+    return 0;
 
   /* Note that using TYPE_PRECISION here is wrong.  We care about the
      actual bits, not the (arbitrary) range of the type.  */
@@ -1054,7 +1309,7 @@ integer_pow2p (tree expr)
       && integer_zerop (TREE_IMAGPART (expr)))
     return 1;
 
-  if (TREE_CODE (expr) != INTEGER_CST || TREE_CONSTANT_OVERFLOW (expr))
+  if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
 
   prec = (POINTER_TYPE_P (TREE_TYPE (expr))
@@ -1092,7 +1347,6 @@ integer_nonzerop (tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == INTEGER_CST
-          && ! TREE_CONSTANT_OVERFLOW (expr)
           && (TREE_INT_CST_LOW (expr) != 0
               || TREE_INT_CST_HIGH (expr) != 0))
          || (TREE_CODE (expr) == COMPLEX_CST
@@ -1185,7 +1439,6 @@ real_zerop (tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == REAL_CST
-          && ! TREE_CONSTANT_OVERFLOW (expr)
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0))
          || (TREE_CODE (expr) == COMPLEX_CST
              && real_zerop (TREE_REALPART (expr))
@@ -1200,7 +1453,6 @@ real_onep (tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == REAL_CST
-          && ! TREE_CONSTANT_OVERFLOW (expr)
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1))
          || (TREE_CODE (expr) == COMPLEX_CST
              && real_onep (TREE_REALPART (expr))
@@ -1215,7 +1467,6 @@ real_twop (tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == REAL_CST
-          && ! TREE_CONSTANT_OVERFLOW (expr)
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2))
          || (TREE_CODE (expr) == COMPLEX_CST
              && real_twop (TREE_REALPART (expr))
@@ -1230,7 +1481,6 @@ real_minus_onep (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))
@@ -1415,8 +1665,7 @@ tree_cons_stat (tree purpose, tree value, tree chain MEM_STAT_DECL)
 {
   tree node;
 
-  node = ggc_alloc_zone_stat (sizeof (struct tree_list),
-                             &tree_zone PASS_MEM_STAT);
+  node = ggc_alloc_zone_pass_stat (sizeof (struct tree_list), &tree_zone);
 
   memset (node, 0, sizeof (struct tree_common));
 
@@ -1477,7 +1726,6 @@ int_size_in_bytes (tree type)
   t = TYPE_SIZE_UNIT (type);
   if (t == 0
       || TREE_CODE (t) != INTEGER_CST
-      || TREE_OVERFLOW (t)
       || TREE_INT_CST_HIGH (t) != 0
       /* If the result would appear negative, it's too big to represent.  */
       || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
@@ -1485,6 +1733,39 @@ int_size_in_bytes (tree type)
 
   return TREE_INT_CST_LOW (t);
 }
+
+/* Return the maximum size of TYPE (in bytes) as a wide integer
+   or return -1 if the size can vary or is larger than an integer.  */
+
+HOST_WIDE_INT
+max_int_size_in_bytes (tree type)
+{
+  HOST_WIDE_INT size = -1;
+  tree size_tree;
+
+  /* If this is an array type, check for a possible MAX_SIZE attached.  */
+
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      size_tree = TYPE_ARRAY_MAX_SIZE (type);
+
+      if (size_tree && host_integerp (size_tree, 1))
+       size = tree_low_cst (size_tree, 1);
+    }
+
+  /* If we still haven't been able to get a size, see if the language
+     can compute a maximum size.  */
+
+  if (size == -1)
+    {
+      size_tree = lang_hooks.types.max_size (type);
+
+      if (size_tree && host_integerp (size_tree, 1))
+       size = tree_low_cst (size_tree, 1);
+    }
+
+  return size;
+}
 \f
 /* Return the bit position of FIELD, in bits from the start of the record.
    This is a tree of type bitsizetype.  */
@@ -1591,7 +1872,7 @@ array_type_nelts (tree type)
 
   return (integer_zerop (min)
          ? max
-         : fold (build2 (MINUS_EXPR, TREE_TYPE (max), max, min)));
+         : fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, min));
 }
 \f
 /* If arg is static -- a reference to an object in static storage -- then
@@ -1611,8 +1892,8 @@ staticp (tree arg)
 
     case VAR_DECL:
       return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
-             && ! DECL_THREAD_LOCAL (arg)
-             && ! DECL_NON_ADDR_CONST_P (arg)
+             && ! DECL_THREAD_LOCAL_P (arg)
+             && ! DECL_DLLIMPORT_P (arg)
              ? arg : NULL);
 
     case CONST_DECL:
@@ -1773,9 +2054,35 @@ tree_node_structure (tree t)
   enum tree_code code = TREE_CODE (t);
 
   switch (TREE_CODE_CLASS (code))
-    {
+    {      
     case tcc_declaration:
-      return TS_DECL;
+      {
+       switch (code)
+         {
+         case FIELD_DECL:
+           return TS_FIELD_DECL;
+         case PARM_DECL:
+           return TS_PARM_DECL;
+         case VAR_DECL:
+           return TS_VAR_DECL;
+         case LABEL_DECL:
+           return TS_LABEL_DECL;
+         case RESULT_DECL:
+           return TS_RESULT_DECL;
+         case CONST_DECL:
+           return TS_CONST_DECL;
+         case TYPE_DECL:
+           return TS_TYPE_DECL;
+         case FUNCTION_DECL:
+           return TS_FUNCTION_DECL;
+         case SYMBOL_MEMORY_TAG:
+         case NAME_MEMORY_TAG:
+         case STRUCT_FIELD_TAG:
+           return TS_MEMORY_TAG;
+         default:
+           return TS_DECL_NON_COMMON;
+         }
+      }
     case tcc_type:
       return TS_TYPE;
     case tcc_reference:
@@ -1806,8 +2113,10 @@ tree_node_structure (tree t)
     case PLACEHOLDER_EXPR:     return TS_COMMON;
     case STATEMENT_LIST:       return TS_STATEMENT_LIST;
     case BLOCK:                        return TS_BLOCK;
+    case CONSTRUCTOR:          return TS_CONSTRUCTOR;
     case TREE_BINFO:           return TS_BINFO;
     case VALUE_HANDLE:         return TS_VALUE_HANDLE;
+    case OMP_CLAUSE:           return TS_OMP_CLAUSE;
 
     default:
       gcc_unreachable ();
@@ -1859,6 +2168,9 @@ 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;
        }
@@ -1903,7 +2215,6 @@ type_contains_placeholder_1 (tree type)
     case COMPLEX_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
-    case CHAR_TYPE:
     case POINTER_TYPE:
     case OFFSET_TYPE:
     case REFERENCE_TYPE:
@@ -1978,7 +2289,7 @@ tree
 substitute_in_expr (tree exp, tree f, tree r)
 {
   enum tree_code code = TREE_CODE (exp);
-  tree op0, op1, op2;
+  tree op0, op1, op2, op3;
   tree new;
   tree inner;
 
@@ -2012,8 +2323,8 @@ substitute_in_expr (tree exp, tree f, tree r)
      if (op0 == TREE_OPERAND (exp, 0))
        return exp;
 
-     new = fold (build3 (COMPONENT_REF, TREE_TYPE (exp),
-                        op0, TREE_OPERAND (exp, 1), NULL_TREE));
+     new = fold_build3 (COMPONENT_REF, TREE_TYPE (exp),
+                       op0, TREE_OPERAND (exp, 1), NULL_TREE);
    }
   else
     switch (TREE_CODE_CLASS (code))
@@ -2038,7 +2349,7 @@ substitute_in_expr (tree exp, tree f, tree r)
            if (op0 == TREE_OPERAND (exp, 0))
              return exp;
 
-           new = fold (build1 (code, TREE_TYPE (exp), op0));
+           new = fold_build1 (code, TREE_TYPE (exp), op0);
            break;
 
          case 2:
@@ -2048,7 +2359,7 @@ substitute_in_expr (tree exp, tree f, tree r)
            if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
              return exp;
 
-           new = fold (build2 (code, TREE_TYPE (exp), op0, op1));
+           new = fold_build2 (code, TREE_TYPE (exp), op0, op1);
            break;
 
          case 3:
@@ -2060,7 +2371,21 @@ substitute_in_expr (tree exp, tree f, tree r)
                && op2 == TREE_OPERAND (exp, 2))
              return exp;
 
-           new = fold (build3 (code, TREE_TYPE (exp), op0, op1, op2));
+           new = fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
+           break;
+
+         case 4:
+           op0 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 0), f, r);
+           op1 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 1), f, r);
+           op2 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 2), f, r);
+           op3 = SUBSTITUTE_IN_EXPR (TREE_OPERAND (exp, 3), f, r);
+
+           if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
+               && op2 == TREE_OPERAND (exp, 2)
+               && op3 == TREE_OPERAND (exp, 3))
+             return exp;
+
+           new = fold (build4 (code, TREE_TYPE (exp), op0, op1, op2, op3));
            break;
 
          default:
@@ -2116,7 +2441,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
        if (POINTER_TYPE_P (TREE_TYPE (elt))
            && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (elt)))
                == need_type))
-         return fold (build1 (INDIRECT_REF, need_type, elt));
+         return fold_build1 (INDIRECT_REF, need_type, elt);
 
       /* If we didn't find it, return the original PLACEHOLDER_EXPR.  If it
         survives until RTL generation, there will be an error.  */
@@ -2158,7 +2483,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
            if (op0 == TREE_OPERAND (exp, 0))
              return exp;
            else
-             return fold (build1 (code, TREE_TYPE (exp), op0));
+             return fold_build1 (code, TREE_TYPE (exp), op0);
 
          case 2:
            op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
@@ -2167,7 +2492,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
            if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
              return exp;
            else
-             return fold (build2 (code, TREE_TYPE (exp), op0, op1));
+             return fold_build2 (code, TREE_TYPE (exp), op0, op1);
 
          case 3:
            op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
@@ -2178,7 +2503,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
                && op2 == TREE_OPERAND (exp, 2))
              return exp;
            else
-             return fold (build3 (code, TREE_TYPE (exp), op0, op1, op2));
+             return fold_build3 (code, TREE_TYPE (exp), op0, op1, op2);
 
          case 4:
            op0 = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TREE_OPERAND (exp, 0), obj);
@@ -2377,7 +2702,7 @@ stabilize_reference_1 (tree e)
    TREE_INVARIANT, and TREE_SIDE_EFFECTS for an ADDR_EXPR.  */
 
 void
-recompute_tree_invarant_for_addr_expr (tree t)
+recompute_tree_invariant_for_addr_expr (tree t)
 {
   tree node;
   bool tc = true, ti = true, se = false;
@@ -2425,6 +2750,8 @@ do { tree _node = (NODE); \
        UPDATE_TITCSE (TREE_OPERAND (node, 2));
     }
 
+  node = lang_hooks.expr_to_decl (node, &tc, &ti, &se);
+
   /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
      the address, since &(*a)->b is a form of addition.  If it's a decl, it's
      invariant and constant if the decl is static.  It's also invariant if it's
@@ -2439,7 +2766,8 @@ do { tree _node = (NODE); \
        ;
       else if (decl_function_context (node) == current_function_decl
               /* Addresses of thread-local variables are invariant.  */
-              || (TREE_CODE (node) == VAR_DECL && DECL_THREAD_LOCAL (node)))
+              || (TREE_CODE (node) == VAR_DECL
+                  && DECL_THREAD_LOCAL_P (node)))
        tc = false;
       else
        ti = tc = false;
@@ -2463,9 +2791,7 @@ do { tree _node = (NODE); \
    Constants, decls, types and misc nodes cannot be.
 
    We define 5 non-variadic functions, from 0 to 4 arguments.  This is
-   enough for all extant tree codes.  These functions can be called
-   directly (preferably!), but can also be obtained via GCC preprocessor
-   magic within the build macro.  */
+   enough for all extant tree codes.  */
 
 tree
 build0_stat (enum tree_code code, tree tt MEM_STAT_DECL)
@@ -2509,7 +2835,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
 
   gcc_assert (TREE_CODE_LENGTH (code) == 1);
 
-  t = ggc_alloc_zone_stat (length, &tree_zone PASS_MEM_STAT);
+  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
 
   memset (t, 0, sizeof (struct tree_common));
 
@@ -2534,13 +2860,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
     TREE_SIDE_EFFECTS (t) = 1;
   else switch (code)
     {
-    case INIT_EXPR:
-    case MODIFY_EXPR:
     case VA_ARG_EXPR:
-    case PREDECREMENT_EXPR:
-    case PREINCREMENT_EXPR:
-    case POSTDECREMENT_EXPR:
-    case POSTINCREMENT_EXPR:
       /* All of these have side-effects, no matter what their
         operands are.  */
       TREE_SIDE_EFFECTS (t) = 1;
@@ -2557,7 +2877,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
 
     case ADDR_EXPR:
       if (node)
-       recompute_tree_invarant_for_addr_expr (t);
+       recompute_tree_invariant_for_addr_expr (t);
       break;
 
     default:
@@ -2704,47 +3024,59 @@ build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   return t;
 }
 
-/* Backup definition for non-gcc build compilers.  */
+tree
+build5_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
+            tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
+{
+  bool constant, read_only, side_effects, invariant;
+  tree t;
+
+  gcc_assert (TREE_CODE_LENGTH (code) == 5);
+
+  t = make_node_stat (code PASS_MEM_STAT);
+  TREE_TYPE (t) = tt;
+
+  side_effects = TREE_SIDE_EFFECTS (t);
+
+  PROCESS_ARG(0);
+  PROCESS_ARG(1);
+  PROCESS_ARG(2);
+  PROCESS_ARG(3);
+  PROCESS_ARG(4);
+
+  TREE_SIDE_EFFECTS (t) = side_effects;
+  TREE_THIS_VOLATILE (t)
+    = (TREE_CODE_CLASS (code) == tcc_reference
+       && arg0 && TREE_THIS_VOLATILE (arg0));
+
+  return t;
+}
 
 tree
-(build) (enum tree_code code, tree tt, ...)
+build7_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
+            tree arg2, tree arg3, tree arg4, tree arg5,
+            tree arg6 MEM_STAT_DECL)
 {
-  tree t, arg0, arg1, arg2, arg3;
-  int length = TREE_CODE_LENGTH (code);
-  va_list p;
+  bool constant, read_only, side_effects, invariant;
+  tree t;
 
-  va_start (p, tt);
-  switch (length)
-    {
-    case 0:
-      t = build0 (code, tt);
-      break;
-    case 1:
-      arg0 = va_arg (p, tree);
-      t = build1 (code, tt, arg0);
-      break;
-    case 2:
-      arg0 = va_arg (p, tree);
-      arg1 = va_arg (p, tree);
-      t = build2 (code, tt, arg0, arg1);
-      break;
-    case 3:
-      arg0 = va_arg (p, tree);
-      arg1 = va_arg (p, tree);
-      arg2 = va_arg (p, tree);
-      t = build3 (code, tt, arg0, arg1, arg2);
-      break;
-    case 4:
-      arg0 = va_arg (p, tree);
-      arg1 = va_arg (p, tree);
-      arg2 = va_arg (p, tree);
-      arg3 = va_arg (p, tree);
-      t = build4 (code, tt, arg0, arg1, arg2, arg3);
-      break;
-    default:
-      gcc_unreachable ();
-    }
-  va_end (p);
+  gcc_assert (code == TARGET_MEM_REF);
+
+  t = make_node_stat (code PASS_MEM_STAT);
+  TREE_TYPE (t) = tt;
+
+  side_effects = TREE_SIDE_EFFECTS (t);
+
+  PROCESS_ARG(0);
+  PROCESS_ARG(1);
+  PROCESS_ARG(2);
+  PROCESS_ARG(3);
+  PROCESS_ARG(4);
+  PROCESS_ARG(5);
+  PROCESS_ARG(6);
+
+  TREE_SIDE_EFFECTS (t) = side_effects;
+  TREE_THIS_VOLATILE (t) = 0;
 
   return t;
 }
@@ -2800,10 +3132,13 @@ build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL)
   else if (code == FUNCTION_DECL)
     DECL_MODE (t) = FUNCTION_MODE;
 
-  /* Set default visibility to whatever the user supplied with
-     visibility_specified depending on #pragma GCC visibility.  */
-  DECL_VISIBILITY (t) = default_visibility;
-  DECL_VISIBILITY_SPECIFIED (t) = visibility_options.inpragma;
+  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
+    {
+      /* Set default visibility to whatever the user supplied with
+        visibility_specified depending on #pragma GCC visibility.  */
+      DECL_VISIBILITY (t) = default_visibility;
+      DECL_VISIBILITY_SPECIFIED (t) = visibility_options.inpragma;
+    }
 
   return t;
 }
@@ -2843,7 +3178,7 @@ build_block (tree vars, tree subblocks, tree supercontext, tree chain)
 
 #if 1 /* ! defined(USE_MAPPED_LOCATION) */
 /* ??? gengtype doesn't handle conditionals */
-static GTY(()) tree last_annotated_node;
+static GTY(()) source_locus last_annotated_node;
 #endif
 
 #ifdef USE_MAPPED_LOCATION
@@ -2875,11 +3210,11 @@ annotate_with_file_line (tree node, const char *file, int line)
      a node with the same information already attached to that node!
      Just return instead of wasting memory.  */
   if (EXPR_LOCUS (node)
+      && EXPR_LINENO (node) == line
       && (EXPR_FILENAME (node) == file
-         || ! strcmp (EXPR_FILENAME (node), file))
-      && EXPR_LINENO (node) == line)
+         || !strcmp (EXPR_FILENAME (node), file)))
     {
-      last_annotated_node = node;
+      last_annotated_node = EXPR_LOCUS (node);
       return;
     }
 
@@ -2887,19 +3222,18 @@ annotate_with_file_line (tree node, const char *file, int line)
      entry cache can reduce the number of allocations by more
      than half.  */
   if (last_annotated_node
-      && EXPR_LOCUS (last_annotated_node)
-      && (EXPR_FILENAME (last_annotated_node) == file
-         || ! strcmp (EXPR_FILENAME (last_annotated_node), file))
-      && EXPR_LINENO (last_annotated_node) == line)
+      && last_annotated_node->line == line
+      && (last_annotated_node->file == file
+         || !strcmp (last_annotated_node->file, file)))
     {
-      SET_EXPR_LOCUS (node, EXPR_LOCUS (last_annotated_node));
+      SET_EXPR_LOCUS (node, last_annotated_node);
       return;
     }
 
   SET_EXPR_LOCUS (node, ggc_alloc (sizeof (location_t)));
   EXPR_LINENO (node) = line;
   EXPR_FILENAME (node) = file;
-  last_annotated_node = node;
+  last_annotated_node = EXPR_LOCUS (node);
 }
 
 void
@@ -3215,31 +3549,66 @@ tree
 merge_dllimport_decl_attributes (tree old, tree new)
 {
   tree a;
-  int delete_dllimport_p;
-
-  old = DECL_ATTRIBUTES (old);
-  new = DECL_ATTRIBUTES (new);
+  int delete_dllimport_p = 1;
 
   /* What we need to do here is remove from `old' dllimport if it doesn't
      appear in `new'.  dllimport behaves like extern: if a declaration is
      marked dllimport and a definition appears later, then the object
-     is not dllimport'd.  */
-  if (lookup_attribute ("dllimport", old) != NULL_TREE
-      && lookup_attribute ("dllimport", new) == NULL_TREE)
-    delete_dllimport_p = 1;
+     is not dllimport'd.  We also remove a `new' dllimport if the old list
+     contains dllexport:  dllexport always overrides dllimport, regardless
+     of the order of declaration.  */     
+  if (!VAR_OR_FUNCTION_DECL_P (new))
+    delete_dllimport_p = 0;
+  else if (DECL_DLLIMPORT_P (new)
+          && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old)))
+    { 
+      DECL_DLLIMPORT_P (new) = 0;
+      warning (OPT_Wattributes, "%q+D already declared with dllexport attribute: "
+             "dllimport ignored", new);
+    }
+  else if (DECL_DLLIMPORT_P (old) && !DECL_DLLIMPORT_P (new))
+    {
+      /* Warn about overriding a symbol that has already been used. eg:
+           extern int __attribute__ ((dllimport)) foo;
+          int* bar () {return &foo;}
+          int foo;
+      */
+      if (TREE_USED (old))
+       {
+         warning (0, "%q+D redeclared without dllimport attribute "
+                  "after being referenced with dll linkage", new);
+         /* If we have used a variable's address with dllimport linkage,
+             keep the old DECL_DLLIMPORT_P flag: the ADDR_EXPR using the
+             decl may already have had TREE_INVARIANT and TREE_CONSTANT
+             computed.
+             We still remove the attribute so that assembler code refers
+             to '&foo rather than '_imp__foo'.  */
+         if (TREE_CODE (old) == VAR_DECL && TREE_ADDRESSABLE (old))
+           DECL_DLLIMPORT_P (new) = 1;
+       }
+
+      /* Let an inline definition silently override the external reference,
+        but otherwise warn about attribute inconsistency.  */ 
+      else if (TREE_CODE (new) == VAR_DECL
+              || !DECL_DECLARED_INLINE_P (new))
+       warning (OPT_Wattributes, "%q+D redeclared without dllimport attribute: "
+                 "previous dllimport ignored", new);
+    }
   else
     delete_dllimport_p = 0;
 
-  a = merge_attributes (old, new);
+  a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new));
 
-  if (delete_dllimport_p)
+  if (delete_dllimport_p) 
     {
       tree prev, t;
-
+      const size_t attr_len = strlen ("dllimport"); 
+     
       /* Scan the list for dllimport and delete it.  */
       for (prev = NULL_TREE, t = a; t; prev = t, t = TREE_CHAIN (t))
        {
-         if (is_attribute_p ("dllimport", TREE_PURPOSE (t)))
+         if (is_attribute_with_length_p ("dllimport", attr_len,
+                                         TREE_PURPOSE (t)))
            {
              if (prev == NULL_TREE)
                a = TREE_CHAIN (a);
@@ -3274,7 +3643,8 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
        }
       if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
        {
-         warning (0, "%qs attribute ignored", IDENTIFIER_POINTER (name));
+         warning (OPT_Wattributes, "%qs attribute ignored",
+                  IDENTIFIER_POINTER (name));
          *no_add_attrs = true;
        }
 
@@ -3285,23 +3655,31 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
      any damage.  */
   if (is_attribute_p ("dllimport", name))
     {
+      /* Honor any target-specific overrides. */ 
+      if (!targetm.valid_dllimport_attribute_p (node))
+       *no_add_attrs = true;
+
+     else if (TREE_CODE (node) == FUNCTION_DECL
+               && DECL_DECLARED_INLINE_P (node))
+       {
+         warning (OPT_Wattributes, "inline function %q+D declared as "
+                 " dllimport: attribute ignored", node); 
+         *no_add_attrs = true;
+       }
       /* Like MS, treat definition of dllimported variables and
-        non-inlined functions on declaration as syntax errors.  We
-        allow the attribute for function definitions if declared
-        inline.  */
-      if (TREE_CODE (node) == FUNCTION_DECL  && DECL_INITIAL (node)
-          && !DECL_DECLARED_INLINE_P (node))
+        non-inlined functions on declaration as syntax errors. */
+     else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node))
        {
-         error ("%Jfunction %qD definition is marked dllimport.", node, node);
+         error ("function %q+D definition is marked dllimport", node);
          *no_add_attrs = true;
        }
 
-      else if (TREE_CODE (node) == VAR_DECL)
+     else if (TREE_CODE (node) == VAR_DECL)
        {
          if (DECL_INITIAL (node))
            {
-             error ("%Jvariable %qD definition is marked dllimport.",
-                    node, node);
+             error ("variable %q+D definition is marked dllimport",
+                    node);
              *no_add_attrs = true;
            }
 
@@ -3313,6 +3691,9 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
          if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
            TREE_PUBLIC (node) = 1;
        }
+
+      if (*no_add_attrs == false)
+        DECL_DLLIMPORT_P (node) = 1;
     }
 
   /*  Report error if symbol is not accessible at global scope.  */
@@ -3320,8 +3701,8 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
       && (TREE_CODE (node) == VAR_DECL
          || TREE_CODE (node) == FUNCTION_DECL))
     {
-      error ("%Jexternal linkage required for symbol %qD because of "
-            "%qs attribute.", node, node, IDENTIFIER_POINTER (name));
+      error ("external linkage required for symbol %q+D because of "
+            "%qs attribute", node, IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
     }
 
@@ -3433,83 +3814,296 @@ build_variant_type_copy (tree type)
   return t;
 }
 \f
-/* Hashing of types so that we don't make duplicates.
-   The entry point is `type_hash_canon'.  */
+/* Return true if the from tree in both tree maps are equal.  */
 
-/* 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
-   of the individual types.  */
+int
+tree_map_eq (const void *va, const void *vb)
+{
+  const struct tree_map  *a = va, *b = vb;
+  return (a->from == b->from);
+}
+
+/* Hash a from tree in a tree_map.  */
 
 unsigned int
-type_hash_list (tree list, hashval_t hashcode)
+tree_map_hash (const void *item)
 {
-  tree tail;
+  return (((const struct tree_map *) item)->hash);
+}
 
-  for (tail = list; tail; tail = TREE_CHAIN (tail))
-    if (TREE_VALUE (tail) != error_mark_node)
-      hashcode = iterative_hash_object (TYPE_HASH (TREE_VALUE (tail)),
-                                       hashcode);
+/* Return true if this tree map structure is marked for garbage collection
+   purposes.  We simply return true if the from tree is marked, so that this
+   structure goes away when the from tree goes away.  */
 
-  return hashcode;
-}
+int
+tree_map_marked_p (const void *p)
+{
+  tree from = ((struct tree_map *) p)->from;
 
-/* These are the Hashtable callback functions.  */
+  return ggc_marked_p (from);
+}
 
-/* Returns true iff the types are equivalent.  */
+/* Return true if the trees in the tree_int_map *'s VA and VB are equal.  */
 
 static int
-type_hash_eq (const void *va, const void *vb)
+tree_int_map_eq (const void *va, const void *vb)
 {
-  const struct type_hash *a = va, *b = vb;
-
-  /* First test the things that are the same for all types.  */
-  if (a->hash != b->hash
-      || TREE_CODE (a->type) != TREE_CODE (b->type)
-      || TREE_TYPE (a->type) != TREE_TYPE (b->type)
-      || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
-                                TYPE_ATTRIBUTES (b->type))
-      || TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
-      || TYPE_MODE (a->type) != TYPE_MODE (b->type))
-    return 0;
+  const struct tree_int_map  *a = va, *b = vb;
+  return (a->from == b->from);
+}
 
-  switch (TREE_CODE (a->type))
-    {
-    case VOID_TYPE:
-    case COMPLEX_TYPE:
-    case POINTER_TYPE:
-    case REFERENCE_TYPE:
-      return 1;
+/* Hash a from tree in the tree_int_map * ITEM.  */
 
-    case VECTOR_TYPE:
-      return TYPE_VECTOR_SUBPARTS (a->type) == TYPE_VECTOR_SUBPARTS (b->type);
+static unsigned int
+tree_int_map_hash (const void *item)
+{
+  return htab_hash_pointer (((const struct tree_int_map *)item)->from);
+}
 
-    case ENUMERAL_TYPE:
-      if (TYPE_VALUES (a->type) != TYPE_VALUES (b->type)
-         && !(TYPE_VALUES (a->type)
-              && TREE_CODE (TYPE_VALUES (a->type)) == TREE_LIST
-              && TYPE_VALUES (b->type)
-              && TREE_CODE (TYPE_VALUES (b->type)) == TREE_LIST
-              && type_list_equal (TYPE_VALUES (a->type),
-                                  TYPE_VALUES (b->type))))
-       return 0;
+/* 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.  */
 
-      /* ... fall through ... */
+static int
+tree_int_map_marked_p (const void *p)
+{
+  tree from = ((struct tree_int_map *) p)->from;
 
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-    case BOOLEAN_TYPE:
-    case CHAR_TYPE:
-      return ((TYPE_MAX_VALUE (a->type) == TYPE_MAX_VALUE (b->type)
-              || tree_int_cst_equal (TYPE_MAX_VALUE (a->type),
-                                     TYPE_MAX_VALUE (b->type)))
-             && (TYPE_MIN_VALUE (a->type) == TYPE_MIN_VALUE (b->type)
-                 || tree_int_cst_equal (TYPE_MIN_VALUE (a->type),
-                                        TYPE_MIN_VALUE (b->type))));
+  return ggc_marked_p (from);
+}
+/* Lookup an init priority for FROM, and return it if we find one.  */
 
-    case OFFSET_TYPE:
-      return TYPE_OFFSET_BASETYPE (a->type) == TYPE_OFFSET_BASETYPE (b->type);
+unsigned short
+decl_init_priority_lookup (tree from)
+{
+  struct tree_int_map *h, in;
+  in.from = from;
 
-    case METHOD_TYPE:
+  h = htab_find_with_hash (init_priority_for_decl, 
+                          &in, htab_hash_pointer (from));
+  if (h)
+    return h->to;
+  return 0;
+}
+
+/* Insert a mapping FROM->TO in the init priority hashtable.  */
+
+void
+decl_init_priority_insert (tree from, unsigned short to)
+{
+  struct tree_int_map *h;
+  void **loc;
+
+  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;
+}  
+
+/* Look up a restrict qualified base decl for FROM.  */
+
+tree
+decl_restrict_base_lookup (tree from)
+{
+  struct tree_map *h;
+  struct tree_map in;
+
+  in.from = from;
+  h = htab_find_with_hash (restrict_base_for_decl, &in,
+                          htab_hash_pointer (from));
+  return h ? h->to : NULL_TREE;
+}
+
+/* Record the restrict qualified base TO for FROM.  */
+
+void
+decl_restrict_base_insert (tree from, tree to)
+{
+  struct tree_map *h;
+  void **loc;
+
+  h = ggc_alloc (sizeof (struct tree_map));
+  h->hash = htab_hash_pointer (from);
+  h->from = from;
+  h->to = to;
+  loc = htab_find_slot_with_hash (restrict_base_for_decl, h, h->hash, INSERT);
+  *(struct tree_map **) loc = h;
+}
+
+/* Print out the statistics for the DECL_DEBUG_EXPR hash table.  */
+
+static void
+print_debug_expr_statistics (void)
+{
+  fprintf (stderr, "DECL_DEBUG_EXPR  hash: size %ld, %ld elements, %f collisions\n",
+          (long) htab_size (debug_expr_for_decl),
+          (long) htab_elements (debug_expr_for_decl),
+          htab_collisions (debug_expr_for_decl));
+}
+
+/* Print out the statistics for the DECL_VALUE_EXPR hash table.  */
+
+static void
+print_value_expr_statistics (void)
+{
+  fprintf (stderr, "DECL_VALUE_EXPR  hash: size %ld, %ld elements, %f collisions\n",
+          (long) htab_size (value_expr_for_decl),
+          (long) htab_elements (value_expr_for_decl),
+          htab_collisions (value_expr_for_decl));
+}
+
+/* Print out statistics for the RESTRICT_BASE_FOR_DECL hash table, but
+   don't print anything if the table is empty.  */
+
+static void
+print_restrict_base_statistics (void)
+{
+  if (htab_elements (restrict_base_for_decl) != 0)
+    fprintf (stderr,
+            "RESTRICT_BASE    hash: size %ld, %ld elements, %f collisions\n",
+            (long) htab_size (restrict_base_for_decl),
+            (long) htab_elements (restrict_base_for_decl),
+            htab_collisions (restrict_base_for_decl));
+}
+
+/* Lookup a debug expression for FROM, and return it if we find one.  */
+
+tree 
+decl_debug_expr_lookup (tree from)
+{
+  struct tree_map *h, in;
+  in.from = from;
+
+  h = htab_find_with_hash (debug_expr_for_decl, &in, htab_hash_pointer (from));
+  if (h)
+    return h->to;
+  return NULL_TREE;
+}
+
+/* Insert a mapping FROM->TO in the debug expression hashtable.  */
+
+void
+decl_debug_expr_insert (tree from, tree to)
+{
+  struct tree_map *h;
+  void **loc;
+
+  h = ggc_alloc (sizeof (struct tree_map));
+  h->hash = htab_hash_pointer (from);
+  h->from = from;
+  h->to = to;
+  loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT);
+  *(struct tree_map **) loc = h;
+}  
+
+/* Lookup a value expression for FROM, and return it if we find one.  */
+
+tree 
+decl_value_expr_lookup (tree from)
+{
+  struct tree_map *h, in;
+  in.from = from;
+
+  h = htab_find_with_hash (value_expr_for_decl, &in, htab_hash_pointer (from));
+  if (h)
+    return h->to;
+  return NULL_TREE;
+}
+
+/* Insert a mapping FROM->TO in the value expression hashtable.  */
+
+void
+decl_value_expr_insert (tree from, tree to)
+{
+  struct tree_map *h;
+  void **loc;
+
+  h = ggc_alloc (sizeof (struct tree_map));
+  h->hash = htab_hash_pointer (from);
+  h->from = from;
+  h->to = to;
+  loc = htab_find_slot_with_hash (value_expr_for_decl, h, h->hash, INSERT);
+  *(struct tree_map **) loc = h;
+}
+
+/* Hashing of types so that we don't make duplicates.
+   The entry point is `type_hash_canon'.  */
+
+/* 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
+   of the individual types.  */
+
+unsigned int
+type_hash_list (tree list, hashval_t hashcode)
+{
+  tree tail;
+
+  for (tail = list; tail; tail = TREE_CHAIN (tail))
+    if (TREE_VALUE (tail) != error_mark_node)
+      hashcode = iterative_hash_object (TYPE_HASH (TREE_VALUE (tail)),
+                                       hashcode);
+
+  return hashcode;
+}
+
+/* These are the Hashtable callback functions.  */
+
+/* Returns true iff the types are equivalent.  */
+
+static int
+type_hash_eq (const void *va, const void *vb)
+{
+  const struct type_hash *a = va, *b = vb;
+
+  /* First test the things that are the same for all types.  */
+  if (a->hash != b->hash
+      || TREE_CODE (a->type) != TREE_CODE (b->type)
+      || TREE_TYPE (a->type) != TREE_TYPE (b->type)
+      || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
+                                TYPE_ATTRIBUTES (b->type))
+      || TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
+      || TYPE_MODE (a->type) != TYPE_MODE (b->type))
+    return 0;
+
+  switch (TREE_CODE (a->type))
+    {
+    case VOID_TYPE:
+    case COMPLEX_TYPE:
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+      return 1;
+
+    case VECTOR_TYPE:
+      return TYPE_VECTOR_SUBPARTS (a->type) == TYPE_VECTOR_SUBPARTS (b->type);
+
+    case ENUMERAL_TYPE:
+      if (TYPE_VALUES (a->type) != TYPE_VALUES (b->type)
+         && !(TYPE_VALUES (a->type)
+              && TREE_CODE (TYPE_VALUES (a->type)) == TREE_LIST
+              && TYPE_VALUES (b->type)
+              && TREE_CODE (TYPE_VALUES (b->type)) == TREE_LIST
+              && type_list_equal (TYPE_VALUES (a->type),
+                                  TYPE_VALUES (b->type))))
+       return 0;
+
+      /* ... fall through ... */
+
+    case INTEGER_TYPE:
+    case REAL_TYPE:
+    case BOOLEAN_TYPE:
+      return ((TYPE_MAX_VALUE (a->type) == TYPE_MAX_VALUE (b->type)
+              || tree_int_cst_equal (TYPE_MAX_VALUE (a->type),
+                                     TYPE_MAX_VALUE (b->type)))
+             && (TYPE_MIN_VALUE (a->type) == TYPE_MIN_VALUE (b->type)
+                 || tree_int_cst_equal (TYPE_MIN_VALUE (a->type),
+                                        TYPE_MIN_VALUE (b->type))));
+
+    case OFFSET_TYPE:
+      return TYPE_OFFSET_BASETYPE (a->type) == TYPE_OFFSET_BASETYPE (b->type);
+
+    case METHOD_TYPE:
       return (TYPE_METHOD_BASETYPE (a->type) == TYPE_METHOD_BASETYPE (b->type)
              && (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
                  || (TYPE_ARG_TYPES (a->type)
@@ -3836,14 +4430,13 @@ tree_int_cst_compare (tree t1, tree t2)
 
 /* Return 1 if T is an INTEGER_CST that can be manipulated efficiently on
    the host.  If POS is zero, the value can be represented in a single
-   HOST_WIDE_INT.  If POS is nonzero, the value must be positive and can
+   HOST_WIDE_INT.  If POS is nonzero, the value must be non-negative and can
    be represented in a single unsigned HOST_WIDE_INT.  */
 
 int
 host_integerp (tree t, int pos)
 {
   return (TREE_CODE (t) == INTEGER_CST
-         && ! TREE_OVERFLOW (t)
          && ((TREE_INT_CST_HIGH (t) == 0
               && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
              || (! pos && TREE_INT_CST_HIGH (t) == -1
@@ -3854,7 +4447,7 @@ host_integerp (tree t, int pos)
 
 /* Return the HOST_WIDE_INT least significant bits of T if it is an
    INTEGER_CST and there is no overflow.  POS is nonzero if the result must
-   be positive.  We must be able to satisfy the above conditions.  */
+   be non-negative.  We must be able to satisfy the above conditions.  */
 
 HOST_WIDE_INT
 tree_low_cst (tree t, int pos)
@@ -3882,7 +4475,7 @@ tree_int_cst_msb (tree t)
 
 /* Return an indication of the sign of the integer constant T.
    The return value is -1 if T < 0, 0 if T == 0, and 1 if T > 0.
-   Note that -1 will never be returned it T's type is unsigned.  */
+   Note that -1 will never be returned if T's type is unsigned.  */
 
 int
 tree_int_cst_sgn (tree t)
@@ -3967,8 +4560,21 @@ simple_cst_equal (tree t1, tree t2)
                         TREE_STRING_LENGTH (t1)));
 
     case CONSTRUCTOR:
-      return simple_cst_list_equal (CONSTRUCTOR_ELTS (t1),
-                                   CONSTRUCTOR_ELTS (t2));
+      {
+       unsigned HOST_WIDE_INT idx;
+       VEC(constructor_elt, gc) *v1 = CONSTRUCTOR_ELTS (t1);
+       VEC(constructor_elt, gc) *v2 = CONSTRUCTOR_ELTS (t2);
+
+       if (VEC_length (constructor_elt, v1) != VEC_length (constructor_elt, v2))
+         return false;
+
+        for (idx = 0; idx < VEC_length (constructor_elt, v1); ++idx)
+         /* ??? Should we handle also fields here? */
+         if (!simple_cst_equal (VEC_index (constructor_elt, v1, idx)->value,
+                                VEC_index (constructor_elt, v2, idx)->value))
+           return false;
+       return true;
+      }
 
     case SAVE_EXPR:
       return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
@@ -4176,6 +4782,17 @@ iterative_hash_expr (tree t, hashval_t val)
       for (; t; t = TREE_CHAIN (t))
        val = iterative_hash_expr (TREE_VALUE (t), val);
       return val;
+    case CONSTRUCTOR:
+      {
+       unsigned HOST_WIDE_INT idx;
+       tree field, value;
+       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), idx, field, value)
+         {
+           val = iterative_hash_expr (field, val);
+           val = iterative_hash_expr (value, val);
+         }
+       return val;
+      }
     case FUNCTION_DECL:
       /* When referring to a built-in FUNCTION_DECL, use the
         __builtin__ form.  Otherwise nodes that compare equal
@@ -4193,8 +4810,8 @@ iterative_hash_expr (tree t, hashval_t val)
 
       if (class == tcc_declaration)
        {
-         /* Otherwise, we can just compare decls by pointer.  */
-         val = iterative_hash_pointer (t, val);
+         /* DECL's have a unique ID */
+         val = iterative_hash_host_wide_int (DECL_UID (t), val);
        }
       else
        {
@@ -4254,6 +4871,9 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode,
 {
   tree t;
 
+  if (to_type == error_mark_node)
+    return error_mark_node;
+
   /* In some cases, languages will have things that aren't a POINTER_TYPE
      (such as a RECORD_TYPE for fat pointers in Ada) as TYPE_POINTER_TO.
      In that case, return that type without regard to the rest of our
@@ -4421,9 +5041,8 @@ build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision,
 }
 
 /* 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.  */
+   ENUMERAL_TYPE or BOOLEAN_TYPE), with low bound LOWVAL and
+   high bound HIGHVAL.  If TYPE is NULL, sizetype is used.  */
 
 tree
 build_range_type (tree type, tree lowval, tree highval)
@@ -4434,8 +5053,8 @@ build_range_type (tree type, tree lowval, tree highval)
   if (type == NULL_TREE)
     type = sizetype;
 
-  TYPE_MIN_VALUE (itype) = convert (type, lowval);
-  TYPE_MAX_VALUE (itype) = highval ? convert (type, highval) : NULL;
+  TYPE_MIN_VALUE (itype) = fold_convert (type, lowval);
+  TYPE_MAX_VALUE (itype) = highval ? fold_convert (type, highval) : NULL;
 
   TYPE_PRECISION (itype) = TYPE_PRECISION (type);
   TYPE_MODE (itype) = TYPE_MODE (type);
@@ -4752,9 +5371,16 @@ get_unwidened (tree op, tree for_type)
   while (TREE_CODE (op) == NOP_EXPR
         || TREE_CODE (op) == CONVERT_EXPR)
     {
-      int bitschange
-       = TYPE_PRECISION (TREE_TYPE (op))
-         - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));
+      int bitschange;
+
+      /* TYPE_PRECISION on vector types has different meaning
+        (TYPE_VECTOR_SUBPARTS) and casts from vectors are view conversions,
+        so avoid them here.  */
+      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == VECTOR_TYPE)
+       break;
+
+      bitschange = TYPE_PRECISION (TREE_TYPE (op))
+                  - TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op, 0)));
 
       /* Truncations are many-one so cannot be removed.
         Unless we are later going to truncate down even farther.  */
@@ -4982,8 +5608,11 @@ int_fits_type_p (tree c, tree type)
     return 0;
 
   /* If we haven't been able to decide at this point, there nothing more we
-     can check ourselves here. Look at the base type if we have one.  */
-  if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
+     can check ourselves here.  Look at the base type if we have one and it
+     has the same precision.  */
+  if (TREE_CODE (type) == INTEGER_TYPE
+      && TREE_TYPE (type) != 0
+      && 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.  */
@@ -5015,8 +5644,10 @@ find_var_from_fn (tree *tp, int *walk_subtrees, void *data)
 }
 
 /* Returns true if T is, contains, or refers to a type with variable
-   size.  If FN is nonzero, only return true if a modifier of the type
-   or position of FN is a variable or parameter inside FN.
+   size.  For METHOD_TYPEs and FUNCTION_TYPEs we exclude the
+   arguments, but not the return type.  If FN is nonzero, only return
+   true if a modifier of the type or position of FN is a variable or
+   parameter inside FN.
 
    This concept is more general than that of C99 'variably modified types':
    in C99, a struct type is never variably modified because a VLA may not
@@ -5042,19 +5673,14 @@ variably_modified_type_p (tree type, tree fn)
   if (type == error_mark_node)
     return false;
 
-  /* If TYPE itself has variable size, it is variably modified.
-
-     We do not yet have a representation of the C99 '[*]' syntax.
-     When a representation is chosen, this function should be modified
-     to test for that case as well.  */
+  /* If TYPE itself has variable size, it is variably modified.  */
   RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
-  RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT(type));
+  RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (type));
 
   switch (TREE_CODE (type))
     {
     case POINTER_TYPE:
     case REFERENCE_TYPE:
-    case ARRAY_TYPE:
     case VECTOR_TYPE:
       if (variably_modified_type_p (TREE_TYPE (type), fn))
        return true;
@@ -5062,23 +5688,16 @@ variably_modified_type_p (tree type, tree fn)
 
     case FUNCTION_TYPE:
     case METHOD_TYPE:
-      /* If TYPE is a function type, it is variably modified if any of the
-         parameters or the return type are variably modified.  */
+      /* If TYPE is a function type, it is variably modified if the
+        return type is variably modified.  */
       if (variably_modified_type_p (TREE_TYPE (type), fn))
          return true;
-
-      for (t = TYPE_ARG_TYPES (type);
-          t && t != void_list_node;
-          t = TREE_CHAIN (t))
-       if (variably_modified_type_p (TREE_VALUE (t), fn))
-         return true;
       break;
 
     case INTEGER_TYPE:
     case REAL_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
-    case CHAR_TYPE:
       /* Scalar types are variably modified if their end points
         aren't constant.  */
       RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
@@ -5088,7 +5707,7 @@ variably_modified_type_p (tree type, tree fn)
     case RECORD_TYPE:
     case UNION_TYPE:
     case QUAL_UNION_TYPE:
-      /* We can't see if any of the field are variably-modified by the
+      /* We can't see if any of the fields are variably-modified by the
         definition we normally use, since that would produce infinite
         recursion via pointers.  */
       /* This is variably modified if some field's type is.  */
@@ -5104,6 +5723,13 @@ variably_modified_type_p (tree type, tree fn)
          }
        break;
 
+    case ARRAY_TYPE:
+      /* Do not call ourselves to avoid infinite recursion.  This is
+        variably modified if the element type is.  */
+      RETURN_TRUE_IF_VAR (TYPE_SIZE (TREE_TYPE (type)));
+      RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (TREE_TYPE (type)));
+      break;
+
     default:
       break;
     }
@@ -5205,6 +5831,9 @@ get_callee_fndecl (tree call)
 {
   tree addr;
 
+  if (call == error_mark_node)
+    return call;
+
   /* It's invalid to call this function with anything but a
      CALL_EXPR.  */
   gcc_assert (TREE_CODE (call) == CALL_EXPR);
@@ -5264,6 +5893,9 @@ dump_tree_statistics (void)
   fprintf (stderr, "(No per-node statistics)\n");
 #endif
   print_type_hash_statistics ();
+  print_debug_expr_statistics ();
+  print_value_expr_statistics ();
+  print_restrict_base_statistics ();
   lang_hooks.print_statistics ();
 }
 \f
@@ -5322,7 +5954,26 @@ get_file_function_name_long (const char *type)
   char *q;
 
   if (first_global_object_name)
-    p = first_global_object_name;
+    {
+      p = first_global_object_name;
+
+      /* For type 'F', the generated name must be unique not only to this
+        translation unit but also to any given link.  Since global names
+        can be overloaded, we concatenate the first global object name
+        with a string derived from the file name of this object.  */
+      if (!strcmp (type, "F"))
+       {
+         const char *file = main_input_filename;
+
+         if (! file)
+           file = input_filename;
+
+         q = alloca (strlen (p) + 10);
+         sprintf (q, "%s_%08X", p, crc32_string (0, file));
+
+         p = q;
+       }
+    }
   else
     {
       /* We don't have anything that we know to be unique to this translation
@@ -5468,6 +6119,128 @@ tree_class_check_failed (const tree node, const enum tree_code_class cl,
      tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
 }
 
+/* Similar to tree_check_failed, except that instead of specifying a
+   dozen codes, use the knowledge that they're all sequential.  */
+
+void
+tree_range_check_failed (const tree node, const char *file, int line,
+                        const char *function, enum tree_code c1,
+                        enum tree_code c2)
+{
+  char *buffer;
+  unsigned length = 0;
+  enum tree_code c;
+
+  for (c = c1; c <= c2; ++c)
+    length += 4 + strlen (tree_code_name[c]);
+
+  length += strlen ("expected ");
+  buffer = alloca (length);
+  length = 0;
+
+  for (c = c1; c <= c2; ++c)
+    {
+      const char *prefix = length ? " or " : "expected ";
+
+      strcpy (buffer + length, prefix);
+      length += strlen (prefix);
+      strcpy (buffer + length, tree_code_name[c]);
+      length += strlen (tree_code_name[c]);
+    }
+
+  internal_error ("tree check: %s, have %s in %s, at %s:%d",
+                 buffer, tree_code_name[TREE_CODE (node)],
+                 function, trim_filename (file), line);
+}
+
+
+/* Similar to tree_check_failed, except that we check that a tree does
+   not have the specified code, given in CL.  */
+
+void
+tree_not_class_check_failed (const tree node, const enum tree_code_class cl,
+                            const char *file, int line, const char *function)
+{
+  internal_error
+    ("tree check: did not expect class %qs, have %qs (%s) in %s, at %s:%d",
+     TREE_CODE_CLASS_STRING (cl),
+     TREE_CODE_CLASS_STRING (TREE_CODE_CLASS (TREE_CODE (node))),
+     tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
+}
+
+
+/* Similar to tree_check_failed but applied to OMP_CLAUSE codes.  */
+
+void
+omp_clause_check_failed (const tree node, const char *file, int line,
+                         const char *function, enum omp_clause_code code)
+{
+  internal_error ("tree check: expected omp_clause %s, have %s in %s, at %s:%d",
+                 omp_clause_code_name[code], tree_code_name[TREE_CODE (node)],
+                 function, trim_filename (file), line);
+}
+
+
+/* Similar to tree_range_check_failed but applied to OMP_CLAUSE codes.  */
+
+void
+omp_clause_range_check_failed (const tree node, const char *file, int line,
+                              const char *function, enum omp_clause_code c1,
+                              enum omp_clause_code c2)
+{
+  char *buffer;
+  unsigned length = 0;
+  enum omp_clause_code c;
+
+  for (c = c1; c <= c2; ++c)
+    length += 4 + strlen (omp_clause_code_name[c]);
+
+  length += strlen ("expected ");
+  buffer = alloca (length);
+  length = 0;
+
+  for (c = c1; c <= c2; ++c)
+    {
+      const char *prefix = length ? " or " : "expected ";
+
+      strcpy (buffer + length, prefix);
+      length += strlen (prefix);
+      strcpy (buffer + length, omp_clause_code_name[c]);
+      length += strlen (omp_clause_code_name[c]);
+    }
+
+  internal_error ("tree check: %s, have %s in %s, at %s:%d",
+                 buffer, omp_clause_code_name[TREE_CODE (node)],
+                 function, trim_filename (file), line);
+}
+
+
+#undef DEFTREESTRUCT
+#define DEFTREESTRUCT(VAL, NAME) NAME,
+
+static const char *ts_enum_names[] = {
+#include "treestruct.def"
+};
+#undef DEFTREESTRUCT
+
+#define TS_ENUM_NAME(EN) (ts_enum_names[(EN)])
+
+/* Similar to tree_class_check_failed, except that we check for
+   whether CODE contains the tree structure identified by EN.  */
+
+void
+tree_contains_struct_check_failed (const tree node, 
+                                  const enum tree_node_structure_enum en,
+                                  const char *file, int line, 
+                                  const char *function)
+{
+  internal_error
+    ("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);
+}
+
+
 /* Similar to above, except that the check is for the bounds of a TREE_VEC's
    (dynamically sized) vector.  */
 
@@ -5504,6 +6277,20 @@ tree_operand_check_failed (int idx, enum tree_code code, const char *file,
      idx + 1, tree_code_name[code], TREE_CODE_LENGTH (code),
      function, trim_filename (file), line);
 }
+
+/* Similar to above, except that the check is for the number of
+   operands of an OMP_CLAUSE node.  */
+
+void
+omp_clause_operand_check_failed (int idx, tree t, const char *file,
+                                int line, const char *function)
+{
+  internal_error
+    ("tree check: accessed operand %d of omp_clause %s with %d operands "
+     "in %s, at %s:%d", idx + 1, omp_clause_code_name[OMP_CLAUSE_CODE (t)],
+     omp_clause_num_ops [OMP_CLAUSE_CODE (t)], function,
+     trim_filename (file), line);
+}
 #endif /* ENABLE_TREE_CHECKING */
 \f
 /* Create a new vector type node holding SUBPARTS units of type INNERTYPE,
@@ -5516,7 +6303,7 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode)
   tree t = make_node (VECTOR_TYPE);
 
   TREE_TYPE (t) = TYPE_MAIN_VARIANT (innertype);
-  TYPE_VECTOR_SUBPARTS (t) = nunits;
+  SET_TYPE_VECTOR_SUBPARTS (t, nunits);
   TYPE_MODE (t) = mode;
   TYPE_READONLY (t) = TYPE_READONLY (innertype);
   TYPE_VOLATILE (t) = TYPE_VOLATILE (innertype);
@@ -5587,7 +6374,9 @@ build_common_tree_nodes (bool signed_char, bool signed_sizetype)
 
   /* Define both `signed char' and `unsigned char'.  */
   signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE);
+  TYPE_STRING_FLAG (signed_char_type_node) = 1;
   unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE);
+  TYPE_STRING_FLAG (unsigned_char_type_node) = 1;
 
   /* Define `char', which is like either `signed char' or `unsigned char'
      but not the same as either.  */
@@ -5595,6 +6384,7 @@ build_common_tree_nodes (bool signed_char, bool signed_sizetype)
     = (signed_char
        ? make_signed_type (CHAR_TYPE_SIZE)
        : make_unsigned_type (CHAR_TYPE_SIZE));
+  TYPE_STRING_FLAG (char_type_node) = 1;
 
   short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE);
   short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE);
@@ -5689,6 +6479,25 @@ build_common_tree_nodes_2 (int short_double)
   long_double_ptr_type_node = build_pointer_type (long_double_type_node);
   integer_ptr_type_node = build_pointer_type (integer_type_node);
 
+  /* Decimal float types. */
+  dfloat32_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE; 
+  layout_type (dfloat32_type_node);
+  TYPE_MODE (dfloat32_type_node) = SDmode;
+  dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
+
+  dfloat64_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
+  layout_type (dfloat64_type_node);
+  TYPE_MODE (dfloat64_type_node) = DDmode;
+  dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
+
+  dfloat128_type_node = make_node (REAL_TYPE);
+  TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE; 
+  layout_type (dfloat128_type_node);
+  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);
@@ -5775,7 +6584,7 @@ build_common_builtin_nodes (void)
       tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
       tmp = tree_cons (NULL_TREE, const_ptr_type_node, tmp);
       tmp = tree_cons (NULL_TREE, const_ptr_type_node, tmp);
-      ftype = build_function_type (ptr_type_node, tmp);
+      ftype = build_function_type (integer_type_node, tmp);
       local_define_builtin ("__builtin_memcmp", ftype, BUILT_IN_MEMCMP,
                            "memcmp", ECF_PURE | ECF_NOTHROW);
     }
@@ -5970,6 +6779,16 @@ build_vector_type (tree innertype, int nunits)
   return make_vector_type (innertype, nunits, VOIDmode);
 }
 
+/* Build RESX_EXPR with given REGION_NUMBER.  */
+tree
+build_resx (int region_number)
+{
+  tree t;
+  t = build1 (RESX_EXPR, void_type_node,
+             build_int_cst (NULL_TREE, region_number));
+  return t;
+}
+
 /* Given an initializer INIT, return TRUE if INIT is zero or some
    aggregate of zeros.  Otherwise return FALSE.  */
 bool
@@ -6004,30 +6823,20 @@ initializer_zerop (tree init)
       return true;
 
     case CONSTRUCTOR:
-      elt = CONSTRUCTOR_ELTS (init);
-      if (elt == NULL_TREE)
-       return true;
+      {
+       unsigned HOST_WIDE_INT idx;
 
-      for (; elt ; elt = TREE_CHAIN (elt))
-       if (! initializer_zerop (TREE_VALUE (elt)))
-         return false;
-      return true;
+       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt)
+         if (!initializer_zerop (elt))
+           return false;
+       return true;
+      }
 
     default:
       return false;
     }
 }
 
-void
-add_var_to_bind_expr (tree bind_expr, tree var)
-{
-  BIND_EXPR_VARS (bind_expr)
-    = chainon (BIND_EXPR_VARS (bind_expr), var);
-  if (BIND_EXPR_BLOCK (bind_expr))
-    BLOCK_VARS (BIND_EXPR_BLOCK (bind_expr))
-      = BIND_EXPR_VARS (bind_expr);
-}
-
 /* Build an empty statement.  */
 
 tree
@@ -6037,6 +6846,31 @@ build_empty_stmt (void)
 }
 
 
+/* Build an OpenMP clause with code CODE.  */
+
+tree
+build_omp_clause (enum omp_clause_code code)
+{
+  tree t;
+  int size, length;
+
+  length = omp_clause_num_ops[code];
+  size = (sizeof (struct tree_omp_clause) + (length - 1) * sizeof (tree));
+
+  t = ggc_alloc (size);
+  memset (t, 0, size);
+  TREE_SET_CODE (t, OMP_CLAUSE);
+  OMP_CLAUSE_SET_CODE (t, code);
+
+#ifdef GATHER_STATISTICS
+  tree_node_counts[(int) omp_clause_kind]++;
+  tree_node_sizes[(int) omp_clause_kind] += size;
+#endif
+  
+  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
    array bounds.  */
@@ -6070,7 +6904,10 @@ in_array_bounds_p (tree ref)
 bool
 is_global_var (tree t)
 {
-  return (TREE_STATIC (t) || DECL_EXTERNAL (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
@@ -6167,16 +7004,16 @@ tree_fold_gcd (tree a, tree b)
     return a;
 
   if (tree_int_cst_sgn (a) == -1)
-    a = fold (build2 (MULT_EXPR, type, a,
-                     convert (type, integer_minus_one_node)));
+    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,
-                     convert (type, integer_minus_one_node)));
+    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));
+      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))
@@ -6192,6 +7029,8 @@ 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);
 }
 
@@ -6200,6 +7039,8 @@ 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);
 }
 
@@ -6210,43 +7051,64 @@ tree
 upper_bound_in_type (tree outer, tree inner)
 {
   unsigned HOST_WIDE_INT lo, hi;
-  unsigned bits = TYPE_PRECISION (inner);
+  unsigned int det = 0;
+  unsigned oprec = TYPE_PRECISION (outer);
+  unsigned iprec = TYPE_PRECISION (inner);
+  unsigned prec;
+
+  /* Compute a unique number for every combination.  */
+  det |= (oprec > iprec) ? 4 : 0;
+  det |= TYPE_UNSIGNED (outer) ? 2 : 0;
+  det |= TYPE_UNSIGNED (inner) ? 1 : 0;
+
+  /* Determine the exponent to use.  */
+  switch (det)
+    {
+    case 0:
+    case 1:
+      /* oprec <= iprec, outer: signed, inner: don't care.  */
+      prec = oprec - 1;
+      break;
+    case 2:
+    case 3:
+      /* oprec <= iprec, outer: unsigned, inner: don't care.  */
+      prec = oprec;
+      break;
+    case 4:
+      /* oprec > iprec, outer: signed, inner: signed.  */
+      prec = iprec - 1;
+      break;
+    case 5:
+      /* oprec > iprec, outer: signed, inner: unsigned.  */
+      prec = iprec;
+      break;
+    case 6:
+      /* oprec > iprec, outer: unsigned, inner: signed.  */
+      prec = oprec;
+      break;
+    case 7:
+      /* oprec > iprec, outer: unsigned, inner: unsigned.  */
+      prec = iprec;
+      break;
+    default:
+      gcc_unreachable ();
+    }
 
-  if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner))
+  /* Compute 2^^prec - 1.  */
+  if (prec <= HOST_BITS_PER_WIDE_INT)
     {
-      /* Zero extending in these cases.  */
-      if (bits <= HOST_BITS_PER_WIDE_INT)
-       {
-         hi = 0;
-         lo = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (HOST_BITS_PER_WIDE_INT - bits);
-       }
-      else
-       {
-         hi = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (2 * HOST_BITS_PER_WIDE_INT - bits);
-         lo = ~(unsigned HOST_WIDE_INT) 0;
-       }
+      hi = 0;
+      lo = ((~(unsigned HOST_WIDE_INT) 0)
+           >> (HOST_BITS_PER_WIDE_INT - prec));
     }
   else
     {
-      /* Sign extending in these cases.  */
-      if (bits <= HOST_BITS_PER_WIDE_INT)
-       {
-         hi = 0;
-         lo = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (HOST_BITS_PER_WIDE_INT - bits) >> 1;
-       }
-      else
-       {
-         hi = (~(unsigned HOST_WIDE_INT) 0)
-                 >> (2 * HOST_BITS_PER_WIDE_INT - bits) >> 1;
-         lo = ~(unsigned HOST_WIDE_INT) 0;
-       }
+      hi = ((~(unsigned HOST_WIDE_INT) 0)
+           >> (2 * HOST_BITS_PER_WIDE_INT - prec));
+      lo = ~(unsigned HOST_WIDE_INT) 0;
     }
 
-  return fold_convert (outer,
-                      build_int_cst_wide (inner, lo, hi));
+  return build_int_cst_wide (outer, lo, hi);
 }
 
 /* Returns the smallest value obtainable by casting something in INNER type to
@@ -6256,23 +7118,39 @@ tree
 lower_bound_in_type (tree outer, tree inner)
 {
   unsigned HOST_WIDE_INT lo, hi;
-  unsigned bits = TYPE_PRECISION (inner);
-
-  if (TYPE_UNSIGNED (outer) || TYPE_UNSIGNED (inner))
+  unsigned oprec = TYPE_PRECISION (outer);
+  unsigned iprec = TYPE_PRECISION (inner);
+
+  /* If OUTER type is unsigned, we can definitely cast 0 to OUTER type
+     and obtain 0.  */
+  if (TYPE_UNSIGNED (outer)
+      /* If we are widening something of an unsigned type, OUTER type
+        contains all values of INNER type.  In particular, both INNER
+        and OUTER types have zero in common.  */
+      || (oprec > iprec && TYPE_UNSIGNED (inner)))
     lo = hi = 0;
-  else if (bits <= HOST_BITS_PER_WIDE_INT)
-    {
-      hi = ~(unsigned HOST_WIDE_INT) 0;
-      lo = (~(unsigned HOST_WIDE_INT) 0) << (bits - 1);
-    }
   else
     {
-      hi = (~(unsigned HOST_WIDE_INT) 0) << (bits - HOST_BITS_PER_WIDE_INT - 1);
-      lo = 0;
+      /* If we are widening a signed type to another signed type, we
+        want to obtain -2^^(iprec-1).  If we are keeping the
+        precision or narrowing to a signed type, we want to obtain
+        -2^(oprec-1).  */
+      unsigned prec = oprec > iprec ? iprec : oprec;
+
+      if (prec <= HOST_BITS_PER_WIDE_INT)
+       {
+         hi = ~(unsigned HOST_WIDE_INT) 0;
+         lo = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
+       }
+      else
+       {
+         hi = ((~(unsigned HOST_WIDE_INT) 0)
+               << (prec - HOST_BITS_PER_WIDE_INT - 1));
+         lo = 0;
+       }
     }
 
-  return fold_convert (outer,
-                      build_int_cst_wide (inner, lo, hi));
+  return build_int_cst_wide (outer, lo, hi);
 }
 
 /* Return nonzero if two operands that are suitable for PHI nodes are
@@ -6407,7 +7285,6 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
     case BOOLEAN_TYPE:
     case ENUMERAL_TYPE:
     case INTEGER_TYPE:
-    case CHAR_TYPE:
     case REAL_TYPE:
       WALK_SUBTREE (TYPE_MIN_VALUE (type));
       WALK_SUBTREE (TYPE_MAX_VALUE (type));
@@ -6470,9 +7347,11 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
      interesting below this point in the tree.  */
   if (!walk_subtrees)
     {
+      /* But we still need to check our siblings.  */
       if (code == TREE_LIST)
-       /* But we still need to check our siblings.  */
        WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+      else if (code == OMP_CLAUSE)
+       WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
       else
        return NULL_TREE;
     }
@@ -6482,181 +7361,207 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
   if (result || ! walk_subtrees)
     return result;
 
-  /* If this is a DECL_EXPR, walk into various fields of the type that it's
-     defining.  We only want to walk into these fields of a type in this
-     case.  Note that decls get walked as part of the processing of a
-     BIND_EXPR.
-
-     ??? Precisely which fields of types that we are supposed to walk in
-     this case vs. the normal case aren't well defined.  */
-  if (code == DECL_EXPR
-      && TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
-      && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+  switch (code)
     {
-      tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
+    case ERROR_MARK:
+    case IDENTIFIER_NODE:
+    case INTEGER_CST:
+    case REAL_CST:
+    case VECTOR_CST:
+    case STRING_CST:
+    case BLOCK:
+    case PLACEHOLDER_EXPR:
+    case SSA_NAME:
+    case FIELD_DECL:
+    case RESULT_DECL:
+      /* None of these have subtrees other than those already walked
+        above.  */
+      break;
 
-      /* Call the function for the type.  See if it returns anything or
-        doesn't want us to continue.  If we are to continue, walk both
-        the normal fields and those for the declaration case.  */
-      result = (*func) (type_p, &walk_subtrees, data);
-      if (result || !walk_subtrees)
-       return NULL_TREE;
+    case TREE_LIST:
+      WALK_SUBTREE (TREE_VALUE (*tp));
+      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
+      break;
 
-      result = walk_type_fields (*type_p, func, data, pset);
-      if (result)
-       return result;
+    case TREE_VEC:
+      {
+       int len = TREE_VEC_LENGTH (*tp);
 
-      WALK_SUBTREE (TYPE_SIZE (*type_p));
-      WALK_SUBTREE (TYPE_SIZE_UNIT (*type_p));
+       if (len == 0)
+         break;
 
-      /* If this is a record type, also walk the fields.  */
-      if (TREE_CODE (*type_p) == RECORD_TYPE
-         || TREE_CODE (*type_p) == UNION_TYPE
-         || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
-       {
-         tree field;
+       /* Walk all elements but the first.  */
+       while (--len)
+         WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
 
-         for (field = TYPE_FIELDS (*type_p); field;
-              field = TREE_CHAIN (field))
-           {
-             /* We'd like to look at the type of the field, but we can easily
-                get infinite recursion.  So assume it's pointed to elsewhere
-                in the tree.  Also, ignore things that aren't fields.  */
-             if (TREE_CODE (field) != FIELD_DECL)
-               continue;
-
-             WALK_SUBTREE (DECL_FIELD_OFFSET (field));
-             WALK_SUBTREE (DECL_SIZE (field));
-             WALK_SUBTREE (DECL_SIZE_UNIT (field));
-             if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
-               WALK_SUBTREE (DECL_QUALIFIER (field));
-           }
-       }
-    }
+       /* Now walk the first one as a tail call.  */
+       WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
+      }
 
-  else if (code != SAVE_EXPR
-          && code != BIND_EXPR
-          && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
-    {
-      int i, len;
-
-      /* Walk over all the sub-trees of this operand.  */
-      len = TREE_CODE_LENGTH (code);
-      /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
-        But, we only want to walk once.  */
-      if (code == TARGET_EXPR
-         && TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1))
-       --len;
-
-      /* Go through the subtrees.  We need to do this in forward order so
-         that the scope of a FOR_EXPR is handled properly.  */
-#ifdef DEBUG_WALK_TREE
-      for (i = 0; i < len; ++i)
-       WALK_SUBTREE (TREE_OPERAND (*tp, i));
-#else
-      for (i = 0; i < len - 1; ++i)
-       WALK_SUBTREE (TREE_OPERAND (*tp, i));
+    case COMPLEX_CST:
+      WALK_SUBTREE (TREE_REALPART (*tp));
+      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
 
-      if (len)
-       {
-         /* The common case is that we may tail recurse here.  */
-         if (code != BIND_EXPR
-             && !TREE_CHAIN (*tp))
-           WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
-         else
-           WALK_SUBTREE (TREE_OPERAND (*tp, len - 1));
-       }
-#endif
-    }
+    case CONSTRUCTOR:
+      {
+       unsigned HOST_WIDE_INT idx;
+       constructor_elt *ce;
 
-  /* If this is a type, walk the needed fields in the type.  */
-  else if (TYPE_P (*tp))
-    {
-      result = walk_type_fields (*tp, func, data, pset);
-      if (result)
-       return result;
-    }
-  else
-    {
-      /* Not one of the easy cases.  We must explicitly go through the
-        children.  */
-      switch (code)
-       {
-       case ERROR_MARK:
-       case IDENTIFIER_NODE:
-       case INTEGER_CST:
-       case REAL_CST:
-       case VECTOR_CST:
-       case STRING_CST:
-       case BLOCK:
-       case PLACEHOLDER_EXPR:
-       case SSA_NAME:
-       case FIELD_DECL:
-       case RESULT_DECL:
-         /* None of thse have subtrees other than those already walked
-            above.  */
-         break;
+       for (idx = 0;
+            VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce);
+            idx++)
+         WALK_SUBTREE (ce->value);
+      }
+      break;
 
-       case TREE_LIST:
-         WALK_SUBTREE (TREE_VALUE (*tp));
-         WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
-         break;
+    case SAVE_EXPR:
+      WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
 
-       case TREE_VEC:
+    case BIND_EXPR:
+      {
+       tree decl;
+       for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
          {
-           int len = TREE_VEC_LENGTH (*tp);
-
-           if (len == 0)
-             break;
+           /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
+              into declarations that are just mentioned, rather than
+              declared; they don't really belong to this part of the tree.
+              And, we can see cycles: the initializer for a declaration
+              can refer to the declaration itself.  */
+           WALK_SUBTREE (DECL_INITIAL (decl));
+           WALK_SUBTREE (DECL_SIZE (decl));
+           WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+         }
+       WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+      }
 
-           /* Walk all elements but the first.  */
-           while (--len)
-             WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
+    case STATEMENT_LIST:
+      {
+       tree_stmt_iterator i;
+       for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+         WALK_SUBTREE (*tsi_stmt_ptr (i));
+      }
+      break;
 
-           /* Now walk the first one as a tail call.  */
-           WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
+    case OMP_CLAUSE:
+      switch (OMP_CLAUSE_CODE (*tp))
+       {
+       case OMP_CLAUSE_PRIVATE:
+       case OMP_CLAUSE_SHARED:
+       case OMP_CLAUSE_FIRSTPRIVATE:
+       case OMP_CLAUSE_LASTPRIVATE:
+       case OMP_CLAUSE_COPYIN:
+       case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_IF:
+       case OMP_CLAUSE_NUM_THREADS:
+       case OMP_CLAUSE_SCHEDULE:
+         WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
+         /* FALLTHRU */
+
+       case OMP_CLAUSE_NOWAIT:
+       case OMP_CLAUSE_ORDERED:
+       case OMP_CLAUSE_DEFAULT:
+         WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+
+       case OMP_CLAUSE_REDUCTION:
+         {
+           int i;
+           for (i = 0; i < 4; i++)
+             WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, i));
+           WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
          }
 
-       case COMPLEX_CST:
-         WALK_SUBTREE (TREE_REALPART (*tp));
-         WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
+       default:
+         gcc_unreachable ();
+       }
+      break;
 
-       case CONSTRUCTOR:
-         WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
+    case TARGET_EXPR:
+      {
+       int i, len;
+
+       /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
+          But, we only want to walk once.  */
+       len = (TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1)) ? 2 : 3;
+       for (i = 0; i < len; ++i)
+         WALK_SUBTREE (TREE_OPERAND (*tp, i));
+       WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len));
+      }
 
-       case SAVE_EXPR:
-         WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+    case DECL_EXPR:
+      /* Walk into various fields of the type that it's defining.  We only
+        want to walk into these fields of a type in this case.  Note that
+        decls get walked as part of the processing of a BIND_EXPR.
 
-       case BIND_EXPR:
-         {
-           tree decl;
-           for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
-             {
-               /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
-                  into declarations that are just mentioned, rather than
-                  declared; they don't really belong to this part of the tree.
-                  And, we can see cycles: the initializer for a declaration
-                  can refer to the declaration itself.  */
-               WALK_SUBTREE (DECL_INITIAL (decl));
-               WALK_SUBTREE (DECL_SIZE (decl));
-               WALK_SUBTREE (DECL_SIZE_UNIT (decl));
-             }
-           WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
-         }
+        ??? Precisely which fields of types that we are supposed to walk in
+        this case vs. the normal case aren't well defined.  */
+      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
+         && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+       {
+         tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
 
-       case STATEMENT_LIST:
-         {
-           tree_stmt_iterator i;
-           for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
-             WALK_SUBTREE (*tsi_stmt_ptr (i));
-         }
-         break;
+         /* Call the function for the type.  See if it returns anything or
+            doesn't want us to continue.  If we are to continue, walk both
+            the normal fields and those for the declaration case.  */
+         result = (*func) (type_p, &walk_subtrees, data);
+         if (result || !walk_subtrees)
+           return NULL_TREE;
 
-       default:
-         /* ??? This could be a language-defined node.  We really should make
-            a hook for it, but right now just ignore it.  */
-         break;
+         result = walk_type_fields (*type_p, func, data, pset);
+         if (result)
+           return result;
+
+         /* If this is a record type, also walk the fields.  */
+         if (TREE_CODE (*type_p) == RECORD_TYPE
+             || TREE_CODE (*type_p) == UNION_TYPE
+             || TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+           {
+             tree field;
+
+             for (field = TYPE_FIELDS (*type_p); field;
+                  field = TREE_CHAIN (field))
+               {
+                 /* We'd like to look at the type of the field, but we can
+                    easily get infinite recursion.  So assume it's pointed
+                    to elsewhere in the tree.  Also, ignore things that
+                    aren't fields.  */
+                 if (TREE_CODE (field) != FIELD_DECL)
+                   continue;
+
+                 WALK_SUBTREE (DECL_FIELD_OFFSET (field));
+                 WALK_SUBTREE (DECL_SIZE (field));
+                 WALK_SUBTREE (DECL_SIZE_UNIT (field));
+                 if (TREE_CODE (*type_p) == QUAL_UNION_TYPE)
+                   WALK_SUBTREE (DECL_QUALIFIER (field));
+               }
+           }
+
+         WALK_SUBTREE (TYPE_SIZE (*type_p));
+         WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
        }
+      /* FALLTHRU */
+
+    default:
+      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+       {
+         int i, len;
+
+         /* Walk over all the sub-trees of this operand.  */
+         len = TREE_CODE_LENGTH (code);
+
+         /* Go through the subtrees.  We need to do this in forward order so
+            that the scope of a FOR_EXPR is handled properly.  */
+         if (len)
+           {
+             for (i = 0; i < len - 1; ++i)
+               WALK_SUBTREE (TREE_OPERAND (*tp, i));
+             WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, len - 1));
+           }
+       }
+
+      /* If this is a type, walk the needed fields in the type.  */
+      else if (TYPE_P (*tp))
+       return walk_type_fields (*tp, func, data, pset);
+      break;
     }
 
   /* We didn't find what we were looking for.  */
@@ -6680,4 +7585,30 @@ walk_tree_without_duplicates (tree *tp, walk_tree_fn func, void *data)
   return result;
 }
 
+
+/* Return true if STMT is an empty statement or contains nothing but
+   empty statements.  */
+
+bool
+empty_body_p (tree stmt)
+{
+  tree_stmt_iterator i;
+  tree body;
+
+  if (IS_EMPTY_STMT (stmt))
+    return true;
+  else if (TREE_CODE (stmt) == BIND_EXPR)
+    body = BIND_EXPR_BODY (stmt);
+  else if (TREE_CODE (stmt) == STATEMENT_LIST)
+    body = stmt;
+  else
+    return false;
+
+  for (i = tsi_start (body); !tsi_end_p (i); tsi_next (&i))
+    if (!empty_body_p (tsi_stmt (i)))
+      return false;
+
+  return true;
+}
+
 #include "gt-tree.h"