OSDN Git Service

gcc/ada/
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index ff8eee6..5cad260 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
-   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
-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
@@ -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
-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"
@@ -50,23 +49,14 @@ static splay_tree file_info_tree;
 int pending_lang_change; /* If we need to switch languages - C++ only */
 int c_header_level;     /* depth in C headers - C++ only */
 
-/* If we need to translate characters received.  This is tri-state:
-   0 means use only the untranslated string; 1 means use only
-   the translated string; -1 means chain the translated string
-   to the untranslated one.  */
-int c_lex_string_translate = 1;
-
-/* True if strings should be passed to the caller of c_lex completely
-   unmolested (no concatenation, no translation).  */
-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_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
        (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
-static enum cpp_ttype lex_string (const cpp_token *, tree *, bool);
+static enum cpp_ttype lex_string (const cpp_token *, tree *, bool, bool);
 static tree lex_charconst (const cpp_token *);
 static void update_header_times (const char *);
 static int dump_one_header (splay_tree_node, void *);
@@ -187,7 +177,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);
-         free ((void *) cstr.text);
+         free (CONST_CAST (unsigned char *, cstr.text));
        }
     }
 #endif
@@ -205,7 +195,7 @@ cb_line_change (cpp_reader * ARG_UNUSED (pfile), const cpp_token *token,
 #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
@@ -283,7 +273,7 @@ cb_def_pragma (cpp_reader *pfile, source_location 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
@@ -309,7 +299,7 @@ cb_def_pragma (cpp_reader *pfile, source_location loc)
 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));
 }
@@ -319,7 +309,7 @@ static void
 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));
 }
@@ -329,7 +319,8 @@ cb_undef (cpp_reader * ARG_UNUSED (pfile), source_location loc,
    non-NULL.  */
 
 enum cpp_ttype
-c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
+c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
+                 int lex_flags)
 {
   static bool no_more_pch;
   const cpp_token *tok;
@@ -338,15 +329,15 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
 
   timevar_push (TV_CPP);
  retry:
-  tok = cpp_get_token (parse_in);
-  type = tok->type;
-
- retry_after_at:
 #ifdef USE_MAPPED_LOCATION
-  *loc = tok->src_loc;
+  tok = cpp_get_token_with_location (parse_in, loc);
 #else
+  tok = cpp_get_token (parse_in);
   *loc = input_location;
 #endif
+  type = tok->type;
+
+ retry_after_at:
   switch (type)
     {
     case CPP_PADDING:
@@ -390,10 +381,19 @@ 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 ())
        {
+#ifdef USE_MAPPED_LOCATION
+         location_t atloc = *loc;
+         location_t newloc;
+#else
          location_t atloc = input_location;
+#endif
 
        retry_at:
+#ifdef USE_MAPPED_LOCATION
+         tok = cpp_get_token_with_location (parse_in, &newloc);
+#else
          tok = cpp_get_token (parse_in);
+#endif
          type = tok->type;
          switch (type)
            {
@@ -402,7 +402,7 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
 
            case CPP_STRING:
            case CPP_WSTRING:
-             type = lex_string (tok, value, true);
+             type = lex_string (tok, value, true, true);
              break;
 
            case CPP_NAME:
@@ -417,6 +417,9 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
            default:
              /* ... or not.  */
              error ("%Hstray %<@%> in program", &atloc);
+#ifdef USE_MAPPED_LOCATION
+             *loc = newloc;
+#endif
              goto retry_after_at;
            }
          break;
@@ -455,12 +458,13 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags)
 
     case CPP_STRING:
     case CPP_WSTRING:
-      if (!c_lex_return_raw_strings)
+      if ((lex_flags & C_LEX_RAW_STRINGS) == 0)
        {
-         type = lex_string (tok, value, false);
+         type = lex_string (tok, value, false,
+                            (lex_flags & C_LEX_STRING_NO_TRANSLATE) == 0);
          break;
        }
-      *value = build_string (tok->val.str.len, (char *) tok->val.str.text);
+      *value = build_string (tok->val.str.len, (const char *) tok->val.str.text);
       break;
       
     case CPP_PRAGMA:
@@ -641,6 +645,10 @@ interpret_float (const cpp_token *token, unsigned int flags)
   char *copy;
   size_t copylen;
 
+  /* 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)
@@ -732,6 +740,131 @@ interpret_float (const cpp_token *token, unsigned int flags)
   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
@@ -749,7 +882,7 @@ interpret_float (const cpp_token *token, unsigned int flags)
    we must arrange to provide.  */
 
 static enum cpp_ttype
-lex_string (const cpp_token *tok, tree *valp, bool objc_string)
+lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
 {
   tree value;
   bool wide = false;
@@ -807,34 +940,12 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string)
     warning (OPT_Wtraditional,
             "traditional C rejects string constant concatenation");
 
-  if ((c_lex_string_translate
+  if ((translate
        ? 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);
-
-      if (c_lex_string_translate == -1)
-       {
-         int xlated = cpp_interpret_string_notranslate (parse_in, strs,
-                                                        concats + 1,
-                                                        &istr, wide);
-         /* 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
-             || 0 != strncmp (TREE_STRING_POINTER (value), (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.  */
-             *valp = build_string (istr.len, (char *) istr.text);
-             valp = &TREE_CHAIN (*valp);
-           }
-         free ((void *) istr.text);
-       }
+      value = build_string (istr.len, (const char *) istr.text);
+      free (CONST_CAST (unsigned char *, istr.text));
     }
   else
     {