OSDN Git Service

2009-11-04 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index c3e7f6e..fd3df8c 100644 (file)
@@ -205,10 +205,13 @@ fe_file_change (const struct line_map *new_map)
         we already did in compile_file.  */
       if (!MAIN_FILE_P (new_map))
        {
-         int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+         unsigned int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+         int line = 0;
+         if (included_at > BUILTINS_LOCATION)
+           line = SOURCE_LINE (new_map - 1, included_at);
 
          input_location = new_map->start_location;
-         (*debug_hooks->start_source_file) (included_at, new_map->to_file);
+         (*debug_hooks->start_source_file) (line, new_map->to_file);
 #ifndef NO_IMPLICIT_EXTERN_C
          if (c_header_level)
            ++c_header_level;
@@ -236,7 +239,6 @@ fe_file_change (const struct line_map *new_map)
     }
 
   update_header_times (new_map->to_file);
-  in_system_header = new_map->sysp != 0;
   input_location = new_map->start_location;
 }
 
@@ -262,8 +264,8 @@ cb_def_pragma (cpp_reader *pfile, source_location loc)
            name = cpp_token_as_text (pfile, s);
        }
 
-      warning (OPT_Wunknown_pragmas, "%Hignoring #pragma %s %s",
-              &fe_loc, space, name);
+      warning_at (fe_loc, OPT_Wunknown_pragmas, "ignoring #pragma %s %s",
+                 space, name);
     }
 }
 
@@ -311,7 +313,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
       goto retry;
 
     case CPP_NAME:
-      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
+      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
       break;
 
     case CPP_NUMBER:
@@ -363,11 +365,12 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
            case CPP_WSTRING:
            case CPP_STRING16:
            case CPP_STRING32:
+           case CPP_UTF8STRING:
              type = lex_string (tok, value, true, true);
              break;
 
            case CPP_NAME:
-             *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
+             *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node.node));
              if (objc_is_reserved_word (*value))
                {
                  type = CPP_AT_NAME;
@@ -377,7 +380,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 
            default:
              /* ... or not.  */
-             error ("%Hstray %<@%> in program", &atloc);
+             error_at (atloc, "stray %<@%> in program");
              *loc = newloc;
              goto retry_after_at;
            }
@@ -388,7 +391,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
     case CPP_HASH:
     case CPP_PASTE:
       {
-       unsigned char name[4];
+       unsigned char name[8];
 
        *cpp_spell_token (parse_in, tok, name, true) = 0;
 
@@ -421,7 +424,8 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
     case CPP_WSTRING:
     case CPP_STRING16:
     case CPP_STRING32:
-      if ((lex_flags & C_LEX_RAW_STRINGS) == 0)
+    case CPP_UTF8STRING:
+      if ((lex_flags & C_LEX_STRING_NO_JOIN) == 0)
        {
          type = lex_string (tok, value, false,
                             (lex_flags & C_LEX_STRING_NO_TRANSLATE) == 0);
@@ -468,7 +472,7 @@ narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
                         unsigned HOST_WIDE_INT high,
                         unsigned int flags)
 {
-  enum integer_type_kind itk;
+  int itk;
 
   if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
     itk = itk_unsigned_int;
@@ -484,7 +488,7 @@ narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
       if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
          || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
              && TREE_INT_CST_LOW (upper) >= low))
-       return itk;
+       return (enum integer_type_kind) itk;
     }
 
   return itk_none;
@@ -495,7 +499,7 @@ static enum integer_type_kind
 narrowest_signed_type (unsigned HOST_WIDE_INT low,
                       unsigned HOST_WIDE_INT high, unsigned int flags)
 {
-  enum integer_type_kind itk;
+  int itk;
 
   if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
     itk = itk_int;
@@ -512,7 +516,7 @@ narrowest_signed_type (unsigned HOST_WIDE_INT low,
       if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
          || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
              && TREE_INT_CST_LOW (upper) >= low))
-       return itk;
+       return (enum integer_type_kind) itk;
     }
 
   return itk_none;
@@ -580,13 +584,18 @@ interpret_integer (const cpp_token *token, unsigned int flags)
            ? widest_unsigned_literal_type_node
            : widest_integer_literal_type_node);
   else
-    type = integer_types[itk];
-
-  if (itk > itk_unsigned_long
-      && (flags & CPP_N_WIDTH) != CPP_N_LARGE
-      && !in_system_header && !flag_isoc99)
-    pedwarn ("integer constant is too large for %qs type",
-            (flags & CPP_N_UNSIGNED) ? "unsigned long" : "long");
+    {
+      type = integer_types[itk];
+      if (itk > itk_unsigned_long
+         && (flags & CPP_N_WIDTH) != CPP_N_LARGE)
+       emit_diagnostic 
+         ((c_dialect_cxx () ? cxx_dialect == cxx98 : !flag_isoc99)
+          ? DK_PEDWARN : DK_WARNING,
+          input_location, OPT_Wlong_long,
+          (flags & CPP_N_UNSIGNED) 
+          ? "integer constant is too large for %<unsigned long%> type"
+          : "integer constant is too large for %<long%> type");
+    }
 
   value = build_int_cst_wide (type, integer.low, integer.high);
 
@@ -603,11 +612,30 @@ static tree
 interpret_float (const cpp_token *token, unsigned int flags)
 {
   tree type;
+  tree const_type;
   tree value;
   REAL_VALUE_TYPE real;
+  REAL_VALUE_TYPE real_trunc;
   char *copy;
   size_t copylen;
 
+  /* Default (no suffix) depends on whether the FLOAT_CONST_DECIMAL64
+     pragma has been used and is either double or _Decimal64.  Types
+     that are not allowed with decimal float default to double.  */
+  if (flags & CPP_N_DEFAULT)
+    {
+      flags ^= CPP_N_DEFAULT;
+      flags |= CPP_N_MEDIUM;
+
+      if (((flags & CPP_N_HEX) == 0) && ((flags & CPP_N_IMAGINARY) == 0))
+       {
+         warning (OPT_Wunsuffixed_float_constants,
+                  "unsuffixed float constant");
+         if (float_const_decimal64_p ())
+           flags |= CPP_N_DFLOAT;
+       }
+    }
+
   /* Decode _Fract and _Accum.  */
   if (flags & CPP_N_FRACT || flags & CPP_N_ACCUM)
     return interpret_fixed (token, flags);
@@ -639,8 +667,8 @@ interpret_float (const cpp_token *token, unsigned int flags)
 
            return error_mark_node;
          }
-       else if (pedantic)
-         pedwarn ("non-standard suffix on floating constant");
+       else
+         pedwarn (input_location, OPT_pedantic, "non-standard suffix on floating constant");
 
        type = c_common_type_for_mode (mode, 0);
        gcc_assert (type);
@@ -653,6 +681,10 @@ interpret_float (const cpp_token *token, unsigned int flags)
     else
       type = double_type_node;
 
+  const_type = excess_precision_type (type);
+  if (!const_type)
+    const_type = type;
+
   /* Copy the constant to a nul-terminated buffer.  If the constant
      has any suffixes, cut them off; REAL_VALUE_ATOF/ REAL_VALUE_HTOF
      can't handle them.  */
@@ -673,21 +705,30 @@ interpret_float (const cpp_token *token, unsigned int flags)
   memcpy (copy, token->val.str.text, copylen);
   copy[copylen] = '\0';
 
-  real_from_string3 (&real, copy, TYPE_MODE (type));
+  real_from_string3 (&real, copy, TYPE_MODE (const_type));
+  if (const_type != type)
+    /* Diagnosing if the result of converting the value with excess
+       precision to the semantic type would overflow (with associated
+       double rounding) is more appropriate than diagnosing if the
+       result of converting the string directly to the semantic type
+       would overflow.  */
+    real_convert (&real_trunc, TYPE_MODE (type), &real);
 
   /* Both C and C++ require a diagnostic for a floating constant
      outside the range of representable values of its type.  Since we
      have __builtin_inf* to produce an infinity, this is now a
      mandatory pedwarn if the target does not support infinities.  */
-  if (REAL_VALUE_ISINF (real)) 
+  if (REAL_VALUE_ISINF (real)
+      || (const_type != type && REAL_VALUE_ISINF (real_trunc)))
     {
       if (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
-       pedwarn ("floating constant exceeds range of %qT", type);
+       pedwarn (input_location, 0, "floating constant exceeds range of %qT", type);
       else
        warning (OPT_Woverflow, "floating constant exceeds range of %qT", type);
     }
   /* We also give a warning if the value underflows.  */
-  else if (REAL_VALUES_EQUAL (real, dconst0))
+  else if (REAL_VALUES_EQUAL (real, dconst0)
+          || (const_type != type && REAL_VALUES_EQUAL (real_trunc, dconst0)))
     {
       REAL_VALUE_TYPE realvoidmode;
       int overflow = real_from_string (&realvoidmode, copy);
@@ -696,9 +737,13 @@ interpret_float (const cpp_token *token, unsigned int flags)
     }
 
   /* Create a node with determined type and value.  */
-  value = build_real (type, real);
+  value = build_real (const_type, real);
   if (flags & CPP_N_IMAGINARY)
-    value = build_complex (NULL_TREE, convert (type, integer_zero_node), value);
+    value = build_complex (NULL_TREE, convert (const_type, integer_zero_node),
+                          value);
+
+  if (type != const_type)
+    value = build1 (EXCESS_PRECISION_EXPR, type, value);
 
   return value;
 }
@@ -828,12 +873,13 @@ interpret_fixed (const cpp_token *token, unsigned int flags)
   return value;
 }
 
-/* Convert a series of STRING, WSTRING, STRING16 and/or STRING32 tokens
-   into a tree, performing string constant concatenation.  TOK is the
-   first of these.  VALP is the location to write the string into.
-   OBJC_STRING indicates whether an '@' token preceded the incoming token.
+/* Convert a series of STRING, WSTRING, STRING16, STRING32 and/or
+   UTF8STRING tokens into a tree, performing string constant
+   concatenation.  TOK is the first of these.  VALP is the location
+   to write the string into. OBJC_STRING indicates whether an '@' token
+   preceded the incoming token.
    Returns the CPP token type of the result (CPP_STRING, CPP_WSTRING,
-   CPP_STRING32, CPP_STRING16, or CPP_OBJC_STRING).
+   CPP_STRING32, CPP_STRING16, CPP_UTF8STRING, or CPP_OBJC_STRING).
 
    This is unfortunately more work than it should be.  If any of the
    strings in the series has an L prefix, the result is a wide string
@@ -878,6 +924,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
     case CPP_WSTRING:
     case CPP_STRING16:
     case CPP_STRING32:
+    case CPP_UTF8STRING:
       if (type != tok->type)
        {
          if (type == CPP_STRING)
@@ -923,6 +970,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
        {
        default:
        case CPP_STRING:
+       case CPP_UTF8STRING:
          value = build_string (1, "");
          break;
        case CPP_STRING16:
@@ -948,6 +996,7 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
     {
     default:
     case CPP_STRING:
+    case CPP_UTF8STRING:
       TREE_TYPE (value) = char_array_type_node;
       break;
     case CPP_STRING16:
@@ -974,7 +1023,7 @@ lex_charconst (const cpp_token *token)
   cppchar_t result;
   tree type, value;
   unsigned int chars_seen;
-  int unsignedp;
+  int unsignedp = 0;
 
   result = cpp_interpret_charconst (parse_in, token,
                                    &chars_seen, &unsignedp);