OSDN Git Service

* init.c (build_new): Allow enumeration types for the array-bounds
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index 7f11604..c147648 100644 (file)
@@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA.  */
 #include "c-pragma.h"
 #include "toplev.h"
 #include "intl.h"
-#include "ggc.h"
 #include "tm_p.h"
 #include "splay-tree.h"
 
@@ -54,15 +53,8 @@ Boston, MA 02111-1307, USA.  */
 #define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ((ENV_VALUE) = getenv (ENV_NAME))
 #endif
 
-#if USE_CPPLIB
-extern cpp_reader  parse_in;
-#else
-/* Stream for reading from the input file.  */
-FILE *finput;
-#endif
-
-/* Private idea of the line number.  See discussion in c_lex().  */
-static int lex_lineno;
+/* The original file name, before changing "-" to "stdin".  */
+static const char *orig_filename;
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -71,52 +63,6 @@ static splay_tree file_info_tree;
 /* Cause the `yydebug' variable to be defined.  */
 #define YYDEBUG 1
 
-#if !USE_CPPLIB
-
-struct putback_buffer
-{
-  unsigned char *buffer;
-  int   buffer_size;
-  int   index;
-};
-
-static struct putback_buffer putback = {NULL, 0, -1};
-
-static inline int getch PARAMS ((void));
-
-static inline int
-getch ()
-{
-  if (putback.index != -1)
-    {
-      int ch = putback.buffer[putback.index];
-      --putback.index;
-      return ch;
-    }
-  return getc (finput);
-}
-
-static inline void put_back PARAMS ((int));
-
-static inline void
-put_back (ch)
-     int ch;
-{
-  if (ch != EOF)
-    {
-      if (putback.index == putback.buffer_size - 1)
-       {
-         putback.buffer_size += 16;
-         putback.buffer = xrealloc (putback.buffer, putback.buffer_size);
-       }
-      putback.buffer[++putback.index] = ch;
-    }
-}
-
-int linemode;
-
-#endif
-
 /* File used for outputting assembler code.  */
 extern FILE *asm_out_file;
 
@@ -126,12 +72,6 @@ extern FILE *asm_out_file;
 /* Number of bytes in a wide character.  */
 #define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
 
-#if !USE_CPPLIB
-static int maxtoken;           /* Current nominal length of token buffer.  */
-static char *token_buffer;     /* Pointer to token buffer.
-                                  Actual allocated length is maxtoken + 2. */
-#endif
-
 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 */
@@ -149,38 +89,26 @@ static tree lex_string             PARAMS ((const char *, unsigned int, int));
 static tree lex_charconst      PARAMS ((const char *, unsigned int, int));
 static void update_header_times        PARAMS ((const char *));
 static int dump_one_header     PARAMS ((splay_tree_node, void *));
-static int mark_splay_tree_node PARAMS ((splay_tree_node, void *));
-static void mark_splay_tree     PARAMS ((void *));
-
-#if !USE_CPPLIB
-static int skip_white_space            PARAMS ((int));
-static char *extend_token_buffer       PARAMS ((const char *));
-static void extend_token_buffer_to     PARAMS ((int));
-static int read_line_number            PARAMS ((int *));
-static void process_directive          PARAMS ((void));
-#else
 static void cb_ident           PARAMS ((cpp_reader *, const cpp_string *));
-static void cb_enter_file      PARAMS ((cpp_reader *));
-static void cb_leave_file      PARAMS ((cpp_reader *));
-static void cb_rename_file     PARAMS ((cpp_reader *));
+static void cb_file_change    PARAMS ((cpp_reader *, const cpp_file_change *));
 static void cb_def_pragma      PARAMS ((cpp_reader *));
-#endif
-
+static void cb_define          PARAMS ((cpp_reader *, cpp_hashnode *));
+static void cb_undef           PARAMS ((cpp_reader *, cpp_hashnode *));
 \f
 const char *
 init_c_lex (filename)
      const char *filename;
 {
+  struct cpp_callbacks *cb;
   struct c_fileinfo *toplevel;
 
+  orig_filename = filename;
+
   /* Set up filename timing.  Must happen before cpp_start_read.  */
   file_info_tree = splay_tree_new ((splay_tree_compare_fn)strcmp,
                                   0,
                                   (splay_tree_delete_value_fn)free);
-  /* Make sure to mark the filenames in the tree for GC.  */
-  ggc_add_root (&file_info_tree, 1, sizeof (file_info_tree), 
-               mark_splay_tree);
-  toplevel = get_fileinfo (ggc_strdup ("<top level>"));
+  toplevel = get_fileinfo ("<top level>");
   if (flag_detailed_statistics)
     {
       header_time = 0;
@@ -194,50 +122,41 @@ init_c_lex (filename)
   GET_ENVIRONMENT (literal_codeset, "LANG");
 #endif
 
-#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
-#else /* !USE_CPPLIB */
+  cb = cpp_get_callbacks (parse_in);
 
-  parse_in.cb.ident = cb_ident;
-  parse_in.cb.enter_file = cb_enter_file;
-  parse_in.cb.leave_file = cb_leave_file;
-  parse_in.cb.rename_file = cb_rename_file;
-  parse_in.cb.def_pragma = cb_def_pragma;
+  cb->ident = cb_ident;
+  cb->file_change = cb_file_change;
+  cb->def_pragma = cb_def_pragma;
 
-  /* Make sure parse_in.digraphs matches flag_digraphs.  */
-  CPP_OPTION (&parse_in, digraphs) = flag_digraphs;
-
-  if (! cpp_start_read (&parse_in, filename))
-    exit (FATAL_EXIT_CODE);    /* cpplib has emitted an error.  */
+  /* Set the debug callbacks if we can use them.  */
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG))
+    {
+      cb->define = cb_define;
+      cb->undef = cb_undef;
+    }
 
   if (filename == 0 || !strcmp (filename, "-"))
     filename = "stdin";
-#endif
 
-#if !USE_CPPLIB
-  maxtoken = 40;
-  token_buffer = (char *) xmalloc (maxtoken + 2);
-#endif
-  /* Start it at 0, because check_newline is called at the very beginning
-     and will increment it to 1.  */
-  lineno = lex_lineno = 0;
+  /* Start it at 0.  */
+  lineno = 0;
 
   return filename;
 }
 
+/* A thin wrapper around the real parser that initializes the 
+   integrated preprocessor after debug output has been initialized.  */
+
+int
+yyparse()
+{
+  if (! cpp_start_read (parse_in, orig_filename))
+    return 1;                  /* cpplib has emitted an error.  */
+
+  return yyparse_1();
+}
+
 struct c_fileinfo *
 get_fileinfo (name)
      const char *name;
@@ -301,328 +220,53 @@ dump_time_statistics ()
   splay_tree_foreach (file_info_tree, dump_one_header, 0);
 }
 
-#if !USE_CPPLIB
-
-/* If C is not whitespace, return C.
-   Otherwise skip whitespace and return first nonwhite char read.  */
-
-static int
-skip_white_space (c)
-     register int c;
-{
-  for (;;)
-    {
-      switch (c)
-       {
-         /* There is no need to process comments or backslash-newline
-             here.  None can occur in the output of cpp.  Do handle \r
-            in case someone sent us a .i file.  */
-
-       case '\n':
-         if (linemode)
-           {
-             put_back (c);
-             return EOF;
-           }
-         c = check_newline ();
-         break;
-
-       case '\r':
-         /* Per C99, horizontal whitespace is just these four characters.  */
-       case ' ':
-       case '\t':
-       case '\f':
-       case '\v':
-         c = getch ();
-         break;
-
-       case '\\':
-         error ("stray '\\' in program");
-         c = getch ();
-         break;
-
-       default:
-         return (c);
-       }
-    }
-}
-
-/* Skips all of the white space at the current location in the input file.  */
-
-void
-position_after_white_space ()
-{
-  register int c;
-
-  c = getch ();
-
-  put_back (skip_white_space (c));
-}
-
-/* Make the token buffer longer, preserving the data in it.
-   P should point to just beyond the last valid character in the old buffer.
-   The value we return is a pointer to the new buffer
-   at a place corresponding to P.  */
+/* Not yet handled: #pragma, #define, #undef.
+   No need to deal with linemarkers under normal conditions.  */
 
 static void
-extend_token_buffer_to (size)
-     int size;
-{
-  do
-    maxtoken = maxtoken * 2 + 10;
-  while (maxtoken < size);
-  token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
-}
-
-static char *
-extend_token_buffer (p)
-     const char *p;
-{
-  int offset = p - token_buffer;
-  extend_token_buffer_to (offset);
-  return token_buffer + offset;
-}
-\f
-
-static int
-read_line_number (num)
-     int *num;
-{
-  tree value;
-  enum cpp_ttype token = c_lex (&value);
-
-  if (token == CPP_NUMBER && TREE_CODE (value) == INTEGER_CST)
-    {
-      *num = TREE_INT_CST_LOW (value);
-      return 1;
-    }
-  else
-    {
-      if (token != CPP_EOF)
-       error ("invalid #-line");
-      return 0;
-    }
-}
-
-/* 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.
-   Otherwise, return the line's first non-whitespace character.  */
-
-int
-check_newline ()
+cb_ident (pfile, str)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+     const cpp_string *str ATTRIBUTE_UNUSED;
 {
-  register int c;
-
-  /* Loop till we get a nonblank, non-directive line.  */
-  for (;;)
+#ifdef ASM_OUTPUT_IDENT
+  if (! flag_no_ident)
     {
-      /* Read first nonwhite char on the line.  */
-      do
-       c = getch ();
-      while (c == ' ' || c == '\t');
-
-      lex_lineno++;
-      if (c == '#')
-       {
-         process_directive ();
-         return '\n';
-       }
-
-      else if (c != '\n')
-       break;
+      /* Convert escapes in the string.  */
+      tree value = lex_string ((const char *)str->text, str->len, 0);
+      ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
     }
-  return c;
+#endif
 }
 
 static void
-process_directive ()
+cb_file_change (pfile, fc)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+     const cpp_file_change *fc;
 {
-  enum cpp_ttype token;
-  tree value;
-  int saw_line;
-  enum { act_none, act_push, act_pop } action;
-  int action_number, l;
-  char *new_file;
-#ifndef NO_IMPLICIT_EXTERN_C
-  int entering_c_header = 0;
-#endif
-  
-  /* Don't read beyond this line.  */
-  saw_line = 0;
-  linemode = 1;
-  
-  token = c_lex (&value);
-
-  if (token == CPP_NAME)
+  if (fc->reason == FC_ENTER)
     {
-      /* If a letter follows, then if the word here is `line', skip
-        it and ignore it; otherwise, ignore the line, with an error
-        if the word isn't `pragma'.  */
-
-      const char *name = IDENTIFIER_POINTER (value);
-
-      if (!strcmp (name, "pragma"))
-       {
-         dispatch_pragma ();
-         goto skipline;
-       }
-      else if (!strcmp (name, "define"))
-       {
-         debug_define (lex_lineno, GET_DIRECTIVE_LINE ());
-         goto skipline;
-       }
-      else if (!strcmp (name, "undef"))
+      /* Don't stack the main buffer on the input stack;
+        we already did in compile_file.  */
+      if (fc->from.filename)
        {
-         debug_undef (lex_lineno, GET_DIRECTIVE_LINE ());
-         goto skipline;
-       }
-      else if (!strcmp (name, "line"))
-       {
-         saw_line = 1;
-         token = c_lex (&value);
-         goto linenum;
-       }
-      else if (!strcmp (name, "ident"))
-       {
-         /* #ident.  We expect a string constant here.
-            The pedantic warning and syntax error are now in cpp.  */
-
-         token = c_lex (&value);
-         if (token != CPP_STRING || TREE_CODE (value) != STRING_CST)
-           goto skipline;
-
-#ifdef ASM_OUTPUT_IDENT
-         if (! flag_no_ident)
+         lineno = fc->from.lineno;
+         push_srcloc (fc->to.filename, 1);
+         input_file_stack->indent_level = indent_level;
+         debug_start_source_file (fc->to.filename);
+#ifndef NO_IMPLICIT_EXTERN_C
+         if (c_header_level)
+           ++c_header_level;
+         else if (fc->externc)
            {
-             ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
+             c_header_level = 1;
+             ++pending_lang_change;
            }
 #endif
-
-         /* Skip the rest of this line.  */
-         goto skipline;
-       }
-
-      error ("undefined or invalid # directive `%s'", name);
-      goto skipline;
-    }
-
-  /* If the # is the only nonwhite char on the line,
-     just ignore it.  Check the new newline.  */
-  if (token == CPP_EOF)
-    goto skipline;
-
-linenum:
-  /* Here we have either `#line' or `# <nonletter>'.
-     In either case, it should be a line number; a digit should follow.  */
-
-  if (token != CPP_NUMBER || TREE_CODE (value) != INTEGER_CST)
-    {
-      error ("invalid #-line");
-      goto skipline;
-    }
-
-  /* subtract one, because it is the following line that
-     gets the specified number */
-
-  l = TREE_INT_CST_LOW (value) - 1;
-
-  /* More follows: it must be a string constant (filename).
-     It would be neat to use cpplib to quickly process the string, but
-     (1) we don't have a handy tokenization of the string, and
-     (2) I don't know how well that would work in the presense
-     of filenames that contain wide characters.  */
-
-  if (saw_line)
-    {
-      /* Don't treat \ as special if we are processing #line 1 "...".
-        If you want it to be treated specially, use # 1 "...".  */
-      ignore_escape_flag = 1;
-    }
-
-  /* Read the string constant.  */
-  token = c_lex (&value);
-
-  ignore_escape_flag = 0;
-
-  if (token == CPP_EOF)
-    {
-      /* No more: store the line number and check following line.  */
-      lex_lineno = l;
-      goto skipline;
-    }
-
-  if (token != CPP_STRING || TREE_CODE (value) != STRING_CST)
-    {
-      error ("invalid #line");
-      goto skipline;
-    }
-
-  new_file = TREE_STRING_POINTER (value);
-
-  if (main_input_filename == 0)
-    main_input_filename = new_file;
-
-  action = act_none;
-  action_number = 0;
-
-  /* Each change of file name
-     reinitializes whether we are now in a system header.  */
-  in_system_header = 0;
-
-  if (!read_line_number (&action_number))
-    {
-      /* Update the name in the top element of input_file_stack.  */
-      if (input_file_stack)
-       input_file_stack->name = input_filename;
-    }
-
-  /* `1' after file name means entering new file.
-     `2' after file name means just left a file.  */
-
-  if (action_number == 1)
-    {
-      action = act_push;
-      read_line_number (&action_number);
-    }
-  else if (action_number == 2)
-    {
-      action = act_pop;
-      read_line_number (&action_number);
-    }
-  if (action_number == 3)
-    {
-      /* `3' after file name means this is a system header file.  */
-      in_system_header = 1;
-      read_line_number (&action_number);
-    }
-#ifndef NO_IMPLICIT_EXTERN_C
-  if (action_number == 4)
-    {
-      /* `4' after file name means this is a C header file.  */
-      entering_c_header = 1;
-      read_line_number (&action_number);
-    }
-#endif
-
-  /* Do the actions implied by the preceding numbers.  */
-  if (action == act_push)
-    {
-      lineno = lex_lineno;
-      push_srcloc (input_filename, 1);
-      input_file_stack->indent_level = indent_level;
-      debug_start_source_file (input_filename);
-#ifndef NO_IMPLICIT_EXTERN_C
-      if (c_header_level)
-       ++c_header_level;
-      else if (entering_c_header)
-       {
-         c_header_level = 1;
-         ++pending_lang_change;
        }
-#endif
+      else
+       main_input_filename = fc->to.filename;
     }
-  else if (action == act_pop)
+  else if (fc->reason == FC_LEAVE)
     {
       /* Popping out of a file.  */
       if (input_file_stack->next)
@@ -630,7 +274,7 @@ linenum:
 #ifndef NO_IMPLICIT_EXTERN_C
          if (c_header_level && --c_header_level == 0)
            {
-             if (entering_c_header)
+             if (fc->externc)
                warning ("badly nested C headers from preprocessor");
              --pending_lang_change;
            }
@@ -639,7 +283,7 @@ linenum:
          if (indent_level != input_file_stack->indent_level)
            {
              warning_with_file_and_line
-               (input_filename, lex_lineno,
+               (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 ? '}' : '{');
@@ -649,133 +293,16 @@ linenum:
          debug_end_source_file (input_file_stack->line);
        }
       else
-       error ("#-lines for entering and leaving files don't match");
+       error ("leaving more files than we entered");
     }
 
-  update_header_times (new_file);
-
-  input_filename = new_file;
-  lex_lineno = l;
+  update_header_times (fc->to.filename);
+  in_system_header = fc->sysp != 0;
+  input_filename = fc->to.filename;
+  lineno = fc->to.lineno;      /* Do we need this?  */
 
   /* Hook for C++.  */
   extract_interface_info ();
-
-  /* skip the rest of this line.  */
- skipline:
-  linemode = 0;
-
-  while (getch () != '\n');
-}
-#else /* USE_CPPLIB */
-
-/* Not yet handled: #pragma, #define, #undef.
-   No need to deal with linemarkers under normal conditions.  */
-
-static void
-cb_ident (pfile, str)
-     cpp_reader *pfile ATTRIBUTE_UNUSED;
-     const cpp_string *str;
-{
-#ifdef ASM_OUTPUT_IDENT
-  if (! flag_no_ident)
-    {
-      /* Convert escapes in the string.  */
-      tree value = lex_string ((const char *)str->text, str->len, 0);
-      ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
-    }
-#endif
-}
-
-static void
-cb_enter_file (pfile)
-     cpp_reader *pfile;
-{
-  cpp_buffer *ip = CPP_BUFFER (pfile);
-  /* Bleah, need a better interface to this.  */
-  const char *flags = cpp_syshdr_flags (pfile, ip);
-
-  /* Mustn't stack the main buffer on the input stack.  (Ick.)  */
-  if (ip->prev)
-    {
-      lex_lineno = lineno = ip->prev->lineno - 1;
-      push_srcloc (ggc_alloc_string (ip->nominal_fname, -1), 1);
-      input_file_stack->indent_level = indent_level;
-      debug_start_source_file (ip->nominal_fname);
-    }
-  else
-    lex_lineno = 1;
-
-  update_header_times (ip->nominal_fname);
-
-  /* Hook for C++.  */
-  extract_interface_info ();
-
-  in_system_header = (flags[0] != 0);
-#ifndef NO_IMPLICIT_EXTERN_C
-  if (c_header_level)
-    ++c_header_level;
-  else if (in_system_header && flags[1] != 0 && flags[2] != 0)
-    {
-      c_header_level = 1;
-      ++pending_lang_change;
-    }
-#endif
-}
-
-static void
-cb_leave_file (pfile)
-     cpp_reader *pfile;
-{
-  /* Bleah, need a better interface to this.  */
-  const char *flags = cpp_syshdr_flags (pfile, CPP_BUFFER (pfile));
-
-  if (input_file_stack->next)
-    {
-#ifndef NO_IMPLICIT_EXTERN_C
-      if (c_header_level && --c_header_level == 0)
-       {
-         if (flags[2] != 0)
-           warning ("badly nested C headers from preprocessor");
-         --pending_lang_change;
-       }
-#endif
-#if 0
-      if (indent_level != input_file_stack->indent_level)
-       {
-         warning_with_file_and_line
-           (input_filename, lex_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
-      /* We get called for the main buffer, but we mustn't pop it.  */
-      pop_srcloc ();
-      debug_end_source_file (input_file_stack->line);
-    }
-
-  in_system_header = (flags[0] != 0);
-  lex_lineno = CPP_BUFFER (pfile)->lineno;
-
-  update_header_times (input_file_stack->name);
-  /* Hook for C++.  */
-  extract_interface_info ();
-}
-
-static void
-cb_rename_file (pfile)
-     cpp_reader *pfile;
-{
-  cpp_buffer *ip = CPP_BUFFER (pfile);
-  /* Bleah, need a better interface to this.  */
-  const char *flags = cpp_syshdr_flags (pfile, ip);
-  input_filename = ggc_alloc_string (ip->nominal_fname, -1);
-  lex_lineno = ip->lineno;
-  in_system_header = (flags[0] != 0);
-
-  update_header_times (ip->nominal_fname);
-  /* Hook for C++.  */
-  extract_interface_info ();
 }
 
 static void
@@ -796,13 +323,31 @@ cb_def_pragma (pfile)
       if (s.type == CPP_NAME)
        name = cpp_token_as_text (pfile, &s);
 
+      lineno = cpp_get_line (parse_in)->line;
       if (name)
        warning ("ignoring #pragma %s %s", space, name);
       else
        warning ("ignoring #pragma %s", space);
     }
 }
-#endif /* USE_CPPLIB */
+
+/* #define callback for DWARF and DWARF2 debug info.  */
+static void
+cb_define (pfile, node)
+     cpp_reader *pfile;
+     cpp_hashnode *node;
+{
+  debug_define (lineno, (const char *) cpp_macro_definition (pfile, node));
+}
+
+/* #undef callback for DWARF and DWARF2 debug info.  */
+static void
+cb_undef (pfile, node)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+     cpp_hashnode *node;
+{
+  debug_undef (lineno, (const char *) node->name);
+}
 
 /* Parse a '\uNNNN' or '\UNNNNNNNN' sequence.
 
@@ -1422,22 +967,20 @@ int
 c_lex (value)
      tree *value;
 {
-#if USE_CPPLIB
   cpp_token tok;
   enum cpp_ttype type;
 
   retry:
   timevar_push (TV_CPP);
-  cpp_get_token (&parse_in, &tok);
+  cpp_get_token (parse_in, &tok);
   timevar_pop (TV_CPP);
 
   /* The C++ front end does horrible things with the current line
      number.  To ensure an accurate line number, we must reset it
      every time we return a token.  */
-  lex_lineno = cpp_get_line (&parse_in)->line;
+  lineno = cpp_get_line (parse_in)->line;
 
   *value = NULL_TREE;
-  lineno = lex_lineno;
   type = tok.type;
   switch (type)
     {
@@ -1485,387 +1028,8 @@ c_lex (value)
     }
 
   return type;
-  
-#else
-  int c;
-  char *p;
-  int wide_flag = 0;
-  int objc_flag = 0;
-  int charconst = 0;
-
-  *value = NULL_TREE;
-
- retry:
-  c = getch ();
-
-  /* Effectively do c = skip_white_space (c)
-     but do it faster in the usual cases.  */
-  while (1)
-    switch (c)
-      {
-      case ' ':
-      case '\t':
-      case '\f':
-      case '\v':
-       c = getch ();
-       break;
-
-      case '\r':
-      case '\n':
-       c = skip_white_space (c);
-      default:
-       goto found_nonwhite;
-      }
- found_nonwhite:
-
-  lineno = lex_lineno;
-
-  switch (c)
-    {
-    case EOF:
-      return CPP_EOF;
-
-    case 'L':
-      /* Capital L may start a wide-string or wide-character constant.  */
-      {
-       register int c1 = getch();
-       if (c1 == '\'')
-         {
-           wide_flag = 1;
-           goto char_constant;
-         }
-       if (c1 == '"')
-         {
-           wide_flag = 1;
-           goto string_constant;
-         }
-       put_back (c1);
-      }
-      goto letter;
-
-    case '@':
-      if (!doing_objc_thang)
-       goto straychar;
-      else
-       {
-         /* '@' may start a constant string object.  */
-         register int c1 = getch ();
-         if (c1 == '"')
-           {
-             objc_flag = 1;
-             goto string_constant;
-           }
-         put_back (c1);
-         /* Fall through to treat '@' as the start of an identifier.  */
-       }
-
-    case 'A':  case 'B':  case 'C':  case 'D':  case 'E':
-    case 'F':  case 'G':  case 'H':  case 'I':  case 'J':
-    case 'K':            case 'M':  case 'N':  case 'O':
-    case 'P':  case 'Q':  case 'R':  case 'S':  case 'T':
-    case 'U':  case 'V':  case 'W':  case 'X':  case 'Y':
-    case 'Z':
-    case 'a':  case 'b':  case 'c':  case 'd':  case 'e':
-    case 'f':  case 'g':  case 'h':  case 'i':  case 'j':
-    case 'k':  case 'l':  case 'm':  case 'n':  case 'o':
-    case 'p':  case 'q':  case 'r':  case 's':  case 't':
-    case 'u':  case 'v':  case 'w':  case 'x':  case 'y':
-    case 'z':
-    case '_':
-    case '$':
-    letter:
-      p = token_buffer;
-      while (ISALNUM (c) || c == '_' || c == '$' || c == '@')
-       {
-         /* Make sure this char really belongs in an identifier.  */
-         if (c == '$')
-           {
-             if (! dollars_in_ident)
-               error ("'$' in identifier");
-             else if (pedantic)
-               pedwarn ("'$' in identifier");
-           }
-
-         if (p >= token_buffer + maxtoken)
-           p = extend_token_buffer (p);
-
-         *p++ = c;
-         c = getch();
-       }
-
-      put_back (c);
-
-      if (p >= token_buffer + maxtoken)
-       p = extend_token_buffer (p);
-      *p = 0;
-
-      *value = get_identifier (token_buffer);
-      return CPP_NAME;
-
-    case '.':
-       {
-         /* It's hard to preserve tokenization on '.' because
-            it could be a symbol by itself, or it could be the
-            start of a floating point number and cpp won't tell us.  */
-         int c1 = getch ();
-         if (c1 == '.')
-           {
-             int c2 = getch ();
-             if (c2 == '.')
-               return CPP_ELLIPSIS;
-
-             put_back (c2);
-             error ("parse error at '..'");
-           }
-         else if (c1 == '*' && c_language == clk_cplusplus)
-           return CPP_DOT_STAR;
-
-         put_back (c1);
-         if (ISDIGIT (c1))
-           goto number;
-       }
-       return CPP_DOT;
-
-    case '0':  case '1':  case '2':  case '3':  case '4':
-    case '5':  case '6':  case '7':  case '8':  case '9':
-    number:
-      p = token_buffer;
-      /* Scan the next preprocessing number.  All C numeric constants
-        are preprocessing numbers, but not all preprocessing numbers
-        are valid numeric constants.  Preprocessing numbers fit the
-        regular expression \.?[0-9]([0-9a-zA-Z_.]|[eEpP][+-])*
-        See C99 section 6.4.8. */
-      for (;;)
-       {
-         if (p >= token_buffer + maxtoken)
-           p = extend_token_buffer (p);
-
-         *p++ = c;
-         c = getch();
-
-         if (c == '+' || c == '-')
-           {
-             int d = p[-1];
-             if (d == 'e' || d == 'E' || d == 'p' || d == 'P')
-               continue;
-           }
-         if (ISALNUM (c) || c == '_' || c == '.')
-           continue;
-         break;
-       }
-      put_back (c);
-
-      *value = lex_number (token_buffer, p - token_buffer);
-      return CPP_NUMBER;
-
-    case '\'':
-    char_constant:
-    charconst = 1;
-
-    case '"':
-    string_constant:
-      {
-       int delimiter = charconst ? '\'' : '"';
-#ifdef MULTIBYTE_CHARS
-       int longest_char = local_mb_cur_max ();
-       (void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
-#endif
-       c = getch ();
-       p = token_buffer + 1;
-
-       while (c != delimiter && c != EOF)
-         {
-           if (p + 2 > token_buffer + maxtoken)
-             p = extend_token_buffer (p);
-
-           /* ignore_escape_flag is set for reading the filename in #line.  */
-           if (!ignore_escape_flag && c == '\\')
-             {
-               *p++ = c;
-               *p++ = getch ();  /* escaped character */
-               c = getch ();
-               continue;
-             }
-           else
-             {
-#ifdef MULTIBYTE_CHARS
-               int i;
-               int char_len = -1;
-               for (i = 0; i < longest_char; ++i)
-                 {
-                   if (p + i >= token_buffer + maxtoken)
-                     p = extend_token_buffer (p);
-                   p[i] = c;
-
-                   char_len = local_mblen (p, i + 1);
-                   if (char_len != -1)
-                     break;
-                   c = getch ();
-                 }
-               if (char_len == -1)
-                 {
-                   /* Replace all except the first byte.  */
-                   put_back (c);
-                   for (--i; i > 0; --i)
-                     put_back (p[i]);
-                   char_len = 1;
-                 }
-               /* mbtowc sometimes needs an extra char before accepting */
-               else if (char_len <= i)
-                 put_back (c);
-
-               p += char_len;
-#else
-               *p++ = c;
-#endif
-               c = getch ();
-             }
-         }
-      }
-
-      if (charconst)
-       {
-         *value =  lex_charconst (token_buffer + 1, p - (token_buffer + 1),
-                                  wide_flag);
-         return wide_flag ? CPP_WCHAR : CPP_CHAR;
-       }
-      else
-       {
-         *value = lex_string (token_buffer + 1, p - (token_buffer + 1),
-                              wide_flag);
-         return wide_flag ? CPP_WSTRING : objc_flag ? CPP_OSTRING : CPP_STRING;
-       }
-
-    case '+':
-    case '-':
-    case '&':
-    case '|':
-    case ':':
-    case '<':
-    case '>':
-    case '*':
-    case '/':
-    case '%':
-    case '^':
-    case '!':
-    case '=':
-      {
-       int c1;
-       enum cpp_ttype type = CPP_EOF;
-
-       switch (c)
-         {
-         case '+': type = CPP_PLUS;    break;
-         case '-': type = CPP_MINUS;   break;
-         case '&': type = CPP_AND;     break;
-         case '|': type = CPP_OR;      break;
-         case ':': type = CPP_COLON;   break;
-         case '<': type = CPP_LESS;    break;
-         case '>': type = CPP_GREATER; break;
-         case '*': type = CPP_MULT;    break;
-         case '/': type = CPP_DIV;     break;
-         case '%': type = CPP_MOD;     break;
-         case '^': type = CPP_XOR;     break;
-         case '!': type = CPP_NOT;     break;
-         case '=': type = CPP_EQ;      break;
-         }
-
-       c1 = getch ();
-
-       if (c1 == '=' && type < CPP_LAST_EQ)
-         return type + (CPP_EQ_EQ - CPP_EQ);
-       else if (c == c1)
-         switch (c)
-           {
-           case '+':   return CPP_PLUS_PLUS;
-           case '-':   return CPP_MINUS_MINUS;
-           case '&':   return CPP_AND_AND;
-           case '|':   return CPP_OR_OR;
-           case ':':
-             if (c_language == clk_cplusplus)
-               return CPP_SCOPE;
-             break;
-
-           case '<':   type = CPP_LSHIFT;      goto do_triad;
-           case '>':   type = CPP_RSHIFT;      goto do_triad;
-           }
-       else
-         switch (c)
-           {
-           case '-':
-             if (c1 == '>')
-               {
-                 if (c_language == clk_cplusplus)
-                   {
-                     c1 = getch ();
-                     if (c1 == '*')
-                       return CPP_DEREF_STAR;
-                     put_back (c1);
-                   }
-                 return CPP_DEREF;
-               }
-             break;
-
-           case '>':
-             if (c1 == '?' && c_language == clk_cplusplus)
-               { type = CPP_MAX; goto do_triad; }
-             break;
-
-           case '<':
-             if (c1 == ':' && flag_digraphs)
-               return CPP_OPEN_SQUARE;
-             if (c1 == '%' && flag_digraphs)
-               { indent_level++; return CPP_OPEN_BRACE; }
-             if (c1 == '?' && c_language == clk_cplusplus)
-               { type = CPP_MIN; goto do_triad; }
-             break;
-
-           case ':':
-             if (c1 == '>' && flag_digraphs)
-               return CPP_CLOSE_SQUARE;
-             break;
-           case '%':
-             if (c1 == '>' && flag_digraphs)
-               { indent_level--; return CPP_CLOSE_BRACE; }
-             break;
-           }
-
-       put_back (c1);
-       return type;
-
-      do_triad:
-       c1 = getch ();
-       if (c1 == '=')
-         type += (CPP_EQ_EQ - CPP_EQ);
-       else
-         put_back (c1);
-       return type;
-      }
-
-    case '~':                  return CPP_COMPL;
-    case '?':                  return CPP_QUERY;
-    case ',':                  return CPP_COMMA;
-    case '(':                  return CPP_OPEN_PAREN;
-    case ')':                  return CPP_CLOSE_PAREN;
-    case '[':                  return CPP_OPEN_SQUARE;
-    case ']':                  return CPP_CLOSE_SQUARE;
-    case '{': indent_level++;  return CPP_OPEN_BRACE;
-    case '}': indent_level--;  return CPP_CLOSE_BRACE;
-    case ';':                  return CPP_SEMICOLON;
-
-    straychar:
-    default:
-      if (ISGRAPH (c))
-       error ("stray '%c' in program", c);
-      else
-       error ("stray '\\%#o' in program", c);
-      goto retry;
-    }
-  /* NOTREACHED */
-#endif
 }
 
-
 #define ERROR(msgid) do { error(msgid); goto syntax_error; } while(0)
 
 static tree
@@ -2061,7 +1225,8 @@ lex_number (str, len)
          case 'f': case 'F':
            if (fflag)
              ERROR ("more than one 'f' suffix on floating constant");
-           else if (warn_traditional && !in_system_header)
+           else if (warn_traditional && !in_system_header
+                    && ! cpp_sys_objmacro_p (parse_in))
              warning ("traditional C rejects the 'f' suffix");
 
            fflag = 1;
@@ -2070,7 +1235,8 @@ lex_number (str, len)
          case 'l': case 'L':
            if (lflag)
              ERROR ("more than one 'l' suffix on floating constant");
-           else if (warn_traditional && !in_system_header)
+           else if (warn_traditional && !in_system_header
+                    && ! cpp_sys_objmacro_p (parse_in))
              warning ("traditional C rejects the 'l' suffix");
 
            lflag = 1;
@@ -2145,7 +1311,8 @@ lex_number (str, len)
            case 'u': case 'U':
              if (spec_unsigned)
                error ("two 'u' suffixes on integer constant");
-             else if (warn_traditional && !in_system_header)
+             else if (warn_traditional && !in_system_header
+                      && ! cpp_sys_objmacro_p (parse_in))
                warning ("traditional C rejects the 'u' suffix");
 
              spec_unsigned = 1;
@@ -2479,7 +1646,7 @@ lex_charconst (str, len, wide)
        }
       else
        {
-         p += char_len;
+         str += char_len;
          c = wc;
        }
 #else
@@ -2550,25 +1717,3 @@ lex_charconst (str, len, wide)
 
   return value;
 }
-
-/* Mark for GC a node in a splay tree whose keys are strings.  */
-
-static int
-mark_splay_tree_node (n, data)
-     splay_tree_node n;
-     void *data ATTRIBUTE_UNUSED;
-{
-  ggc_mark_string ((char *) n->key);
-  return 0;
-}
-
-/* Mark for GC a splay tree whose keys are strings.  */
-
-static void
-mark_splay_tree (p)
-     void *p;
-{
-  splay_tree st = *(splay_tree *) p;
-  
-  splay_tree_foreach (st, mark_splay_tree_node, NULL);
-}