OSDN Git Service

* Makefile.in (INSTALL_CPP, UNINSTALL_CPP): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index 7bafde7..2ecc147 100644 (file)
@@ -22,12 +22,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "config.h"
 #include "system.h"
 
+#include "real.h"
 #include "rtl.h"
 #include "tree.h"
 #include "expr.h"
 #include "input.h"
 #include "output.h"
-#include "c-lex.h"
 #include "c-tree.h"
 #include "c-common.h"
 #include "flags.h"
@@ -40,13 +40,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "splay-tree.h"
 #include "debug.h"
 
-/* MULTIBYTE_CHARS support only works for native compilers.
-   ??? Ideally what we want is to model widechar support after
-   the current floating point support.  */
-#ifdef CROSS_COMPILE
-#undef MULTIBYTE_CHARS
-#endif
-
 #ifdef MULTIBYTE_CHARS
 #include "mbchar.h"
 #include <locale.h>
@@ -65,9 +58,6 @@ static unsigned int src_lineno;
 static int header_time, body_time;
 static splay_tree file_info_tree;
 
-/* Cause the `yydebug' variable to be defined.  */
-#define YYDEBUG 1
-
 /* File used for outputting assembler code.  */
 extern FILE *asm_out_file;
 
@@ -77,14 +67,12 @@ extern FILE *asm_out_file;
 /* Number of bytes in a wide character.  */
 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
 
-int indent_level;        /* Number of { minus number of }.  */
 int pending_lang_change; /* If we need to switch languages - C++ only */
 int c_header_level;     /* depth in C headers - C++ only */
 
 /* Nonzero tells yylex to ignore \ in string constants.  */
 static int ignore_escape_flag;
 
-static void parse_float                PARAMS ((PTR));
 static tree lex_number         PARAMS ((const char *, unsigned int));
 static tree lex_string         PARAMS ((const unsigned char *, unsigned int,
                                         int));
@@ -157,12 +145,20 @@ init_c_lex (filename)
    the primary source file.  */
 
 void
-c_common_parse_file ()
+c_common_parse_file (set_yydebug)
+     int set_yydebug ATTRIBUTE_UNUSED;
 {
+#if YYDEBUG != 0
+  yydebug = set_yydebug;
+#else
+  warning ("YYDEBUG not defined");
+#endif
+
   (*debug_hooks->start_source_file) (lineno, input_filename);
   cpp_finish_options (parse_in);
 
   yyparse ();
+  free_parser_stacks ();
 }
 
 struct c_fileinfo *
@@ -228,9 +224,6 @@ dump_time_statistics ()
   splay_tree_foreach (file_info_tree, dump_one_header, 0);
 }
 
-/* Not yet handled: #pragma, #define, #undef.
-   No need to deal with linemarkers under normal conditions.  */
-
 static void
 cb_ident (pfile, line, str)
      cpp_reader *pfile ATTRIBUTE_UNUSED;
@@ -273,10 +266,11 @@ cb_file_change (pfile, new_map)
        main_input_filename = new_map->to_file;
       else
        {
-         lineno = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
+          int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
+
+         lineno = included_at;
          push_srcloc (new_map->to_file, 1);
-         input_file_stack->indent_level = indent_level;
-         (*debug_hooks->start_source_file) (lineno, new_map->to_file);
+         (*debug_hooks->start_source_file) (included_at, new_map->to_file);
 #ifndef NO_IMPLICIT_EXTERN_C
          if (c_header_level)
            ++c_header_level;
@@ -298,16 +292,6 @@ cb_file_change (pfile, new_map)
          --pending_lang_change;
        }
 #endif
-#if 0
-      if (indent_level != input_file_stack->indent_level)
-       {
-         warning_with_file_and_line
-           (input_filename, lineno,
-            "this file contains more '%c's than '%c's",
-            indent_level > input_file_stack->indent_level ? '{' : '}',
-            indent_level > input_file_stack->indent_level ? '}' : '{');
-       }
-#endif
       pop_srcloc ();
       
       (*debug_hooks->end_source_file) (to_line);
@@ -701,67 +685,6 @@ struct try_type type_sequence[] =
 };
 #endif /* 0 */
 \f
-struct pf_args
-{
-  /* Input */
-  const char *str;
-  int fflag;
-  int lflag;
-  int base;
-  /* Output */
-  int conversion_errno;
-  REAL_VALUE_TYPE value;
-  tree type;
-};
-static void
-parse_float (data)
-  PTR data;
-{
-  struct pf_args * args = (struct pf_args *) data;
-  const char *typename;
-
-  args->conversion_errno = 0;
-  args->type = double_type_node;
-  typename = "double";
-
-  /* The second argument, machine_mode, of REAL_VALUE_ATOF
-     tells the desired precision of the binary result
-     of decimal-to-binary conversion.  */
-
-  if (args->fflag)
-    {
-      if (args->lflag)
-       error ("both 'f' and 'l' suffixes on floating constant");
-
-      args->type = float_type_node;
-      typename = "float";
-    }
-  else if (args->lflag)
-    {
-      args->type = long_double_type_node;
-      typename = "long double";
-    }
-  else if (flag_single_precision_constant)
-    {
-      args->type = float_type_node;
-      typename = "float";
-    }
-
-  errno = 0;
-  if (args->base == 16)
-    args->value = REAL_VALUE_HTOF (args->str, TYPE_MODE (args->type));
-  else
-    args->value = REAL_VALUE_ATOF (args->str, TYPE_MODE (args->type));
-
-  args->conversion_errno = errno;
-  /* A diagnostic is required here by some ISO C testsuites.
-     This is not pedwarn, because some people don't want
-     an error for this.  */
-  if (REAL_VALUE_ISINF (args->value) && pedantic)
-    warning ("floating point number exceeds range of '%s'", typename);
-}
 int
 c_lex (value)
      tree *value;
@@ -783,9 +706,6 @@ c_lex (value)
   *value = NULL_TREE;
   switch (tok->type)
     {
-    case CPP_OPEN_BRACE:  indent_level++;  break;
-    case CPP_CLOSE_BRACE: indent_level--;  break;
-
     /* Issue this error here, where we can get at tok->val.c.  */
     case CPP_OTHER:
       if (ISGRAPH (tok->val.c))
@@ -972,14 +892,11 @@ lex_number (str, len)
   if (floatflag != NOT_FLOAT)
     {
       tree type;
-      int imag, fflag, lflag, conversion_errno;
+      const char *typename;
+      int imag, fflag, lflag;
       REAL_VALUE_TYPE real;
-      struct pf_args args;
       char *copy;
 
-      if (base == 16 && pedantic && !flag_isoc99)
-       pedwarn ("floating constant may not be in radix 16");
-
       if (base == 16 && floatflag != AFTER_EXPON)
        ERROR ("hexadecimal floating constant has no exponent");
 
@@ -1044,34 +961,45 @@ lex_number (str, len)
            ERROR ("invalid suffix on floating constant");
          }
 
-      /* Setup input for parse_float() */
-      args.str = copy;
-      args.fflag = fflag;
-      args.lflag = lflag;
-      args.base = base;
+      type = double_type_node;
+      typename = "double";
+       
+      if (fflag)
+       {
+         if (lflag)
+           ERROR ("both 'f' and 'l' suffixes on floating constant");
 
-      /* Convert string to a double, checking for overflow.  */
-      if (do_float_handler (parse_float, (PTR) &args))
+         type = float_type_node;
+         typename = "float";
+       }
+      else if (lflag)
+       {
+         type = long_double_type_node;
+         typename = "long double";
+       }
+      else if (flag_single_precision_constant)
        {
-         /* Receive output from parse_float() */
-         real = args.value;
+         type = float_type_node;
+         typename = "float";
        }
+
+      /* Warn about this only after we know we're not issuing an error.  */
+      if (base == 16 && pedantic && !flag_isoc99)
+       pedwarn ("hexadecimal floating constants are only valid in C99");
+
+      /* The second argument, machine_mode, of REAL_VALUE_ATOF
+        tells the desired precision of the binary result
+        of decimal-to-binary conversion.  */
+      if (base == 16)
+       real = REAL_VALUE_HTOF (copy, TYPE_MODE (type));
       else
-         /* We got an exception from parse_float() */
-         ERROR ("floating constant out of range");
-
-      /* Receive output from parse_float() */
-      conversion_errno = args.conversion_errno;
-      type = args.type;
-           
-#ifdef ERANGE
-      /* ERANGE is also reported for underflow,
-        so test the value to distinguish overflow from that.  */
-      if (conversion_errno == ERANGE && pedantic
-         && (REAL_VALUES_LESS (dconst1, real)
-             || REAL_VALUES_LESS (real, dconstm1)))
+       real = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+
+      /* A diagnostic is required here by some ISO C testsuites.
+        This is not pedwarn, because some people don't want
+        an error for this.  */
+      if (REAL_VALUE_ISINF (real) && pedantic)
        warning ("floating point number exceeds range of 'double'");
-#endif
 
       /* Create a node with determined type and value.  */
       if (imag)
@@ -1292,9 +1220,7 @@ lex_string (str, len, wide)
   char *buf = alloca ((len + 1) * (wide ? WCHAR_BYTES : 1));
   char *q = buf;
   const unsigned char *p = str, *limit = str + len;
-  unsigned int c;
-  unsigned width = wide ? WCHAR_TYPE_SIZE
-                       : TYPE_PRECISION (char_type_node);
+  cppchar_t c;
 
 #ifdef MULTIBYTE_CHARS
   /* Reset multibyte conversion state.  */
@@ -1324,18 +1250,10 @@ lex_string (str, len, wide)
 #endif
 
       if (c == '\\' && !ignore_escape_flag)
-       {
-         unsigned int mask;
-
-         if (width < HOST_BITS_PER_INT)
-           mask = ((unsigned int) 1 << width) - 1;
-         else
-           mask = ~0;
-         c = cpp_parse_escape (parse_in, &p, limit, mask);
-       }
+       c = cpp_parse_escape (parse_in, &p, limit, wide);
        
-      /* Add this single character into the buffer either as a wchar_t
-        or as a single byte.  */
+      /* Add this single character into the buffer either as a wchar_t,
+        a multibyte sequence, or as a single byte.  */
       if (wide)
        {
          unsigned charwidth = TYPE_PRECISION (char_type_node);
@@ -1356,6 +1274,16 @@ lex_string (str, len, wide)
            }
          q += WCHAR_BYTES;
        }
+#ifdef MULTIBYTE_CHARS
+      else if (char_len > 1)
+       {
+         /* We're dealing with a multibyte character. */
+         for ( ; char_len >0; --char_len)
+           {
+             *q++ = *(p - char_len);
+           }
+       }
+#endif
       else
        {
          *q++ = c;
@@ -1389,31 +1317,31 @@ static tree
 lex_charconst (token)
      const cpp_token *token;
 {
-  HOST_WIDE_INT result;
-  tree value;
+  cppchar_t result;
+  tree type, value;
   unsigned int chars_seen;
+  int unsignedp;
  
-  result = cpp_interpret_charconst (parse_in, token, warn_multichar,
-                                   &chars_seen);
+  result = cpp_interpret_charconst (parse_in, token,
+                                   &chars_seen, &unsignedp);
+
+  /* Cast to cppchar_signed_t to get correct sign-extension of RESULT
+     before possibly widening to HOST_WIDE_INT for build_int_2.  */
+  if (unsignedp || (cppchar_signed_t) result >= 0)
+    value = build_int_2 (result, 0);
+  else
+    value = build_int_2 ((cppchar_signed_t) result, -1);
+
   if (token->type == CPP_WCHAR)
-    {
-      value = build_int_2 (result, 0);
-      TREE_TYPE (value) = wchar_type_node;
-    }
+    type = wchar_type_node;
+  /* In C, a character constant has type 'int'.
+     In C++ 'char', but multi-char charconsts have type 'int'.  */
+  else if ((c_language == clk_c || c_language == clk_objective_c)
+          || chars_seen > 1)
+    type = integer_type_node;
   else
-    {
-      if (result < 0)
-       value = build_int_2 (result, -1);
-      else
-       value = build_int_2 (result, 0);
-      /* In C, a character constant has type 'int'.
-        In C++ 'char', but multi-char charconsts have type 'int'.  */
-      if (c_language == clk_cplusplus && chars_seen <= 1)
-       TREE_TYPE (value) = char_type_node;
-      else
-       TREE_TYPE (value) = integer_type_node;
-    }
+    type = char_type_node;
+
+  TREE_TYPE (value) = type;
   return value;
 }