OSDN Git Service

2000-06-26 Joseph S. Myers <jsm28@cam.ac.uk>
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index ab71f78..8b917ff 100644 (file)
@@ -1,5 +1,6 @@
 /* Lexical analyzer for C and Objective C.
-   Copyright (C) 1987, 88, 89, 92, 94-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
+   1998, 1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -33,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "intl.h"
 #include "ggc.h"
+#include "tm_p.h"
 
 /* MULTIBYTE_CHARS support only works for native compilers.
    ??? Ideally what we want is to model widechar support after
@@ -58,7 +60,7 @@ extern cpp_options parse_options;
 FILE *finput;
 #endif
 
-extern void yyprint                    PROTO((FILE *, int, YYSTYPE));
+extern void yyprint                    PARAMS ((FILE *, int, YYSTYPE));
 
 /* The elements of `ridpointers' are identifier nodes
    for the reserved type names and storage classes.
@@ -83,14 +85,14 @@ extern int yy_get_token ();
 #define UNGETC(c) put_back (c)
 
 struct putback_buffer {
-  char *buffer;
+  unsigned char *buffer;
   int   buffer_size;
   int   index;
 };
 
 static struct putback_buffer putback = {NULL, 0, -1};
 
-static inline int getch PROTO ((void));
+static inline int getch PARAMS ((void));
 
 static inline int
 getch ()
@@ -104,7 +106,7 @@ getch ()
   return getc (finput);
 }
 
-static inline void put_back PROTO ((int));
+static inline void put_back PARAMS ((int));
 
 static inline void
 put_back (ch)
@@ -124,16 +126,6 @@ put_back (ch)
 
 int linemode;
 
-/* the declaration found for the last IDENTIFIER token read in.
-   yylex must look this up to detect typedefs, which get token type TYPENAME,
-   so it is left around in case the identifier is not a typedef but is
-   used in a context which makes it a reference to a variable.  */
-tree lastiddecl;
-
-/* Nonzero enables objc features.  */
-
-int doing_objc_thang;
-
 extern int yydebug;
 
 /* File used for outputting assembler code.  */
@@ -159,15 +151,15 @@ static int ignore_escape_flag;
 static int end_of_file;
 
 #ifdef HANDLE_GENERIC_PRAGMAS
-static int handle_generic_pragma       PROTO((int));
+static int handle_generic_pragma       PARAMS ((int));
 #endif /* HANDLE_GENERIC_PRAGMAS */
-static int whitespace_cr               PROTO((int));
-static int skip_white_space            PROTO((int));
-static char *extend_token_buffer       PROTO((const char *));
-static int readescape                  PROTO((int *));
-static void parse_float                        PROTO((PTR));
-static void extend_token_buffer_to     PROTO((int));
-static int read_line_number            PROTO((int *));
+static int whitespace_cr               PARAMS ((int));
+static int skip_white_space            PARAMS ((int));
+static char *extend_token_buffer       PARAMS ((const char *));
+static int readescape                  PARAMS ((int *));
+static void parse_float                        PARAMS ((PTR));
+static void extend_token_buffer_to     PARAMS ((int));
+static int read_line_number            PARAMS ((int *));
 \f
 /* Do not insert generated code into the source, instead, include it.
    This allows us to build gcc automatically even for targets that
@@ -220,9 +212,9 @@ remember_protocol_qualifiers ()
       wordlist[i].name = "oneway";
 }
 \f
-char *
+const char *
 init_parse (filename)
-     char *filename;
+     const char *filename;
 {
 #if !USE_CPPLIB
   /* Open input file.  */
@@ -254,6 +246,8 @@ init_parse (filename)
   cpp_token = CPP_DIRECTIVE;
 #endif
 
+  add_c_tree_codes ();
+  
   init_lex ();
   init_pragma ();
 
@@ -303,6 +297,8 @@ init_lex ()
   ridpointers[(int) RID_CONST] = get_identifier ("const");
   ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict");
   ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
+  ridpointers[(int) RID_BOUNDED] = get_identifier ("__bounded");
+  ridpointers[(int) RID_UNBOUNDED] = get_identifier ("__unbounded");
   ridpointers[(int) RID_AUTO] = get_identifier ("auto");
   ridpointers[(int) RID_STATIC] = get_identifier ("static");
   ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
@@ -339,7 +335,7 @@ init_lex ()
       UNSET_RESERVED_WORD ("iterator");
       UNSET_RESERVED_WORD ("complex");
     }
-  else if (!flag_isoc9x)
+  else if (!flag_isoc99)
     UNSET_RESERVED_WORD ("restrict");
 
   if (flag_no_asm)
@@ -404,6 +400,7 @@ yyprint (file, yychar, yylval)
 \f
 /* Iff C is a carriage return, warn about it - if appropriate -
    and return nonzero.  */
+
 static int
 whitespace_cr (c)
      int c;
@@ -525,7 +522,7 @@ extend_token_buffer (p)
 static int
 pragma_getc ()
 {
-  return GETC();
+  return GETC ();
 }
 
 static void
@@ -638,7 +635,7 @@ check_newline ()
             (if both are defined), in order to give the back
             end a chance to override the interpretation of
             SYSV style pragmas.  */
-         if (HANDLE_PRAGMA (getch, put_back,
+         if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
                             IDENTIFIER_POINTER (yylval.ttype)))
            goto skipline;
 #endif /* HANDLE_PRAGMA */
@@ -675,7 +672,7 @@ check_newline ()
        }
       else if (!strcmp (name, "ident"))
        {
-         /* #ident.  The pedantic warning is now in cccp.c.  */
+         /* #ident.  The pedantic warning is now in cpp.  */
 
          /* Here we have just seen `#ident '.
             A string constant should follow.  */
@@ -758,14 +755,7 @@ linenum:
       goto skipline;
     }
 
-  if (! ggc_p && !TREE_PERMANENT (yylval.ttype))
-    {
-      input_filename
-       = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
-      strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
-    }
-  else
-    input_filename = TREE_STRING_POINTER (yylval.ttype);
+  input_filename = TREE_STRING_POINTER (yylval.ttype);
 
   if (main_input_filename == 0)
     main_input_filename = input_filename;
@@ -948,7 +938,10 @@ readescape (ignore_ptr)
          nonnull = 1;
        }
       if (! nonnull)
-       error ("\\x used with no following hex digits");
+       {
+         warning ("\\x used with no following hex digits");
+         return 'x';
+       }
       else if (count == 0)
        /* Digits are all 0's.  Ok.  */
        ;
@@ -1203,7 +1196,7 @@ parse_float (data)
    next token, which screws up feed_input.  So just return a null
    character.  */
 
-static inline int token_getch PROTO ((void));
+static inline int token_getch PARAMS ((void));
 
 static inline int
 token_getch ()
@@ -1215,7 +1208,7 @@ token_getch ()
   return GETC ();
 }
 
-static inline void token_put_back PROTO ((int));
+static inline void token_put_back PARAMS ((int));
 
 static inline void
 token_put_back (ch)
@@ -1401,10 +1394,10 @@ yylex ()
            /* Only return OBJECTNAME if it is a typedef.  */
            if (doing_objc_thang && value == OBJECTNAME)
              {
-               lastiddecl = lookup_name(yylval.ttype);
+               tree decl = lookup_name(yylval.ttype);
 
-               if (lastiddecl == NULL_TREE
-                   || TREE_CODE (lastiddecl) != TYPE_DECL)
+               if (decl == NULL_TREE
+                   || TREE_CODE (decl) != TYPE_DECL)
                  value = IDENTIFIER;
              }
 
@@ -1423,24 +1416,26 @@ yylex ()
 
       if (value == IDENTIFIER)
        {
+         tree decl;
+
          if (token_buffer[0] == '@')
            error("invalid identifier `%s'", token_buffer);
 
           yylval.ttype = get_identifier (token_buffer);
-         lastiddecl = lookup_name (yylval.ttype);
+         decl = lookup_name (yylval.ttype);
 
-         if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
+         if (decl != 0 && TREE_CODE (decl) == TYPE_DECL)
            value = TYPENAME;
          /* A user-invisible read-only initialized variable
             should be replaced by its value.
             We handle only strings since that's the only case used in C.  */
-         else if (lastiddecl != 0 && TREE_CODE (lastiddecl) == VAR_DECL
-                  && DECL_IGNORED_P (lastiddecl)
-                  && TREE_READONLY (lastiddecl)
-                  && DECL_INITIAL (lastiddecl) != 0
-                  && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST)
+         else if (decl != 0 && TREE_CODE (decl) == VAR_DECL
+                  && DECL_IGNORED_P (decl)
+                  && TREE_READONLY (decl)
+                  && DECL_INITIAL (decl) != 0
+                  && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
            {
-             tree stringval = DECL_INITIAL (lastiddecl);
+             tree stringval = DECL_INITIAL (decl);
 
              /* Copy the string value so that we won't clobber anything
                 if we put something in the TREE_CHAIN of this one.  */
@@ -1624,7 +1619,7 @@ yylex ()
                    floatflag = AFTER_EXPON;
                    break;   /* start of exponent */
                  }
-               else if (c >= 'a')
+               else if (c >= 'a' && c <= 'f')
                  {
                    c = c - 'a' + 10;
                  }
@@ -1786,7 +1781,8 @@ yylex ()
                      {
                        if (spec_long_long)
                          error ("three `l's in integer constant");
-                       else if (pedantic && ! in_system_header && warn_long_long)
+                       else if (pedantic && ! flag_isoc99
+                                && ! in_system_header && warn_long_long)
                          pedwarn ("ANSI C forbids long long integer constants");
                        spec_long_long = 1;
                      }
@@ -1901,7 +1897,11 @@ yylex ()
 
            type = flag_traditional ? traditional_type : ansi_type;
 
-           if (warn_traditional && traditional_type != ansi_type)
+           /* We assume that constants specified in a non-decimal
+              base are bit patterns, and that the programmer really
+              meant what they wrote.  */
+           if (warn_traditional && base == 10
+               && traditional_type != ansi_type)
              {
                if (TYPE_PRECISION (traditional_type)
                    != TYPE_PRECISION (ansi_type))