OSDN Git Service

PR fortran/27553
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index 5be65f1..44e63d7 100644 (file)
@@ -1,6 +1,7 @@
 /* Mainly the interface between cpplib and the C front ends.
    Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
-   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -16,8 +17,8 @@ for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -45,12 +46,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 static int header_time, body_time;
 static splay_tree file_info_tree;
 
-#undef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
-
-/* Number of bytes in a wide character.  */
-#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
-
 int pending_lang_change; /* If we need to switch languages - C++ only */
 int c_header_level;     /* depth in C headers - C++ only */
 
@@ -256,7 +251,7 @@ fe_file_change (const struct line_map *new_map)
       if (c_header_level && --c_header_level == 0)
        {
          if (new_map->sysp == 2)
-           warning ("badly nested C headers from preprocessor");
+           warning (0, "badly nested C headers from preprocessor");
          --pending_lang_change;
        }
 #endif
@@ -304,7 +299,8 @@ cb_def_pragma (cpp_reader *pfile, source_location loc)
            name = cpp_token_as_text (pfile, s);
        }
 
-      warning ("%Hignoring #pragma %s %s", &fe_loc, space, name);
+      warning (OPT_Wunknown_pragmas, "%Hignoring #pragma %s %s",
+              &fe_loc, space, name);
     }
 }
 
@@ -337,6 +333,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
   static bool no_more_pch;
   const cpp_token *tok;
   enum cpp_ttype type;
+  unsigned char add_flags = 0;
 
   timevar_push (TV_CPP);
  retry:
@@ -370,6 +367,10 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
            break;
 
          case CPP_N_INTEGER:
+           /* C++ uses '0' to mark virtual functions as pure.
+              Set PURE_ZERO to pass this information to the C++ parser.  */
+           if (tok->val.str.len == 1 && *tok->val.str.text == '0')
+             add_flags = PURE_ZERO;
            *value = interpret_integer (tok, flags);
            break;
 
@@ -457,11 +458,11 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
          type = lex_string (tok, value, false);
          break;
        }
+      *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
+      break;
       
-      /* FALLTHROUGH */
-
     case CPP_PRAGMA:
-      *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
+      *value = build_int_cst (NULL, tok->val.pragma);
       break;
 
       /* These tokens should not be visible outside cpplib.  */
@@ -476,7 +477,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
     }
 
   if (cpp_flags)
-    *cpp_flags = tok->flags;
+    *cpp_flags = tok->flags | add_flags;
 
   if (!no_more_pch)
     {
@@ -489,13 +490,6 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
   return type;
 }
 
-enum cpp_ttype
-c_lex (tree *value)
-{
-  location_t loc;
-  return c_lex_with_flags (value, &loc, NULL);
-}
-
 /* Returns the narrowest C-visible unsigned type, starting with the
    minimum specified by FLAGS, that can fit HIGH:LOW, or itk_none if
    there isn't one.  */
@@ -602,10 +596,11 @@ interpret_integer (const cpp_token *token, unsigned int flags)
                  if (itk_u < itk_unsigned_long)
                    itk_u = itk_unsigned_long;
                  itk = itk_u;
-                 warning ("this decimal constant is unsigned only in ISO C90");
+                 warning (0, "this decimal constant is unsigned only in ISO C90");
                }
-             else if (warn_traditional)
-               warning ("this decimal constant would be unsigned in ISO C90");
+             else
+               warning (OPT_Wtraditional,
+                        "this decimal constant would be unsigned in ISO C90");
            }
        }
     }
@@ -643,43 +638,45 @@ interpret_float (const cpp_token *token, unsigned int flags)
   REAL_VALUE_TYPE real;
   char *copy;
   size_t copylen;
-  const char *type_name;
 
-  /* FIXME: make %T work in error/warning, then we don't need type_name.  */
-  if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
-    {
+  /* Decode type based on width and properties. */
+  if (flags & CPP_N_DFLOAT)
+    if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+      type = dfloat128_type_node;
+    else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+      type = dfloat32_type_node;
+    else
+      type = dfloat64_type_node;
+  else
+    if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
       type = long_double_type_node;
-      type_name = "long double";
-    }
-  else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
-          || flag_single_precision_constant)
-    {
+    else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL
+            || flag_single_precision_constant)
       type = float_type_node;
-      type_name = "float";
-    }
-  else
-    {
+    else
       type = double_type_node;
-      type_name = "double";
-    }
 
   /* 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.  */
   copylen = token->val.str.len;
-  if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
-    /* Must be an F or L suffix.  */
-    copylen--;
-  if (flags & CPP_N_IMAGINARY)
-    /* I or J suffix.  */
-    copylen--;
+  if (flags & CPP_N_DFLOAT) 
+    copylen -= 2;
+  else 
+    {
+      if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM)
+       /* Must be an F or L suffix.  */
+       copylen--;
+      if (flags & CPP_N_IMAGINARY)
+       /* I or J suffix.  */
+       copylen--;
+    }
 
   copy = (char *) alloca (copylen + 1);
   memcpy (copy, token->val.str.text, copylen);
   copy[copylen] = '\0';
 
-  real_from_string (&real, copy);
-  real_convert (&real, TYPE_MODE (type), &real);
+  real_from_string3 (&real, copy, TYPE_MODE (type));
 
   /* Both C and C++ require a diagnostic for a floating constant
      outside the range of representable values of its type.  Since we
@@ -687,7 +684,7 @@ interpret_float (const cpp_token *token, unsigned int flags)
      appropriate for this to be a mandatory pedwarn rather than
      conditioned on -pedantic.  */
   if (REAL_VALUE_ISINF (real) && pedantic)
-    pedwarn ("floating constant exceeds range of %<%s%>", type_name);
+    pedwarn ("floating constant exceeds range of %qT", type);
 
   /* Create a node with determined type and value.  */
   value = build_real (type, real);
@@ -766,10 +763,11 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
   /* We have read one more token than we want.  */
   _cpp_backup_tokens (parse_in, 1);
   if (concats)
-    strs = (cpp_string *) obstack_finish (&str_ob);
+    strs = XOBFINISH (&str_ob, cpp_string *);
 
-  if (concats && !objc_string && warn_traditional && !in_system_header)
-    warning ("traditional C rejects string constant concatenation");
+  if (concats && !objc_string && !in_system_header)
+    warning (OPT_Wtraditional,
+            "traditional C rejects string constant concatenation");
 
   if ((c_lex_string_translate
        ? cpp_interpret_string : cpp_interpret_string_notranslate)