OSDN Git Service

update
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index dc56b86..7612352 100644 (file)
@@ -1,5 +1,5 @@
 /* Lexical analyzer for C and Objective C.
-   Copyright (C) 1987, 88, 89, 92, 94-96, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 92, 94-97, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -19,31 +19,19 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 #include "config.h"
-
-#include <stdio.h>
-#include <errno.h>
+#include "system.h"
 #include <setjmp.h>
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
 
 #include "rtl.h"
 #include "tree.h"
 #include "input.h"
+#include "output.h"
 #include "c-lex.h"
 #include "c-tree.h"
 #include "flags.h"
 #include "c-parse.h"
 #include "c-pragma.h"
-
-#include <ctype.h>
+#include "toplev.h"
 
 /* MULTIBYTE_CHARS support only works for native compilers.
    ??? Ideally what we want is to model widechar support after
@@ -53,19 +41,16 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifdef MULTIBYTE_CHARS
-#include <stdlib.h>
 #include <locale.h>
 #endif
 
-#ifndef errno
-extern int errno;
-#endif
-
 #if USE_CPPLIB
 #include "cpplib.h"
-cpp_reader parse_in;
-cpp_options parse_options;
-static enum cpp_token cpp_token;
+extern cpp_reader  parse_in;
+extern cpp_options parse_options;
+#else
+/* Stream for reading from the input file.  */
+FILE *finput;
 #endif
 
 /* The elements of `ridpointers' are identifier nodes
@@ -77,24 +62,10 @@ tree ridpointers[(int) RID_MAX];
 #define YYDEBUG 1
 
 #if USE_CPPLIB
-static unsigned char *yy_cur, *yy_lim;
-
-int
-yy_get_token ()
-{
-  for (;;)
-    {
-      parse_in.limit = parse_in.token_buffer;
-      cpp_token = cpp_get_token (&parse_in);
-      if (cpp_token == CPP_EOF)
-       return -1;
-      yy_lim = CPP_PWRITTEN (&parse_in);
-      yy_cur = parse_in.token_buffer;
-      if (yy_cur < yy_lim)
-       return *yy_cur++;
-    }
-}
-
+extern unsigned char *yy_cur, *yy_lim;
+  
+extern int yy_get_token ();
+  
 #define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ())
 #define UNGETC(c) ((c), yy_cur--)
 #else
@@ -112,8 +83,6 @@ tree lastiddecl;
 
 int doing_objc_thang;
 
-extern tree is_class_name ();
-
 extern int yydebug;
 
 /* File used for outputting assembler code.  */
@@ -148,7 +117,9 @@ static int nextchar = -1;
 #ifdef HANDLE_SYSV_PRAGMA
 static int handle_sysv_pragma          PROTO((int));
 #endif /* HANDLE_SYSV_PRAGMA */
+static int whitespace_cr               PROTO((int));
 static int skip_white_space            PROTO((int));
+static int skip_white_space_on_line    PROTO((void));
 static char *extend_token_buffer       PROTO((char *));
 static int readescape                  PROTO((int *));
 int check_newline ();
@@ -202,12 +173,30 @@ remember_protocol_qualifiers ()
       wordlist[i].name = "oneway";   
 }
 \f
-#if USE_CPPLIB
-void
+char *
 init_parse (filename)
      char *filename;
 {
+#if !USE_CPPLIB
+  /* Open input file.  */
+  if (filename == 0 || !strcmp (filename, "-"))
+    {
+      finput = stdin;
+      filename = "stdin";
+    }
+  else
+    finput = fopen (filename, "r");
+  if (finput == 0)
+    pfatal_with_name (filename);
+
+#ifdef IO_BUFFER_SIZE
+  setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
+#endif
+#endif /* !USE_CPPLIB */
+
   init_lex ();
+
+#if USE_CPPLIB
   yy_cur = "\n";
   yy_lim = yy_cur+1;
 
@@ -218,14 +207,20 @@ init_parse (filename)
   parse_in.show_column = 1;
   if (! cpp_start_read (&parse_in, filename))
     abort ();
+#endif
+
+  return filename;
 }
 
 void
 finish_parse ()
 {
+#if USE_CPPLIB
   cpp_finish (&parse_in);
-}
+#else
+  fclose (finput);
 #endif
+}
 
 void
 init_lex ()
@@ -330,10 +325,14 @@ yyprint (file, yychar, yylval)
       if (TREE_CODE (t) == INTEGER_CST)
        fprintf (file,
 #if HOST_BITS_PER_WIDE_INT == 64
-#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+                " 0x%x%016x",
+#else
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
                 " 0x%lx%016lx",
 #else
-                " 0x%x%016x",
+                " 0x%llx%016llx",
+#endif
 #endif
 #else
 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
@@ -349,7 +348,7 @@ yyprint (file, yychar, yylval)
 \f
 /* Iff C is a carriage return, warn about it - if appropriate -
    and return nonzero.  */
-int
+static int
 whitespace_cr (c)
      int c;
 {
@@ -484,88 +483,6 @@ extend_token_buffer (p)
   return token_buffer + offset;
 }
 \f
-#if !USE_CPPLIB
-#define GET_DIRECTIVE_LINE() get_directive_line (finput)
-#else /* USE_CPPLIB */
-/* Read the rest of a #-directive from input stream FINPUT.
-   In normal use, the directive name and the white space after it
-   have already been read, so they won't be included in the result.
-   We allow for the fact that the directive line may contain
-   a newline embedded within a character or string literal which forms
-   a part of the directive.
-
-   The value is a string in a reusable buffer.  It remains valid
-   only until the next time this function is called.  */
-
-static char *
-GET_DIRECTIVE_LINE ()
-{
-  static char *directive_buffer = NULL;
-  static unsigned buffer_length = 0;
-  register char *p;
-  register char *buffer_limit;
-  register int looking_for = 0;
-  register int char_escaped = 0;
-
-  if (buffer_length == 0)
-    {
-      directive_buffer = (char *)xmalloc (128);
-      buffer_length = 128;
-    }
-
-  buffer_limit = &directive_buffer[buffer_length];
-
-  for (p = directive_buffer; ; )
-    {
-      int c;
-
-      /* Make buffer bigger if it is full.  */
-      if (p >= buffer_limit)
-        {
-         register unsigned bytes_used = (p - directive_buffer);
-
-         buffer_length *= 2;
-         directive_buffer
-           = (char *)xrealloc (directive_buffer, buffer_length);
-         p = &directive_buffer[bytes_used];
-         buffer_limit = &directive_buffer[buffer_length];
-        }
-
-      c = GETC ();
-
-      /* Discard initial whitespace.  */
-      if ((c == ' ' || c == '\t') && p == directive_buffer)
-       continue;
-
-      /* Detect the end of the directive.  */
-      if (c == '\n' && looking_for == 0)
-       {
-          UNGETC (c);
-         c = '\0';
-       }
-
-      *p++ = c;
-
-      if (c == 0)
-       return directive_buffer;
-
-      /* Handle string and character constant syntax.  */
-      if (looking_for)
-       {
-         if (looking_for == c && !char_escaped)
-           looking_for = 0;    /* Found terminator... stop looking.  */
-       }
-      else
-        if (c == '\'' || c == '"')
-         looking_for = c;      /* Don't stop buffering until we see another
-                                  another one of these (or an EOF).  */
-
-      /* Handle backslash.  */
-      char_escaped = (c == '\\' && ! char_escaped);
-    }
-}
-#endif /* USE_CPPLIB */
-\f
 /* At the beginning of a line, increment the line number
    and process any #-directive on this line.
    If the line is a #-directive, read the entire line and return a newline.
@@ -1242,7 +1159,7 @@ yylex ()
     case '$':
     letter:
       p = token_buffer;
-      while (isalnum (c) || c == '_' || c == '$' || c == '@')
+      while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
        {
          /* Make sure this char really belongs in an identifier.  */
          if (c == '@' && ! doing_objc_thang)
@@ -1354,7 +1271,7 @@ yylex ()
 
        next_c = GETC ();
        UNGETC (next_c);        /* Always undo this lookahead.  */
-       if (!isalnum (next_c) && next_c != '.')
+       if (!ISALNUM (next_c) && next_c != '.')
          {
            token_buffer[0] = (char)c,  token_buffer[1] = '\0';
            yylval.ttype = (c == '0') ? integer_zero_node : integer_one_node;
@@ -1411,7 +1328,7 @@ yylex ()
        /* Read all the digits-and-decimal-points.  */
 
        while (c == '.'
-              || (isalnum (c) && c != 'l' && c != 'L'
+              || (ISALNUM (c) && c != 'l' && c != 'L'
                   && c != 'u' && c != 'U'
                   && c != 'i' && c != 'I' && c != 'j' && c != 'J'
                   && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
@@ -1440,7 +1357,7 @@ yylex ()
                   only when it is followed by a digit.
                   Otherwise, unread the following non-digit
                   and use the '.' as a structural token.  */
-               if (p == token_buffer + 2 && !isdigit (c))
+               if (p == token_buffer + 2 && !ISDIGIT (c))
                  {
                    if (c == '.')
                      {
@@ -1464,7 +1381,7 @@ yylex ()
                /* It is not a decimal point.
                   It should be a digit (perhaps a hex digit).  */
 
-               if (isdigit (c))
+               if (ISDIGIT (c))
                  {
                    c = c - '0';
                  }
@@ -1528,8 +1445,8 @@ yylex ()
        if (floatflag != NOT_FLOAT)
          {
            tree type = double_type_node;
-           int exceeds_double = 0;
            int imag = 0;
+           int conversion_errno = 0;
            REAL_VALUE_TYPE value;
            jmp_buf handler;
 
@@ -1546,9 +1463,9 @@ yylex ()
                    *p++ = c;
                    c = GETC();
                  }
-               if (! isdigit (c))
+               if (! ISDIGIT (c))
                  error ("floating constant exponent has no digits");
-               while (isdigit (c))
+               while (ISDIGIT (c))
                  {
                    if (p >= token_buffer + maxtoken - 3)
                      p = extend_token_buffer (p);
@@ -1558,7 +1475,6 @@ yylex ()
              }
 
            *p = 0;
-           errno = 0;
 
            /* Convert string to a double, checking for overflow.  */
            if (setjmp (handler))
@@ -1628,7 +1544,9 @@ yylex ()
                      error ("both `f' and `l' in floating constant");
 
                    type = float_type_node;
+                   errno = 0;
                    value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+                   conversion_errno = errno;
                    /* A diagnostic is required here by some ANSI C testsuites.
                       This is not pedwarn, become some people don't want
                       an error for this.  */
@@ -1638,13 +1556,17 @@ yylex ()
                else if (lflag)
                  {
                    type = long_double_type_node;
+                   errno = 0;
                    value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+                   conversion_errno = errno;
                    if (REAL_VALUE_ISINF (value) && pedantic)
                      warning ("floating point number exceeds range of `long double'");
                  }
                else
                  {
+                   errno = 0;
                    value = REAL_VALUE_ATOF (copy, TYPE_MODE (type));
+                   conversion_errno = errno;
                    if (REAL_VALUE_ISINF (value) && pedantic)
                      warning ("floating point number exceeds range of `double'");
                  }
@@ -1652,17 +1574,12 @@ yylex ()
                set_float_handler (NULL_PTR);
            }
 #ifdef ERANGE
-           if (errno == ERANGE && !flag_traditional && pedantic)
-             {
-               /* ERANGE is also reported for underflow,
-                  so test the value to distinguish overflow from that.  */
-               if (REAL_VALUES_LESS (dconst1, value)
-                   || REAL_VALUES_LESS (value, dconstm1))
-                 {
-                   warning ("floating point number exceeds range of `double'");
-                   exceeds_double = 1;
-                 }
-             }
+           /* ERANGE is also reported for underflow,
+              so test the value to distinguish overflow from that.  */
+           if (conversion_errno == ERANGE && !flag_traditional && pedantic
+               && (REAL_VALUES_LESS (dconst1, value)
+                   || REAL_VALUES_LESS (value, dconstm1)))
+             warning ("floating point number exceeds range of `double'");
 #endif
 
            /* If the result is not a number, assume it must have been
@@ -1689,6 +1606,7 @@ yylex ()
            int spec_imag = 0;
            int bytes, warn, i;
 
+           traditional_type = ansi_type = type = NULL_TREE;
            while (1)
              {
                if (c == 'u' || c == 'U')
@@ -1862,7 +1780,7 @@ yylex ()
        UNGETC (c);
        *p = 0;
 
-       if (isalnum (c) || c == '.' || c == '_' || c == '$'
+       if (ISALNUM (c) || c == '.' || c == '_' || c == '$'
            || (!flag_traditional && (c == '-' || c == '+')
                && (p[-1] == 'e' || p[-1] == 'E')))
          error ("missing white space after number `%s'", token_buffer);
@@ -1909,7 +1827,7 @@ yylex ()
                    && (unsigned) c >= (1 << width))
                  pedwarn ("escape sequence out of range for character");
 #ifdef MAP_CHARACTER
-               if (isprint (c))
+               if (ISPRINT (c))
                  c = MAP_CHARACTER (c);
 #endif
              }
@@ -1965,12 +1883,12 @@ yylex ()
            else if (TREE_UNSIGNED (char_type_node)
                     || ((result >> (num_bits - 1)) & 1) == 0)
              yylval.ttype
-               = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0
+               = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
                                         >> (HOST_BITS_PER_WIDE_INT - num_bits)),
                               0);
            else
              yylval.ttype
-               = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0
+               = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
                                          >> (HOST_BITS_PER_WIDE_INT - num_bits)),
                               -1);
            TREE_TYPE (yylval.ttype) = integer_type_node;