OSDN Git Service

* jcf-parse.c (parse_class_file): Re-enter the current file.
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index 4ceb6e4..23abaad 100644 (file)
@@ -1,13 +1,13 @@
 /* Mainly the interface between cpplib and the C front ends.
    Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
 /* 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, 2005
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
    Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 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, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
@@ -41,6 +40,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tm_p.h"
 #include "splay-tree.h"
 #include "debug.h"
 #include "tm_p.h"
 #include "splay-tree.h"
 #include "debug.h"
+#include "target.h"
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -61,6 +61,7 @@ bool c_lex_return_raw_strings = false;
 
 static tree interpret_integer (const cpp_token *, unsigned int);
 static tree interpret_float (const cpp_token *, unsigned int);
 
 static tree interpret_integer (const cpp_token *, unsigned int);
 static tree interpret_float (const cpp_token *, unsigned int);
+static tree interpret_fixed (const cpp_token *, unsigned int);
 static enum integer_type_kind narrowest_unsigned_type
        (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
 static enum integer_type_kind narrowest_signed_type
 static enum integer_type_kind narrowest_unsigned_type
        (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
 static enum integer_type_kind narrowest_signed_type
@@ -102,7 +103,7 @@ init_c_lex (void)
   /* Set the debug callbacks if we can use them.  */
   if (debug_info_level == DINFO_LEVEL_VERBOSE
       && (write_symbols == DWARF2_DEBUG
   /* Set the debug callbacks if we can use them.  */
   if (debug_info_level == DINFO_LEVEL_VERBOSE
       && (write_symbols == DWARF2_DEBUG
-          || write_symbols == VMS_AND_DWARF2_DEBUG))
+         || write_symbols == VMS_AND_DWARF2_DEBUG))
     {
       cb->define = cb_define;
       cb->undef = cb_undef;
     {
       cb->define = cb_define;
       cb->undef = cb_undef;
@@ -186,7 +187,7 @@ cb_ident (cpp_reader * ARG_UNUSED (pfile),
       if (cpp_interpret_string (pfile, str, 1, &cstr, false))
        {
          ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text);
       if (cpp_interpret_string (pfile, str, 1, &cstr, false))
        {
          ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text);
-         free ((void *) cstr.text);
+         free (CONST_CAST (unsigned char *, cstr.text));
        }
     }
 #endif
        }
     }
 #endif
@@ -204,7 +205,7 @@ cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token,
 #else
     {
       source_location loc = token->src_loc;
 #else
     {
       source_location loc = token->src_loc;
-      const struct line_map *map = linemap_lookup (&line_table, loc);
+      const struct line_map *map = linemap_lookup (line_table, loc);
       input_line = SOURCE_LINE (map, loc);
     }
 #endif
       input_line = SOURCE_LINE (map, loc);
     }
 #endif
@@ -223,12 +224,12 @@ fe_file_change (const struct line_map *new_map)
       if (!MAIN_FILE_P (new_map))
        {
 #ifdef USE_MAPPED_LOCATION
       if (!MAIN_FILE_P (new_map))
        {
 #ifdef USE_MAPPED_LOCATION
-          int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
+         int included_at = LAST_SOURCE_LINE_LOCATION (new_map - 1);
 
          input_location = included_at;
          push_srcloc (new_map->start_location);
 #else
 
          input_location = included_at;
          push_srcloc (new_map->start_location);
 #else
-          int included_at = LAST_SOURCE_LINE (new_map - 1);
+         int included_at = LAST_SOURCE_LINE (new_map - 1);
 
          input_line = included_at;
          push_srcloc (new_map->to_file, 1);
 
          input_line = included_at;
          push_srcloc (new_map->to_file, 1);
@@ -282,7 +283,7 @@ cb_def_pragma (cpp_reader *pfile, source_location loc)
       const cpp_token *s;
 #ifndef USE_MAPPED_LOCATION
       location_t fe_loc;
       const cpp_token *s;
 #ifndef USE_MAPPED_LOCATION
       location_t fe_loc;
-      const struct line_map *map = linemap_lookup (&line_table, loc);
+      const struct line_map *map = linemap_lookup (line_table, loc);
       fe_loc.file = map->to_file;
       fe_loc.line = SOURCE_LINE (map, loc);
 #else
       fe_loc.file = map->to_file;
       fe_loc.line = SOURCE_LINE (map, loc);
 #else
@@ -308,7 +309,7 @@ cb_def_pragma (cpp_reader *pfile, source_location loc)
 static void
 cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
 {
 static void
 cb_define (cpp_reader *pfile, source_location loc, cpp_hashnode *node)
 {
-  const struct line_map *map = linemap_lookup (&line_table, loc);
+  const struct line_map *map = linemap_lookup (line_table, loc);
   (*debug_hooks->define) (SOURCE_LINE (map, loc),
                          (const char *) cpp_macro_definition (pfile, node));
 }
   (*debug_hooks->define) (SOURCE_LINE (map, loc),
                          (const char *) cpp_macro_definition (pfile, node));
 }
@@ -318,7 +319,7 @@ static void
 cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
          cpp_hashnode *node)
 {
 cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
          cpp_hashnode *node)
 {
-  const struct line_map *map = linemap_lookup (&line_table, loc);
+  const struct line_map *map = linemap_lookup (line_table, loc);
   (*debug_hooks->undef) (SOURCE_LINE (map, loc),
                         (const char *) NODE_NAME (node));
 }
   (*debug_hooks->undef) (SOURCE_LINE (map, loc),
                         (const char *) NODE_NAME (node));
 }
@@ -333,23 +334,24 @@ 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;
   static bool no_more_pch;
   const cpp_token *tok;
   enum cpp_ttype type;
+  unsigned char add_flags = 0;
 
   timevar_push (TV_CPP);
  retry:
 
   timevar_push (TV_CPP);
  retry:
-  tok = cpp_get_token (parse_in);
-  type = tok->type;
-  
- retry_after_at:
 #ifdef USE_MAPPED_LOCATION
 #ifdef USE_MAPPED_LOCATION
-  *loc = tok->src_loc;
+  tok = cpp_get_token_with_location (parse_in, loc);
 #else
 #else
+  tok = cpp_get_token (parse_in);
   *loc = input_location;
 #endif
   *loc = input_location;
 #endif
+  type = tok->type;
+
+ retry_after_at:
   switch (type)
     {
     case CPP_PADDING:
       goto retry;
   switch (type)
     {
     case CPP_PADDING:
       goto retry;
-      
+
     case CPP_NAME:
       *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
       break;
     case CPP_NAME:
       *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
       break;
@@ -363,9 +365,14 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
          case CPP_N_INVALID:
            /* cpplib has issued an error.  */
            *value = error_mark_node;
          case CPP_N_INVALID:
            /* cpplib has issued an error.  */
            *value = error_mark_node;
+           errorcount++;
            break;
 
          case CPP_N_INTEGER:
            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;
 
            *value = interpret_integer (tok, flags);
            break;
 
@@ -383,16 +390,25 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
       /* An @ may give the next token special significance in Objective-C.  */
       if (c_dialect_objc ())
        {
       /* An @ may give the next token special significance in Objective-C.  */
       if (c_dialect_objc ())
        {
+#ifdef USE_MAPPED_LOCATION
+         location_t atloc = *loc;
+         location_t newloc;
+#else
          location_t atloc = input_location;
          location_t atloc = input_location;
-         
+#endif
+
        retry_at:
        retry_at:
+#ifdef USE_MAPPED_LOCATION
+         tok = cpp_get_token_with_location (parse_in, &newloc);
+#else
          tok = cpp_get_token (parse_in);
          tok = cpp_get_token (parse_in);
+#endif
          type = tok->type;
          switch (type)
            {
            case CPP_PADDING:
              goto retry_at;
          type = tok->type;
          switch (type)
            {
            case CPP_PADDING:
              goto retry_at;
-             
+
            case CPP_STRING:
            case CPP_WSTRING:
              type = lex_string (tok, value, true);
            case CPP_STRING:
            case CPP_WSTRING:
              type = lex_string (tok, value, true);
@@ -410,6 +426,9 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
            default:
              /* ... or not.  */
              error ("%Hstray %<@%> in program", &atloc);
            default:
              /* ... or not.  */
              error ("%Hstray %<@%> in program", &atloc);
+#ifdef USE_MAPPED_LOCATION
+             *loc = newloc;
+#endif
              goto retry_after_at;
            }
          break;
              goto retry_after_at;
            }
          break;
@@ -420,12 +439,12 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
     case CPP_PASTE:
       {
        unsigned char name[4];
     case CPP_PASTE:
       {
        unsigned char name[4];
-       
+
        *cpp_spell_token (parse_in, tok, name, true) = 0;
        *cpp_spell_token (parse_in, tok, name, true) = 0;
-       
+
        error ("stray %qs in program", name);
       }
        error ("stray %qs in program", name);
       }
-      
+
       goto retry;
 
     case CPP_OTHER:
       goto retry;
 
     case CPP_OTHER:
@@ -453,11 +472,11 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
          type = lex_string (tok, value, false);
          break;
        }
          type = lex_string (tok, value, false);
          break;
        }
+      *value = build_string (tok->val.str.len, (const char *) tok->val.str.text);
+      break;
       
       
-      /* FALLTHROUGH */
-
     case CPP_PRAGMA:
     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.  */
       break;
 
       /* These tokens should not be visible outside cpplib.  */
@@ -472,24 +491,17 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
     }
 
   if (cpp_flags)
     }
 
   if (cpp_flags)
-    *cpp_flags = tok->flags;
+    *cpp_flags = tok->flags | add_flags;
 
   if (!no_more_pch)
     {
       no_more_pch = true;
       c_common_no_more_pch ();
     }
 
   if (!no_more_pch)
     {
       no_more_pch = true;
       c_common_no_more_pch ();
     }
-  
+
   timevar_pop (TV_CPP);
   timevar_pop (TV_CPP);
-  
-  return type;
-}
 
 
-enum cpp_ttype
-pragma_lex (tree *value)
-{
-  location_t loc;
-  return c_lex_with_flags (value, &loc, NULL);
+  return type;
 }
 
 /* Returns the narrowest C-visible unsigned type, starting with the
 }
 
 /* Returns the narrowest C-visible unsigned type, starting with the
@@ -541,7 +553,7 @@ narrowest_signed_type (unsigned HOST_WIDE_INT low,
   for (; itk < itk_none; itk += 2 /* skip signed types */)
     {
       tree upper = TYPE_MAX_VALUE (integer_types[itk]);
   for (; itk < itk_none; itk += 2 /* skip signed types */)
     {
       tree upper = TYPE_MAX_VALUE (integer_types[itk]);
-      
+
       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))
       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))
@@ -640,51 +652,93 @@ interpret_float (const cpp_token *token, unsigned int flags)
   REAL_VALUE_TYPE real;
   char *copy;
   size_t copylen;
   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 _Fract and _Accum.  */
+  if (flags & CPP_N_FRACT || flags & CPP_N_ACCUM)
+    return interpret_fixed (token, flags);
+
+  /* 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_MD)
+      {
+       char suffix;
+       enum machine_mode mode;
+
+       if ((flags & CPP_N_WIDTH_MD) == CPP_N_MD_W)
+         suffix = 'w';
+       else
+         suffix = 'q';
+
+       mode = targetm.c.mode_for_suffix (suffix);
+       if (mode == VOIDmode)
+         {
+           error ("unsupported non-standard suffix on floating constant");
+           errorcount++;
+
+           return error_mark_node;
+         }
+       else if (pedantic)
+         pedwarn ("non-standard suffix on floating constant");
+
+       type = c_common_type_for_mode (mode, 0);
+       gcc_assert (type);
+      }
+    else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
       type = long_double_type_node;
       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 = float_type_node;
-      type_name = "float";
-    }
-  else
-    {
+    else
       type = double_type_node;
       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;
 
   /* 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 or machine defined 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';
 
 
   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
 
   /* 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, it might now be
-     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);
+     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 (!MODE_HAS_INFINITIES (TYPE_MODE (type)))
+       pedwarn ("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))
+    {
+      REAL_VALUE_TYPE realvoidmode;
+      int overflow = real_from_string (&realvoidmode, copy);
+      if (overflow < 0 || !REAL_VALUES_EQUAL (realvoidmode, dconst0)) 
+       warning (OPT_Woverflow, "floating constant truncated to zero");
+    }
 
   /* Create a node with determined type and value.  */
   value = build_real (type, real);
 
   /* Create a node with determined type and value.  */
   value = build_real (type, real);
@@ -694,6 +748,131 @@ interpret_float (const cpp_token *token, unsigned int flags)
   return value;
 }
 
   return value;
 }
 
+/* Interpret TOKEN, a fixed-point number with FLAGS as classified
+   by cpplib.  */
+
+static tree
+interpret_fixed (const cpp_token *token, unsigned int flags)
+{
+  tree type;
+  tree value;
+  FIXED_VALUE_TYPE fixed;
+  char *copy;
+  size_t copylen;
+
+  copylen = token->val.str.len;
+
+  if (flags & CPP_N_FRACT) /* _Fract.  */
+    {
+      if (flags & CPP_N_UNSIGNED) /* Unsigned _Fract.  */
+       {
+         if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+           {
+             type = unsigned_long_long_fract_type_node;
+             copylen -= 4;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
+           {
+             type = unsigned_long_fract_type_node;
+             copylen -= 3;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+           {
+             type = unsigned_short_fract_type_node;
+             copylen -= 3;
+           }
+          else
+           {
+             type = unsigned_fract_type_node;
+             copylen -= 2;
+           }
+       }
+      else /* Signed _Fract.  */
+       {
+         if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+           {
+             type = long_long_fract_type_node;
+             copylen -= 3;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
+           {
+             type = long_fract_type_node;
+             copylen -= 2;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+           {
+             type = short_fract_type_node;
+             copylen -= 2;
+           }
+          else
+           {
+             type = fract_type_node;
+             copylen --;
+           }
+         }
+    }
+  else /* _Accum.  */
+    {
+      if (flags & CPP_N_UNSIGNED) /* Unsigned _Accum.  */
+       {
+         if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+           {
+             type = unsigned_long_long_accum_type_node;
+             copylen -= 4;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
+           {
+             type = unsigned_long_accum_type_node;
+             copylen -= 3;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+           {
+             type = unsigned_short_accum_type_node;
+             copylen -= 3;
+            }
+         else
+           {
+             type = unsigned_accum_type_node;
+             copylen -= 2;
+           }
+       }
+      else /* Signed _Accum.  */
+        {
+         if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+           {
+             type = long_long_accum_type_node;
+             copylen -= 3;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
+           {
+             type = long_accum_type_node;
+             copylen -= 2;
+           }
+         else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+           {
+             type = short_accum_type_node;
+             copylen -= 2;
+           }
+         else
+           {
+             type = accum_type_node;
+             copylen --;
+           }
+       }
+    }
+
+  copy = (char *) alloca (copylen + 1);
+  memcpy (copy, token->val.str.text, copylen);
+  copy[copylen] = '\0';
+
+  fixed_from_string (&fixed, copy, TYPE_MODE (type));
+
+  /* Create a node with determined type and value.  */
+  value = build_fixed (type, fixed);
+
+  return value;
+}
+
 /* Convert a series of STRING and/or WSTRING 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
 /* Convert a series of STRING and/or WSTRING 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
@@ -740,21 +919,21 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
          goto retry;
        }
       /* FALLTHROUGH */
          goto retry;
        }
       /* FALLTHROUGH */
-      
+
     default:
       break;
     default:
       break;
-      
+
     case CPP_WSTRING:
       wide = true;
       /* FALLTHROUGH */
     case CPP_WSTRING:
       wide = true;
       /* FALLTHROUGH */
-      
+
     case CPP_STRING:
       if (!concats)
        {
          gcc_obstack_init (&str_ob);
          obstack_grow (&str_ob, &str, sizeof (cpp_string));
        }
     case CPP_STRING:
       if (!concats)
        {
          gcc_obstack_init (&str_ob);
          obstack_grow (&str_ob, &str, sizeof (cpp_string));
        }
-       
+
       concats++;
       obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
       goto retry;
       concats++;
       obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
       goto retry;
@@ -773,8 +952,8 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
        ? cpp_interpret_string : cpp_interpret_string_notranslate)
       (parse_in, strs, concats + 1, &istr, wide))
     {
        ? cpp_interpret_string : cpp_interpret_string_notranslate)
       (parse_in, strs, concats + 1, &istr, wide))
     {
-      value = build_string (istr.len, (char *) istr.text);
-      free ((void *) istr.text);
+      value = build_string (istr.len, (const char *) istr.text);
+      free (CONST_CAST (unsigned char *, istr.text));
 
       if (c_lex_string_translate == -1)
        {
 
       if (c_lex_string_translate == -1)
        {
@@ -784,18 +963,18 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
          /* Assume that, if we managed to translate the string above,
             then the untranslated parsing will always succeed.  */
          gcc_assert (xlated);
          /* Assume that, if we managed to translate the string above,
             then the untranslated parsing will always succeed.  */
          gcc_assert (xlated);
-         
+
          if (TREE_STRING_LENGTH (value) != (int) istr.len
          if (TREE_STRING_LENGTH (value) != (int) istr.len
-             || 0 != strncmp (TREE_STRING_POINTER (value), (char *) istr.text,
-                              istr.len))
+             || 0 != strncmp (TREE_STRING_POINTER (value),
+                              (const char *) istr.text, istr.len))
            {
              /* Arrange for us to return the untranslated string in
                 *valp, but to set up the C type of the translated
                 one.  */
            {
              /* Arrange for us to return the untranslated string in
                 *valp, but to set up the C type of the translated
                 one.  */
-             *valp = build_string (istr.len, (char *) istr.text);
+             *valp = build_string (istr.len, (const char *) istr.text);
              valp = &TREE_CHAIN (*valp);
            }
              valp = &TREE_CHAIN (*valp);
            }
-         free ((void *) istr.text);
+         free (CONST_CAST (unsigned char *, istr.text));
        }
     }
   else
        }
     }
   else