OSDN Git Service

* intrinsic.texi (STAT): Fixed a format typo in sample code.
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 333c745..e838ba1 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.
 
@@ -96,7 +97,8 @@ static const char * const tree_node_kind_names[] = {
   "constructors",
   "random kinds",
   "lang_decl kinds",
-  "lang_type kinds"
+  "lang_type kinds",
+  "omp clauses"
 };
 #endif /* GATHER_STATISTICS */
 
@@ -172,13 +174,49 @@ 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.  */
 
 void
 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);
@@ -230,6 +268,15 @@ init_ttree (void)
   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;
@@ -288,6 +335,11 @@ tree_code_size (enum tree_code code)
            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);
          }
@@ -327,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);
@@ -366,7 +419,12 @@ tree_size (tree node)
              + (TREE_VEC_LENGTH (node) - 1) * sizeof(char *));
 
     case STRING_CST:
-      return sizeof (struct tree_string) + TREE_STRING_LENGTH (node) - 1;
+      return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 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);
@@ -375,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.  */
 
@@ -479,13 +538,16 @@ 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;
       if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
        DECL_IN_SYSTEM_HEADER (t) = in_system_header;
-      /* We have not yet computed the alias set for this declaration.  */
-      DECL_POINTER_ALIAS_SET (t) = -1;
+      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++;
 
@@ -765,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))
        {
@@ -952,13 +1013,16 @@ 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;
 
-  return build_constructor (type, v);
+  t = build_constructor (type, v);
+  TREE_CONSTANT (t) = TREE_CONSTANT (value);
+  return t;
 }
 
 
@@ -967,8 +1031,9 @@ build_constructor_single (tree type, tree index, tree value)
 tree
 build_constructor_from_list (tree type, tree vals)
 {
-  tree t;
+  tree t, val;
   VEC(constructor_elt,gc) *v = NULL;
+  bool constant_p = true;
 
   if (vals)
     {
@@ -976,12 +1041,17 @@ build_constructor_from_list (tree type, tree 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 = TREE_VALUE (t);
+         elt->value = val;
+         if (!TREE_CONSTANT (val))
+           constant_p = false;
        }
     }
 
-  return build_constructor (type, v);
+  t = build_constructor (type, v);
+  TREE_CONSTANT (t) = constant_p;
+  return t;
 }
 
 
@@ -1050,8 +1120,9 @@ build_string (int len, const char *str)
 {
   tree s;
   size_t length;
-  
-  length = len + sizeof (struct tree_string);
+
+  /* Do not waste bytes provided by padding of struct tree_string.  */
+  length = len + offsetof (struct tree_string, str) + 1;
 
 #ifdef GATHER_STATISTICS
   tree_node_counts[(int) c_kind]++;
@@ -1090,6 +1161,47 @@ build_complex (tree type, tree real, tree imag)
   return t;
 }
 
+/* Return a constant of arithmetic type TYPE which is the
+   multiplicative identity of the set TYPE.  */
+
+tree
+build_one_cst (tree type)
+{
+  switch (TREE_CODE (type))
+    {
+    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
+    case POINTER_TYPE: case REFERENCE_TYPE:
+    case OFFSET_TYPE:
+      return build_int_cst (type, 1);
+
+    case REAL_TYPE:
+      return build_real (type, dconst1);
+
+    case VECTOR_TYPE:
+      {
+       tree scalar, cst;
+       int i;
+
+       scalar = build_one_cst (TREE_TYPE (type));
+
+       /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
+       cst = NULL_TREE;
+       for (i = TYPE_VECTOR_SUBPARTS (type); --i >= 0; )
+         cst = tree_cons (NULL_TREE, scalar, cst);
+
+       return build_vector (type, cst);
+      }
+
+    case COMPLEX_TYPE:
+      return build_complex (type,
+                           build_one_cst (TREE_TYPE (type)),
+                           fold_convert (TREE_TYPE (type), integer_zero_node));
+
+    default:
+      gcc_unreachable ();
+    }
+}
+
 /* Build a BINFO with LEN language slots.  */
 
 tree
@@ -1148,7 +1260,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
@@ -1165,7 +1276,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
@@ -1189,14 +1299,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.  */
@@ -1240,7 +1351,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))
@@ -1278,7 +1389,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
@@ -1371,7 +1481,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))
@@ -1386,7 +1495,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))
@@ -1401,7 +1509,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))
@@ -1416,7 +1523,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))
@@ -1662,7 +1768,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)
@@ -1670,6 +1775,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.  */
@@ -1797,7 +1935,7 @@ staticp (tree arg)
     case VAR_DECL:
       return ((TREE_STATIC (arg) || DECL_EXTERNAL (arg))
              && ! DECL_THREAD_LOCAL_P (arg)
-             && ! DECL_NON_ADDR_CONST_P (arg)
+             && ! DECL_DLLIMPORT_P (arg)
              ? arg : NULL);
 
     case CONST_DECL:
@@ -1979,6 +2117,10 @@ tree_node_structure (tree t)
            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;
          }
@@ -2016,6 +2158,7 @@ tree_node_structure (tree t)
     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 ();
@@ -2114,7 +2257,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:
@@ -2602,7 +2744,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;
@@ -2691,9 +2833,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)
@@ -2779,15 +2919,15 @@ 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:
-      if (TREE_CODE_CLASS (code) == tcc_unary
+      if ((TREE_CODE_CLASS (code) == tcc_unary || code == VIEW_CONVERT_EXPR)
          && node && !TYPE_P (node)
          && TREE_CONSTANT (node))
        TREE_CONSTANT (t) = 1;
-      if (TREE_CODE_CLASS (code) == tcc_unary
+      if ((TREE_CODE_CLASS (code) == tcc_unary || code == VIEW_CONVERT_EXPR)
          && node && TREE_INVARIANT (node))
        TREE_INVARIANT (t) = 1;
       if (TREE_CODE_CLASS (code) == tcc_reference
@@ -2927,14 +3067,13 @@ build4_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
 }
 
 tree
-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)
+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 (code == TARGET_MEM_REF);
+  gcc_assert (TREE_CODE_LENGTH (code) == 5);
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
@@ -2946,66 +3085,40 @@ build7_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   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;
+  TREE_THIS_VOLATILE (t)
+    = (TREE_CODE_CLASS (code) == tcc_reference
+       && arg0 && TREE_THIS_VOLATILE (arg0));
 
   return t;
 }
 
-/* Backup definition for non-gcc build compilers.  */
-
 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, arg4, arg5, arg6;
-  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;
-    case 7:
-      arg0 = va_arg (p, tree);
-      arg1 = va_arg (p, tree);
-      arg2 = va_arg (p, tree);
-      arg3 = va_arg (p, tree);
-      arg4 = va_arg (p, tree);
-      arg5 = va_arg (p, tree);
-      arg6 = va_arg (p, tree);
-      t = build7 (code, tt, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
-      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;
 }
@@ -3061,14 +3174,6 @@ build_decl_stat (enum tree_code code, tree name, tree type MEM_STAT_DECL)
   else if (code == FUNCTION_DECL)
     DECL_MODE (t) = FUNCTION_MODE;
 
-  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;
 }
 
@@ -3107,7 +3212,7 @@ build_block (tree vars, tree subblocks, tree supercontext, tree chain)
 
 #if 1 /* ! defined(USE_MAPPED_LOCATION) */
 /* ??? gengtype doesn't handle conditionals */
-static GTY(()) location_t *last_annotated_node;
+static GTY(()) source_locus last_annotated_node;
 #endif
 
 #ifdef USE_MAPPED_LOCATION
@@ -3344,7 +3449,6 @@ is_attribute_with_length_p (const char *attr, int attr_len, tree ident)
       gcc_assert (attr[1] == '_');
       gcc_assert (attr[attr_len - 2] == '_');
       gcc_assert (attr[attr_len - 1] == '_');
-      gcc_assert (attr[1] == '_');
       if (ident_len == attr_len - 4
          && strncmp (attr + 2, p, attr_len - 4) == 0)
        return 1;
@@ -3394,6 +3498,28 @@ lookup_attribute (const char *attr_name, tree list)
   return NULL_TREE;
 }
 
+/* Remove any instances of attribute ATTR_NAME in LIST and return the
+   modified list.  */
+
+tree
+remove_attribute (const char *attr_name, tree list)
+{
+  tree *p;
+  size_t attr_len = strlen (attr_name);
+
+  for (p = &list; *p; )
+    {
+      tree l = *p;
+      gcc_assert (TREE_CODE (TREE_PURPOSE (l)) == IDENTIFIER_NODE);
+      if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l)))
+       *p = TREE_CHAIN (l);
+      else
+       p = &TREE_CHAIN (l);
+    }
+
+  return list;
+}
+
 /* Return an attribute list that is the union of a1 and a2.  */
 
 tree
@@ -3428,7 +3554,17 @@ merge_attributes (tree a1, tree a2)
                   a = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)),
                                         TREE_CHAIN (a)))
                {
-                 if (simple_cst_equal (TREE_VALUE (a), TREE_VALUE (a2)) == 1)
+                 if (TREE_VALUE (a) != NULL
+                     && TREE_CODE (TREE_VALUE (a)) == TREE_LIST
+                     && TREE_VALUE (a2) != NULL
+                     && TREE_CODE (TREE_VALUE (a2)) == TREE_LIST)
+                   {
+                     if (simple_cst_list_equal (TREE_VALUE (a),
+                                                TREE_VALUE (a2)) == 1)
+                       break;
+                   }
+                 else if (simple_cst_equal (TREE_VALUE (a),
+                                            TREE_VALUE (a2)) == 1)
                    break;
                }
              if (a == NULL_TREE)
@@ -3478,31 +3614,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);
@@ -3545,22 +3716,39 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
       return NULL_TREE;
     }
 
+  if (TREE_CODE (node) != FUNCTION_DECL
+      && TREE_CODE (node) != VAR_DECL)
+    {
+      *no_add_attrs = true;
+      warning (OPT_Wattributes, "%qs attribute ignored",
+              IDENTIFIER_POINTER (name));
+      return NULL_TREE;
+    }
+
   /* Report error on dllimport ambiguities seen now before they cause
      any damage.  */
-  if (is_attribute_p ("dllimport", name))
+  else 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 ("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))
            {
@@ -3577,6 +3765,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.  */
@@ -3976,7 +4167,6 @@ type_hash_eq (const void *va, const void *vb)
     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)))
@@ -4194,15 +4384,21 @@ attribute_list_contained (tree l1, tree l2)
           attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)),
                                    TREE_CHAIN (attr)))
        {
-         if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) == 1)
+         if (TREE_VALUE (t2) != NULL
+             && TREE_CODE (TREE_VALUE (t2)) == TREE_LIST
+             && TREE_VALUE (attr) != NULL
+             && TREE_CODE (TREE_VALUE (attr)) == TREE_LIST)
+           {
+             if (simple_cst_list_equal (TREE_VALUE (t2),
+                                        TREE_VALUE (attr)) == 1)
+               break;
+           }
+         else if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) == 1)
            break;
        }
 
       if (attr == 0)
        return 0;
-
-      if (simple_cst_equal (TREE_VALUE (t2), TREE_VALUE (attr)) != 1)
-       return 0;
     }
 
   return 1;
@@ -4321,7 +4517,6 @@ 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
@@ -4360,7 +4555,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)
@@ -4695,8 +4890,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
        {
@@ -4926,9 +5121,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)
@@ -4939,8 +5133,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);
@@ -4988,7 +5182,11 @@ build_array_type (tree elt_type, tree index_type)
   
   if (index_type == 0)
     {
-      layout_type (t);
+      tree save = t;
+      hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
+      t = type_hash_canon (hashcode, t);
+      if (save == t)
+       layout_type (t);
       return t;
     }
 
@@ -5494,8 +5692,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.  */
@@ -5527,8 +5728,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
@@ -5554,19 +5757,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;
@@ -5574,23 +5772,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));
@@ -5600,7 +5791,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.  */
@@ -5616,6 +5807,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;
     }
@@ -5717,6 +5915,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);
@@ -5837,7 +6038,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
@@ -5982,6 +6202,103 @@ tree_class_check_failed (const tree node, const enum tree_code_class 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, 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,
 
@@ -6044,6 +6361,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,
@@ -6127,7 +6458,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.  */
@@ -6135,6 +6468,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);
@@ -6229,6 +6563,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);
@@ -6361,6 +6714,26 @@ build_common_builtin_nodes (void)
                        "__builtin_nonlocal_goto",
                        ECF_NORETURN | ECF_NOTHROW);
 
+  tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
+  tmp = tree_cons (NULL_TREE, ptr_type_node, tmp);
+  ftype = build_function_type (void_type_node, tmp);
+  local_define_builtin ("__builtin_setjmp_setup", ftype,
+                       BUILT_IN_SETJMP_SETUP,
+                       "__builtin_setjmp_setup", ECF_NOTHROW);
+
+  tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
+  ftype = build_function_type (ptr_type_node, tmp);
+  local_define_builtin ("__builtin_setjmp_dispatcher", ftype,
+                       BUILT_IN_SETJMP_DISPATCHER,
+                       "__builtin_setjmp_dispatcher",
+                       ECF_PURE | ECF_NOTHROW);
+
+  tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
+  ftype = build_function_type (void_type_node, tmp);
+  local_define_builtin ("__builtin_setjmp_receiver", ftype,
+                       BUILT_IN_SETJMP_RECEIVER,
+                       "__builtin_setjmp_receiver", ECF_NOTHROW);
+
   ftype = build_function_type (ptr_type_node, void_list_node);
   local_define_builtin ("__builtin_stack_save", ftype, BUILT_IN_STACK_SAVE,
                        "__builtin_stack_save", ECF_NOTHROW);
@@ -6568,16 +6941,6 @@ initializer_zerop (tree init)
     }
 }
 
-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
@@ -6587,6 +6950,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.  */
@@ -6615,12 +7003,48 @@ in_array_bounds_p (tree ref)
   return true;
 }
 
+/* Returns true if it is possible to prove that the range of
+   an array access REF (an ARRAY_RANGE_REF expression) falls
+   into the array bounds.  */
+
+bool
+range_in_array_bounds_p (tree ref)
+{
+  tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
+  tree range_min, range_max, min, max;
+
+  range_min = TYPE_MIN_VALUE (domain_type);
+  range_max = TYPE_MAX_VALUE (domain_type);
+  if (!range_min
+      || !range_max
+      || TREE_CODE (range_min) != INTEGER_CST
+      || TREE_CODE (range_max) != INTEGER_CST)
+    return false;
+
+  min = array_ref_low_bound (ref);
+  max = array_ref_up_bound (ref);
+  if (!min
+      || !max
+      || TREE_CODE (min) != INTEGER_CST
+      || TREE_CODE (max) != INTEGER_CST)
+    return false;
+
+  if (tree_int_cst_lt (range_min, min)
+      || tree_int_cst_lt (max, range_max))
+    return false;
+
+  return true;
+}
+
 /* Return true if T (assumed to be a DECL) is a global variable.  */
 
 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
@@ -6718,11 +7142,11 @@ tree_fold_gcd (tree a, tree b)
 
   if (tree_int_cst_sgn (a) == -1)
     a = fold_build2 (MULT_EXPR, type, a,
-                    convert (type, integer_minus_one_node));
+                    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));
+                    build_int_cst (type, -1));
 
   while (1)
     {
@@ -6742,6 +7166,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);
 }
 
@@ -6750,6 +7176,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);
 }
 
@@ -6994,7 +7422,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));
@@ -7057,9 +7484,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;
     }
@@ -7069,190 +7498,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 these 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:
-         {
-           unsigned HOST_WIDE_INT idx;
-           constructor_elt *ce;
+    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));
+      }
 
-           for (idx = 0;
-                VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (*tp), idx, ce);
-                idx++)
-             WALK_SUBTREE (ce->value);
-         }
-         break;
+    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 SAVE_EXPR:
-         WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+        ??? 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 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));
-         }
+         /* 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 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;
+         result = walk_type_fields (*type_p, func, data, pset);
+         if (result)
+           return result;
 
-       default:
-         /* ??? This could be a language-defined node.  We really should make
-            a hook for it, but right now just ignore it.  */
-         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;
+
+             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.  */
@@ -7276,4 +7722,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"