OSDN Git Service

* toplev.c (rest_of_compilation): Avoid cfg_cleanup calls when not
[pf3gnuchains/gcc-fork.git] / gcc / c-common.c
index bdf47c4..1a20b47 100644 (file)
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "real.h"
 #include "flags.h"
@@ -29,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "c-pragma.h"
 #include "rtl.h"
 #include "ggc.h"
+#include "varray.h"
 #include "expr.h"
 #include "c-common.h"
 #include "diagnostic.h"
@@ -38,6 +41,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "langhooks.h"
 #include "except.h"            /* For USING_SJLJ_EXCEPTIONS.  */
+#include "tree-inline.h"
 
 cpp_reader *parse_in;          /* Declared in c-pragma.h.  */
 
@@ -83,10 +87,6 @@ cpp_reader *parse_in;                /* Declared in c-pragma.h.  */
                        : "long long unsigned int"))
 #endif
 
-#ifndef STDC_0_IN_SYSTEM_HEADERS
-#define STDC_0_IN_SYSTEM_HEADERS 0
-#endif
-
 #ifndef REGISTER_PREFIX
 #define REGISTER_PREFIX ""
 #endif
@@ -191,11 +191,20 @@ enum c_language_kind c_language;
 
 tree c_global_trees[CTI_MAX];
 
+/* Nonzero if we can read a PCH file now.  */
+
+int allow_pch = 1;
+\f
 /* Switches common to the C front ends.  */
 
 /* Nonzero if prepreprocessing only.  */
 int flag_preprocess_only;
 
+/* The file name to which we should write a precompiled header, or
+   NULL if no header will be written in this compile.  */
+
+const char *pch_file;
+
 /* Nonzero if an ISO standard was selected.  It rejects macros in the
    user's namespace.  */
 int flag_iso;
@@ -294,7 +303,7 @@ int warn_write_strings;
 
 int warn_redundant_decls;
 
-/* Warn about testing equality of floating point numbers. */
+/* Warn about testing equality of floating point numbers.  */
 
 int warn_float_equal;
 
@@ -306,14 +315,10 @@ int warn_char_subscripts;
 
 int warn_conversion;
 
-/* Warn about #pragma directives that are not recognised.  */      
+/* Warn about #pragma directives that are not recognized.  */      
 
 int warn_unknown_pragmas; /* Tri state variable.  */  
 
-/* Nonzero means warn about use of multicharacter literals.  */
-
-int warn_multichar = 1;
-
 /* Warn about format/argument anomalies in calls to formatted I/O functions
    (*printf, *scanf, strftime, strfmon, etc.).  */
 
@@ -446,10 +451,18 @@ int print_struct_values;
 const char *constant_string_class_name;
 
 /* Warn if multiple methods are seen for the same selector, but with
-   different argument types.  */
+   different argument types.  Performs the check on the whole selector
+   table at the end of compilation.  */
 
 int warn_selector;
 
+/* Warn if a @selector() is found, and no method with that selector
+   has been previously declared.  The check is done on each
+   @selector() as soon as it is found - so it warns about forward
+   declarations.  */
+
+int warn_undeclared_selector;
+
 /* Warn if methods required by a protocol are not implemented in the 
    class adopting it.  When turned off, methods inherited to that
    class are also considered implemented.  */
@@ -566,6 +579,26 @@ int flag_permissive;
 
 int flag_enforce_eh_specs = 1;
 
+/*  The version of the C++ ABI in use.  The following values are
+    allowed:
+
+    0: The version of the ABI believed most conformant with the 
+       C++ ABI specification.  This ABI may change as bugs are
+       discovered and fixed.  Therefore, 0 will not necessarily
+       indicate the same ABI in different versions of G++.
+
+    1: The version of the ABI first used in G++ 3.2.
+
+    Additional positive integers will be assigned as new versions of
+    the ABI become the default version of the ABI.  */
+
+int flag_abi_version = 1;
+
+/* Nonzero means warn about things that will change when compiling
+   with an ABI-compliant compiler.  */
+
+int warn_abi = 0;
+
 /* Nonzero means warn about implicit declarations.  */
 
 int warn_implicit = 1;
@@ -575,26 +608,26 @@ int warn_implicit = 1;
 
 int warn_ctor_dtor_privacy = 1;
 
-/* Non-zero means warn in function declared in derived class has the
+/* Nonzero means warn in function declared in derived class has the
    same name as a virtual in the base class, but fails to match the
    type signature of any virtual function in the base class.  */
 
 int warn_overloaded_virtual;
 
-/* Non-zero means warn when declaring a class that has a non virtual
+/* Nonzero means warn when declaring a class that has a non virtual
    destructor, when it really ought to have a virtual one.  */
 
 int warn_nonvdtor;
 
-/* Non-zero means warn when the compiler will reorder code.  */
+/* Nonzero means warn when the compiler will reorder code.  */
 
 int warn_reorder;
 
-/* Non-zero means warn when synthesis behavior differs from Cfront's.  */
+/* Nonzero means warn when synthesis behavior differs from Cfront's.  */
 
 int warn_synth;
 
-/* Non-zero means warn when we convert a pointer to member function
+/* Nonzero means warn when we convert a pointer to member function
    into a pointer to (void or function).  */
 
 int warn_pmf2ptr = 1;
@@ -692,8 +725,6 @@ static int if_stack_space = 0;
 /* Stack pointer.  */
 static int if_stack_pointer = 0;
 
-static void cb_register_builtins PARAMS ((cpp_reader *));
-
 static tree handle_packed_attribute    PARAMS ((tree *, tree, tree, int,
                                                 bool *));
 static tree handle_nocommon_attribute  PARAMS ((tree *, tree, tree, int,
@@ -730,6 +761,8 @@ static tree handle_alias_attribute  PARAMS ((tree *, tree, tree, int,
                                                 bool *));
 static tree handle_visibility_attribute        PARAMS ((tree *, tree, tree, int,
                                                 bool *));
+static tree handle_tls_model_attribute PARAMS ((tree *, tree, tree, int,
+                                                bool *));
 static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
                                                             tree, int,
                                                             bool *));
@@ -757,8 +790,16 @@ static bool get_nonnull_operand            PARAMS ((tree,
                                                 unsigned HOST_WIDE_INT *));
 void builtin_define_std PARAMS ((const char *));
 static void builtin_define_with_value PARAMS ((const char *, const char *,
-                                              int));
+                                               int));
+static void builtin_define_with_int_value PARAMS ((const char *,
+                                                  HOST_WIDE_INT));
+static void builtin_define_with_hex_fp_value PARAMS ((const char *, tree,
+                                                     int, const char *,
+                                                     const char *));
 static void builtin_define_type_max PARAMS ((const char *, tree, int));
+static void builtin_define_type_precision PARAMS ((const char *, tree));
+static void builtin_define_float_constants PARAMS ((const char *,
+                                                   const char *, tree));
 
 /* Table of machine-independent attributes common to all C-like languages.  */
 const struct attribute_spec c_common_attribute_table[] =
@@ -820,6 +861,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_vector_size_attribute },
   { "visibility",            1, 1, true,  false, false,
                              handle_visibility_attribute },
+  { "tls_model",             1, 1, true,  false, false,
+                             handle_tls_model_attribute },
   { "nonnull",                0, -1, false, true, true,
                              handle_nonnull_attribute },
   { "nothrow",                0, 0, true,  false, false,
@@ -829,7 +872,7 @@ const struct attribute_spec c_common_attribute_table[] =
 };
 
 /* Give the specifications for the format attributes, used by C and all
-   descendents.  */
+   descendants.  */
 
 const struct attribute_spec c_common_format_attribute_table[] =
 {
@@ -1017,13 +1060,18 @@ finish_fname_decls ()
   
   if (body)
     {
-      /* They were called into existence, so add to statement tree.  */
-      body = chainon (body,
-                     TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
-      body = build_stmt (COMPOUND_STMT, body);
-      
-      COMPOUND_STMT_NO_SCOPE (body) = 1;
-      TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body;
+      /* They were called into existence, so add to statement tree.  Add
+        the DECL_STMTs inside the outermost scope.  */
+      tree *p = &DECL_SAVED_TREE (current_function_decl);
+      /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK.  */
+      while (TREE_CODE (*p) != COMPOUND_STMT)
+       p = &TREE_CHAIN (*p);
+      p = &COMPOUND_BODY (*p);
+      if (TREE_CODE (*p) == SCOPE_STMT)
+       p = &TREE_CHAIN (*p);
+
+      body = chainon (body, *p);
+      *p = body;
     }
   
   for (ix = 0; fname_vars[ix].decl; ix++)
@@ -1046,7 +1094,7 @@ finish_fname_decls ()
   saved_function_name_decls = stack;
 }
 
-/* Return the text name of the current function, suitable prettified
+/* Return the text name of the current function, suitably prettified
    by PRETTY_P.  */
 
 const char *
@@ -1108,7 +1156,7 @@ fname_decl (rid, id)
         the current statement.  Later this tree will be moved to the
         beginning of the function and this line number will be wrong.
         To avoid this problem set the lineno to 0 here; that prevents
-        it from appearing in the RTL. */
+        it from appearing in the RTL.  */
       int saved_lineno = lineno;
       lineno = 0;
       
@@ -1130,7 +1178,7 @@ fname_decl (rid, id)
     }
   if (!ix && !current_function_decl)
     pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
-  
+
   return decl;
 }
 
@@ -1813,7 +1861,7 @@ verify_tree (x, pbefore_sp, pno_sp, writer)
     }
 }
 
-/* Try to warn for undefined behaviour in EXPR due to missing sequence
+/* Try to warn for undefined behavior in EXPR due to missing sequence
    points.  */
 
 static void
@@ -2012,10 +2060,14 @@ c_common_type_for_mode (mode, unsignedp)
       return unsignedp ? unsigned_V2DI_type_node : V2DI_type_node;
     case V2SImode:
       return unsignedp ? unsigned_V2SI_type_node : V2SI_type_node;
+    case V2HImode:
+      return unsignedp ? unsigned_V2HI_type_node : V2HI_type_node;
     case V4HImode:
       return unsignedp ? unsigned_V4HI_type_node : V4HI_type_node;
     case V8QImode:
       return unsignedp ? unsigned_V8QI_type_node : V8QI_type_node;
+    case V1DImode:
+      return unsignedp ? unsigned_V1DI_type_node : V1DI_type_node;
     case V16SFmode:
       return V16SF_type_node;
     case V4SFmode:
@@ -2765,12 +2817,13 @@ c_common_truthvalue_conversion (expr)
     case ABS_EXPR:
     case FLOAT_EXPR:
     case FFS_EXPR:
-      /* These don't change whether an object is non-zero or zero.  */
+    case POPCOUNT_EXPR:
+      /* These don't change whether an object is nonzero or zero.  */
       return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
 
     case LROTATE_EXPR:
     case RROTATE_EXPR:
-      /* These don't change whether an object is zero or non-zero, but
+      /* These don't change whether an object is zero or nonzero, but
         we can't ignore them if their second arg has side-effects.  */
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)))
        return build (COMPOUND_EXPR, boolean_type_node, TREE_OPERAND (expr, 1),
@@ -2942,7 +2995,7 @@ c_common_get_alias_set (t)
   if (! TYPE_P (t))
     return -1;
 
-  /* The C standard guarantess that any object may be accessed via an
+  /* The C standard guarantees that any object may be accessed via an
      lvalue that has character type.  */
   if (t == char_type_node
       || t == signed_char_type_node
@@ -3055,7 +3108,7 @@ c_sizeof_or_alignof_type (type, op, complain)
      TYPE_IS_SIZETYPE means that certain things (like overflow) will
      never happen.  However, this node should really have type
      `size_t', which is just a typedef for an ordinary integer type.  */
-  value = fold (build1 (NOP_EXPR, c_size_type_node, value));
+  value = fold (build1 (NOP_EXPR, size_type_node, value));
   my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)), 20001021);
   
   return value;
@@ -3106,7 +3159,7 @@ c_alignof_expr (expr)
   else
     return c_alignof (TREE_TYPE (expr));
 
-  return fold (build1 (NOP_EXPR, c_size_type_node, t));
+  return fold (build1 (NOP_EXPR, size_type_node, t));
 }
 \f
 /* Handle C and C++ default attributes.  */
@@ -3150,6 +3203,7 @@ c_common_nodes_and_builtins ()
 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
+#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
 #include "builtin-types.def"
 #undef DEF_PRIMITIVE_TYPE
@@ -3161,6 +3215,7 @@ c_common_nodes_and_builtins ()
 #undef DEF_FUNCTION_TYPE_VAR_0
 #undef DEF_FUNCTION_TYPE_VAR_1
 #undef DEF_FUNCTION_TYPE_VAR_2
+#undef DEF_FUNCTION_TYPE_VAR_3
 #undef DEF_POINTER_TYPE
     BT_LAST
   };
@@ -3249,10 +3304,10 @@ c_common_nodes_and_builtins ()
   /* `unsigned long' is the standard type for sizeof.
      Note that stddef.h uses `unsigned long',
      and this must agree, even if long and int are the same size.  */
-  c_size_type_node =
+  size_type_node =
     TREE_TYPE (identifier_global_value (get_identifier (SIZE_TYPE)));
-  signed_size_type_node = c_common_signed_type (c_size_type_node);
-  set_sizetype (c_size_type_node);
+  signed_size_type_node = c_common_signed_type (size_type_node);
+  set_sizetype (size_type_node);
 
   build_common_tree_nodes_2 (flag_short_double);
 
@@ -3480,6 +3535,19 @@ c_common_nodes_and_builtins ()
                  tree_cons (NULL_TREE,                         \
                             builtin_types[(int) ARG2],         \
                             NULL_TREE)));
+
+#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3)                \
+   builtin_types[(int) ENUM]                                           \
+    = build_function_type                                              \
+      (builtin_types[(int) RETURN],                                    \
+       tree_cons (NULL_TREE,                                           \
+                 builtin_types[(int) ARG1],                            \
+                 tree_cons (NULL_TREE,                                 \
+                            builtin_types[(int) ARG2],                 \
+                            tree_cons (NULL_TREE,                      \
+                                       builtin_types[(int) ARG3],      \
+                                       NULL_TREE))));
+
 #define DEF_POINTER_TYPE(ENUM, TYPE)                   \
   builtin_types[(int) ENUM]                            \
     = build_pointer_type (builtin_types[(int) TYPE]);
@@ -3491,13 +3559,15 @@ c_common_nodes_and_builtins ()
 #undef DEF_FUNCTION_TYPE_4
 #undef DEF_FUNCTION_TYPE_VAR_0
 #undef DEF_FUNCTION_TYPE_VAR_1
+#undef DEF_FUNCTION_TYPE_VAR_2
+#undef DEF_FUNCTION_TYPE_VAR_3
 #undef DEF_POINTER_TYPE
 
   if (!c_attrs_initialized)
     c_init_attributes ();
 
 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,                  \
-                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS)               \
+                   BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)     \
   if (NAME)                                                            \
     {                                                                  \
       tree decl;                                                       \
@@ -3524,6 +3594,8 @@ c_common_nodes_and_builtins ()
                                   built_in_attributes[(int) ATTRS]);   \
                                                                        \
       built_in_decls[(int) ENUM] = decl;                               \
+      if (IMPLICIT)                                                    \
+        implicit_built_in_decls[(int) ENUM] = decl;                    \
     }                                                                  
 #include "builtins.def"
 #undef DEF_BUILTIN
@@ -3853,7 +3925,7 @@ expand_tree_builtin (function, params, coerced_params)
   return NULL_TREE;
 }
 
-/* Returns non-zero if CODE is the code for a statement.  */
+/* Returns nonzero if CODE is the code for a statement.  */
 
 int
 statement_code_p (code)
@@ -4455,9 +4527,9 @@ c_expand_builtin_printf (arglist, target, tmode, modifier, ignore, unlocked)
      int unlocked;
 {
   tree fn_putchar = unlocked ?
-    built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : built_in_decls[BUILT_IN_PUTCHAR];
+    implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTCHAR];
   tree fn_puts = unlocked ?
-    built_in_decls[BUILT_IN_PUTS_UNLOCKED] : built_in_decls[BUILT_IN_PUTS];
+    implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTS];
   tree fn, format_arg, stripped_string;
 
   /* If the return value is used, or the replacement _DECL isn't
@@ -4559,9 +4631,9 @@ c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore, unlocked)
      int unlocked;
 {
   tree fn_fputc = unlocked ?
-    built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : built_in_decls[BUILT_IN_FPUTC];
+    implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTC];
   tree fn_fputs = unlocked ?
-    built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : built_in_decls[BUILT_IN_FPUTS];
+    implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTS];
   tree fn, format_arg, stripped_string;
 
   /* If the return value is used, or the replacement _DECL isn't
@@ -4671,8 +4743,193 @@ boolean_increment (code, arg)
   return val;
 }
 \f
-/* Hook that registers front end and target-specific built-ins.  */
+/* Define NAME with value TYPE precision.  */
+static void
+builtin_define_type_precision (name, type)
+     const char *name;
+     tree type;
+{
+  builtin_define_with_int_value (name, TYPE_PRECISION (type));
+}
+
+/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX.  */
 static void
+builtin_define_float_constants (name_prefix, fp_suffix, type)
+     const char *name_prefix;
+     const char *fp_suffix;
+     tree type;
+{
+  /* Used to convert radix-based values to base 10 values in several cases.
+
+     In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
+     least 6 significant digits for correct results.  Using the fraction
+     formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an
+     intermediate; perhaps someone can find a better approximation, in the
+     mean time, I suspect using doubles won't harm the bootstrap here.  */
+
+  const double log10_2 = .30102999566398119521;
+  double log10_b;
+  const struct real_format *fmt;
+
+  char name[64], buf[128];
+  int dig, min_10_exp, max_10_exp;
+  int decimal_dig;
+
+  fmt = real_format_for_mode[TYPE_MODE (type) - QFmode];
+
+  /* The radix of the exponent representation.  */
+  if (type == float_type_node)
+    builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
+  log10_b = log10_2 * fmt->log2_b;
+
+  /* The number of radix digits, p, in the floating-point significand.  */
+  sprintf (name, "__%s_MANT_DIG__", name_prefix);
+  builtin_define_with_int_value (name, fmt->p);
+
+  /* The number of decimal digits, q, such that any floating-point number
+     with q decimal digits can be rounded into a floating-point number with
+     p radix b digits and back again without change to the q decimal digits,
+
+       p log10 b                       if b is a power of 10
+       floor((p - 1) log10 b)          otherwise
+  */
+  dig = (fmt->p - 1) * log10_b;
+  sprintf (name, "__%s_DIG__", name_prefix);
+  builtin_define_with_int_value (name, dig);
+
+  /* The minimum negative int x such that b**(x-1) is a normalized float.  */
+  sprintf (name, "__%s_MIN_EXP__", name_prefix);
+  sprintf (buf, "(%d)", fmt->emin);
+  builtin_define_with_value (name, buf, 0);
+
+  /* The minimum negative int x such that 10**x is a normalized float,
+
+         ceil (log10 (b ** (emin - 1)))
+       = ceil (log10 (b) * (emin - 1))
+
+     Recall that emin is negative, so the integer truncation calculates
+     the ceiling, not the floor, in this case.  */
+  min_10_exp = (fmt->emin - 1) * log10_b;
+  sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
+  sprintf (buf, "(%d)", min_10_exp);
+  builtin_define_with_value (name, buf, 0);
+
+  /* The maximum int x such that b**(x-1) is a representable float.  */
+  sprintf (name, "__%s_MAX_EXP__", name_prefix);
+  builtin_define_with_int_value (name, fmt->emax);
+
+  /* The maximum int x such that 10**x is in the range of representable
+     finite floating-point numbers,
+
+         floor (log10((1 - b**-p) * b**emax))
+       = floor (log10(1 - b**-p) + log10(b**emax))
+       = floor (log10(1 - b**-p) + log10(b)*emax)
+
+     The safest thing to do here is to just compute this number.  But since
+     we don't link cc1 with libm, we cannot.  We could implement log10 here
+     a series expansion, but that seems too much effort because:
+
+     Note that the first term, for all extant p, is a number exceedingly close
+     to zero, but slightly negative.  Note that the second term is an integer
+     scaling an irrational number, and that because of the floor we are only
+     interested in its integral portion.
+
+     In order for the first term to have any effect on the integral portion
+     of the second term, the second term has to be exceedingly close to an
+     integer itself (e.g. 123.000000000001 or something).  Getting a result
+     that close to an integer requires that the irrational multiplicand have
+     a long series of zeros in its expansion, which doesn't occur in the
+     first 20 digits or so of log10(b).
+
+     Hand-waving aside, crunching all of the sets of constants above by hand
+     does not yield a case for which the first term is significant, which
+     in the end is all that matters.  */
+  max_10_exp = fmt->emax * log10_b;
+  sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
+  builtin_define_with_int_value (name, max_10_exp);
+
+  /* The number of decimal digits, n, such that any floating-point number
+     can be rounded to n decimal digits and back again without change to
+     the value. 
+
+       p * log10(b)                    if b is a power of 10
+       ceil(1 + p * log10(b))          otherwise
+
+     The only macro we care about is this number for the widest supported
+     floating type, but we want this value for rendering constants below.  */
+  {
+    double d_decimal_dig = 1 + fmt->p * log10_b;
+    decimal_dig = d_decimal_dig;
+    if (decimal_dig < d_decimal_dig)
+      decimal_dig++;
+  }
+  if (type == long_double_type_node)
+    builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
+
+  /* Since, for the supported formats, B is always a power of 2, we
+     construct the following numbers directly as a hexadecimal
+     constants.  */
+
+  /* The maximum representable finite floating-point number,
+     (1 - b**-p) * b**emax  */
+  {
+    int i, n;
+    char *p;
+
+    strcpy (buf, "0x0.");
+    n = fmt->p * fmt->log2_b;
+    for (i = 0, p = buf + 4; i + 3 < n; i += 4)
+      *p++ = 'f';
+    if (i < n)
+      *p++ = "08ce"[n - i];
+    sprintf (p, "p%d", fmt->emax * fmt->log2_b);
+  }
+  sprintf (name, "__%s_MAX__", name_prefix);
+  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+
+  /* The minimum normalized positive floating-point number,
+     b**(emin-1).  */
+  sprintf (name, "__%s_MIN__", name_prefix);
+  sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
+  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+
+  /* The difference between 1 and the least value greater than 1 that is
+     representable in the given floating point type, b**(1-p).  */
+  sprintf (name, "__%s_EPSILON__", name_prefix);
+  sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
+  builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+
+  /* For C++ std::numeric_limits<T>::denorm_min.  The minimum denormalized
+     positive floating-point number, b**(emin-p).  Zero for formats that
+     don't support denormals.  */
+  sprintf (name, "__%s_DENORM_MIN__", name_prefix);
+  if (fmt->has_denorm)
+    {
+      sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
+      builtin_define_with_hex_fp_value (name, type, decimal_dig,
+                                       buf, fp_suffix);
+    }
+  else
+    {
+      sprintf (buf, "0.0%s", fp_suffix);
+      builtin_define_with_value (name, buf, 0);
+    }
+
+  /* For C++ std::numeric_limits<T>::has_infinity.  */
+  sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
+  builtin_define_with_int_value (name, 
+                                MODE_HAS_INFINITIES (TYPE_MODE (type)));
+  /* For C++ std::numeric_limits<T>::has_quiet_NaN.  We do not have a
+     predicate to distinguish a target that has both quiet and
+     signalling NaNs from a target that has only quiet NaNs or only
+     signalling NaNs, so we assume that a target that has any kind of
+     NaN has quiet NaNs.  */
+  sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
+  builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
+}
+
+/* Hook that registers front end and target-specific built-ins.  */
+void
 cb_register_builtins (pfile)
      cpp_reader *pfile;
 {
@@ -4712,12 +4969,18 @@ cb_register_builtins (pfile)
   builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
   builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
   builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
+  builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
 
-  {
-    char buf[8];
-    sprintf (buf, "%d", (int) TYPE_PRECISION (signed_char_type_node));
-    builtin_define_with_value ("__CHAR_BIT__", buf, 0);
-  }
+  builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
+
+  /* float.h needs to know these.  */
+
+  builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
+                                TARGET_FLT_EVAL_METHOD);
+
+  builtin_define_float_constants ("FLT", "F", float_type_node);
+  builtin_define_float_constants ("DBL", "", double_type_node);
+  builtin_define_float_constants ("LDBL", "L", long_double_type_node);
 
   /* For use in assembly language.  */
   builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
@@ -4740,7 +5003,7 @@ cb_register_builtins (pfile)
 
   if (fast_math_flags_set_p ())
     cpp_define (pfile, "__FAST_MATH__");
-  if (flag_no_inline)
+  if (flag_really_no_inline)
     cpp_define (pfile, "__NO_INLINE__");
   if (flag_signaling_nans)
     cpp_define (pfile, "__SUPPORT_SNAN__");
@@ -4755,9 +5018,17 @@ cb_register_builtins (pfile)
   if (!flag_signed_char)
     cpp_define (pfile, "__CHAR_UNSIGNED__");
 
+  if (c_language == clk_cplusplus && TREE_UNSIGNED (wchar_type_node))
+    cpp_define (pfile, "__WCHAR_UNSIGNED__");
+
+  /* Make the choice of ObjC runtime visible to source code.  */
+  if (flag_objc && flag_next_runtime)
+    cpp_define (pfile, "__NEXT_RUNTIME__");
+
   /* A straightforward target hook doesn't work, because of problems
      linking that hook's body when part of non-C front ends.  */
 # define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
+# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
 # define builtin_define(TXT) cpp_define (pfile, TXT)
 # define builtin_assert(TXT) cpp_assert (pfile, TXT)
   TARGET_CPU_CPP_BUILTINS ();
@@ -4836,109 +5107,97 @@ builtin_define_with_value (macro, expansion, is_str)
   cpp_define (parse_in, buf);
 }
 
-/* Define MAX for TYPE based on the precision of the type, which is assumed
-   to be signed.  IS_LONG is 1 for type "long" and 2 for "long long".  */
-
+/* Pass an object-like macro and an integer value to define it to.  */
 static void
-builtin_define_type_max (macro, type, is_long)
+builtin_define_with_int_value (macro, value)
      const char *macro;
-     tree type;
-     int is_long;
+     HOST_WIDE_INT value;
 {
-  const char *value;
   char *buf;
-  size_t mlen, vlen, extra;
-
-  /* Pre-rendering the values mean we don't have to futz with printing a
-     multi-word decimal value.  There are also a very limited number of
-     precisions that we support, so it's really a waste of time.  */
-  switch (TYPE_PRECISION (type))
-    {
-    case 8:
-      value = "127";
-      break;
-    case 16:
-      value = "32767";
-      break;
-    case 32:
-      value = "2147483647";
-      break;
-    case 64:
-      value = "9223372036854775807";
-      break;
-    case 128:
-      value = "170141183460469231731687303715884105727";
-      break;
-    default:
-      abort ();
-    }
+  size_t mlen = strlen (macro);
+  size_t vlen = 18;
+  size_t extra = 2; /* space for = and NUL.  */
 
-  mlen = strlen (macro);
-  vlen = strlen (value);
-  extra = 2 + is_long;
   buf = alloca (mlen + vlen + extra);
-
-  sprintf (buf, "%s=%s%s", macro, value,
-          (is_long == 1 ? "L" : is_long == 2 ? "LL" : ""));
+  memcpy (buf, macro, mlen);
+  buf[mlen] = '=';
+  sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
 
   cpp_define (parse_in, buf);
 }
 
-/* Front end initialization common to C, ObjC and C++.  */
-const char *
-c_common_init (filename)
-     const char *filename;
+/* Pass an object-like macro a hexadecimal floating-point value.  */
+static void
+builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix)
+     const char *macro;
+     tree type ATTRIBUTE_UNUSED;
+     int digits;
+     const char *hex_str;
+     const char *fp_suffix;
 {
-  cpp_options *options = cpp_get_options (parse_in);
+  REAL_VALUE_TYPE real;
+  char dec_str[64], buf[256];
 
-  /* Set up preprocessor arithmetic.  Must be done after call to
-     c_common_nodes_and_builtins for wchar_type_node to be good.  */
-  options->precision = TYPE_PRECISION (intmax_type_node);
-  options->char_precision = TYPE_PRECISION (char_type_node);
-  options->int_precision = TYPE_PRECISION (integer_type_node);
-  options->wchar_precision = TYPE_PRECISION (wchar_type_node);
-  options->unsigned_wchar = TREE_UNSIGNED (wchar_type_node);
-  options->unsigned_char = !flag_signed_char;
-  options->warn_multichar = warn_multichar;
-  options->stdc_0_in_system_headers = STDC_0_IN_SYSTEM_HEADERS;
+  /* Hex values are really cool and convenient, except that they're
+     not supported in strict ISO C90 mode.  First, the "p-" sequence
+     is not valid as part of a preprocessor number.  Second, we get a
+     pedwarn from the preprocessor, which has no context, so we can't
+     suppress the warning with __extension__.
 
-  /* We want -Wno-long-long to override -pedantic -std=non-c99
-     and/or -Wtraditional, whatever the ordering.  */
-  options->warn_long_long
-    = warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
+     So instead what we do is construct the number in hex (because 
+     it's easy to get the exact correct value), parse it as a real,
+     then print it back out as decimal.  */
 
-  /* Register preprocessor built-ins before calls to
-     cpp_main_file.  */
-  cpp_get_callbacks (parse_in)->register_builtins = cb_register_builtins;
+  real_from_string (&real, hex_str);
+  real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
 
-  /* NULL is passed up to toplev.c and we exit quickly.  */
-  if (flag_preprocess_only)
-    {
-      cpp_preprocess_file (parse_in);
-      return NULL;
-    }
+  sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
+  cpp_define (parse_in, buf);
+}
 
-  /* Do this before initializing pragmas, as then cpplib's hash table
-     has been set up.  */
-  filename = init_c_lex (filename);
+/* Define MAX for TYPE based on the precision of the type.  IS_LONG is
+   1 for type "long" and 2 for "long long".  We have to handle
+   unsigned types, since wchar_t might be unsigned.  */
 
-  init_pragma ();
+static void
+builtin_define_type_max (macro, type, is_long)
+     const char *macro;
+     tree type;
+     int is_long;
+{
+  static const char *const values[]
+    = { "127", "255",
+       "32767", "65535",
+       "2147483647", "4294967295",
+       "9223372036854775807", "18446744073709551615",
+       "170141183460469231731687303715884105727",
+       "340282366920938463463374607431768211455" };
+  static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
+
+  const char *value, *suffix;
+  char *buf;
+  size_t idx;
 
-  if (!c_attrs_initialized)
-    c_init_attributes ();
+  /* Pre-rendering the values mean we don't have to futz with printing a
+     multi-word decimal value.  There are also a very limited number of
+     precisions that we support, so it's really a waste of time.  */
+  switch (TYPE_PRECISION (type))
+    {
+    case 8:    idx = 0; break;
+    case 16:   idx = 2; break;
+    case 32:   idx = 4; break;
+    case 64:   idx = 6; break;
+    case 128:  idx = 8; break;
+    default:    abort ();
+    }
 
-  return filename;
-}
+  value = values[idx + TREE_UNSIGNED (type)];
+  suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
 
-/* Common finish hook for the C, ObjC and C++ front ends.  */
-void
-c_common_finish ()
-{
-  cpp_finish (parse_in);
+  buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
+  sprintf (buf, "%s=%s%s", macro, value, suffix);
 
-  /* For performance, avoid tearing down cpplib's internal structures.
-     Call cpp_errors () instead of cpp_destroy ().  */
-  errorcount += cpp_errors (parse_in);
+  cpp_define (parse_in, buf);
 }
 
 static void
@@ -5173,16 +5432,19 @@ handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
    struct attribute_spec.handler.  */
 
 static tree
-handle_used_attribute (node, name, args, flags, no_add_attrs)
-     tree *node;
+handle_used_attribute (pnode, name, args, flags, no_add_attrs)
+     tree *pnode;
      tree name;
      tree args ATTRIBUTE_UNUSED;
      int flags ATTRIBUTE_UNUSED;
      bool *no_add_attrs;
 {
-  if (TREE_CODE (*node) == FUNCTION_DECL)
-    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (*node))
-      = TREE_USED (*node) = 1;
+  tree node = *pnode;
+
+  if (TREE_CODE (node) == FUNCTION_DECL
+      || (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
+    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (node))
+      = TREE_USED (node) = 1;
   else
     {
       warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@@ -5391,6 +5653,7 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
       int len = strlen (p);
       enum machine_mode mode = VOIDmode;
       tree typefm;
+      tree ptr_type;
 
       if (len > 4 && p[0] == '_' && p[1] == '_'
          && p[len - 1] == '_' && p[len - 2] == '_')
@@ -5420,6 +5683,10 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
       else if (0 == (typefm = (*lang_hooks.types.type_for_mode)
                     (mode, TREE_UNSIGNED (type))))
        error ("no data type for mode `%s'", p);
+      else if ((TREE_CODE (type) == POINTER_TYPE
+               || TREE_CODE (type) == REFERENCE_TYPE)
+              && !(*targetm.valid_pointer_mode) (mode))
+       error ("invalid pointer mode `%s'", p);
       else
        {
          /* If this is a vector, make sure we either have hardware
@@ -5432,6 +5699,19 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
              return NULL_TREE;
            }
 
+         if (TREE_CODE (type) == POINTER_TYPE)
+           {
+             ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
+                                                     mode);
+             *node = ptr_type;
+           }
+         else if (TREE_CODE (type) == REFERENCE_TYPE)
+           {
+             ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
+                                                       mode);
+             *node = ptr_type;
+           }
+         else
          *node = typefm;
          /* No need to layout the type here.  The caller should do this.  */
        }
@@ -5678,9 +5958,53 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs)
        }
       if (strcmp (TREE_STRING_POINTER (id), "hidden")
          && strcmp (TREE_STRING_POINTER (id), "protected")
-         && strcmp (TREE_STRING_POINTER (id), "internal"))
+         && strcmp (TREE_STRING_POINTER (id), "internal")
+         && strcmp (TREE_STRING_POINTER (id), "default"))
+       {
+         error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+    }
+
+  return NULL_TREE;
+}
+
+/* Handle an "tls_model" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_tls_model_attribute (node, name, args, flags, no_add_attrs)
+     tree *node;
+     tree name;
+     tree args;
+     int flags ATTRIBUTE_UNUSED;
+     bool *no_add_attrs;
+{
+  tree decl = *node;
+
+  if (! DECL_THREAD_LOCAL (decl))
+    {
+      warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+  else
+    {
+      tree id;
+
+      id = TREE_VALUE (args);
+      if (TREE_CODE (id) != STRING_CST)
+       {
+         error ("tls_model arg not a string");
+         *no_add_attrs = true;
+         return NULL_TREE;
+       }
+      if (strcmp (TREE_STRING_POINTER (id), "local-exec")
+         && strcmp (TREE_STRING_POINTER (id), "initial-exec")
+         && strcmp (TREE_STRING_POINTER (id), "local-dynamic")
+         && strcmp (TREE_STRING_POINTER (id), "global-dynamic"))
        {
-         error ("visibility arg must be one of \"hidden\", \"protected\" or \"internal\"");
+         error ("tls_model arg must be one of \"local-exec\", \"initial-exec\", \"local-dynamic\" or \"global-dynamic\"");
          *no_add_attrs = true;
          return NULL_TREE;
        }
@@ -5867,7 +6191,7 @@ handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
    The normal mechanism to prevent duplicates is to use type_hash_canon, but
    since we want to distinguish types that are essentially identical (except
    for their debug representation), we use a local list here.  */
-static tree vector_type_node_list = 0;
+static GTY(()) tree vector_type_node_list = 0;
 
 /* Handle a "vector_size" attribute; arguments as in
    struct attribute_spec.handler.  */
@@ -6066,7 +6390,7 @@ handle_nonnull_attribute (node, name, args, flags, no_add_attrs)
   unsigned HOST_WIDE_INT attr_arg_num;
 
   /* If no arguments are specified, all pointer arguments should be
-     non-null.  Veryify a full prototype is given so that the arguments
+     non-null.  Verify a full prototype is given so that the arguments
      will have the correct types when we actually check them later.  */
   if (! args)
     {