OSDN Git Service

* java/io/DataInput.java: Merge with Classpath.
[pf3gnuchains/gcc-fork.git] / gcc / c-lex.c
index 971d9cd..8e6582f 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
    1998, 1999, 2000 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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 version.
+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
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -58,7 +58,10 @@ Boston, MA 02111-1307, USA.  */
 static const char *cpp_filename;
 
 /* The current line map.  */
-static struct line_map *map;
+static const struct line_map *map;
+
+/* The line used to refresh the lineno global variable after each token.  */
+static unsigned int src_lineno;
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -89,9 +92,10 @@ static tree lex_string               PARAMS ((const char *, unsigned int, int));
 static tree lex_charconst      PARAMS ((const cpp_token *));
 static void update_header_times        PARAMS ((const char *));
 static int dump_one_header     PARAMS ((splay_tree_node, void *));
+static void cb_line_change     PARAMS ((cpp_reader *, const cpp_token *, int));
 static void cb_ident           PARAMS ((cpp_reader *, unsigned int,
                                         const cpp_string *));
-static void cb_file_change    PARAMS ((cpp_reader *, const cpp_file_change *));
+static void cb_file_change    PARAMS ((cpp_reader *, const struct line_map *));
 static void cb_def_pragma      PARAMS ((cpp_reader *, unsigned int));
 static void cb_define          PARAMS ((cpp_reader *, unsigned int,
                                         cpp_hashnode *));
@@ -125,6 +129,7 @@ init_c_lex (filename)
 
   cb = cpp_get_callbacks (parse_in);
 
+  cb->line_change = cb_line_change;
   cb->ident = cb_ident;
   cb->file_change = cb_file_change;
   cb->def_pragma = cb_def_pragma;
@@ -243,29 +248,40 @@ cb_ident (pfile, line, str)
 #endif
 }
 
+/* Called at the start of every non-empty line.  TOKEN is the first
+   lexed token on the line.  Used for diagnostic line numbers.  */
+static void
+cb_line_change (pfile, token, parsing_args)
+     cpp_reader *pfile ATTRIBUTE_UNUSED;
+     const cpp_token *token;
+     int parsing_args ATTRIBUTE_UNUSED;
+{
+  src_lineno = SOURCE_LINE (map, token->line);
+}
+
 static void
-cb_file_change (pfile, fc)
+cb_file_change (pfile, new_map)
      cpp_reader *pfile ATTRIBUTE_UNUSED;
-     const cpp_file_change *fc;
+     const struct line_map *new_map;
 {
-  unsigned int from_line = SOURCE_LINE (fc->map - 1, fc->line - 1);
+  unsigned int to_line = SOURCE_LINE (new_map, new_map->to_line);
 
-  if (fc->reason == LC_ENTER)
+  if (new_map->reason == LC_ENTER)
     {
       /* Don't stack the main buffer on the input stack;
         we already did in compile_file.  */
-      if (MAIN_FILE_P (fc->map))
-       main_input_filename = fc->map->to_file;
+      if (map == NULL)
+       main_input_filename = new_map->to_file;
       else
        {
-         lineno = from_line;
-         push_srcloc (fc->map->to_file, 1);
+         lineno = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
+         push_srcloc (new_map->to_file, 1);
          input_file_stack->indent_level = indent_level;
-         (*debug_hooks->start_source_file) (lineno, fc->map->to_file);
+         (*debug_hooks->start_source_file) (lineno, new_map->to_file);
 #ifndef NO_IMPLICIT_EXTERN_C
          if (c_header_level)
            ++c_header_level;
-         else if (fc->externc)
+         else if (new_map->sysp == 2)
            {
              c_header_level = 1;
              ++pending_lang_change;
@@ -273,41 +289,36 @@ cb_file_change (pfile, fc)
 #endif
        }
     }
-  else if (fc->reason == LC_LEAVE)
+  else if (new_map->reason == LC_LEAVE)
     {
-      /* Popping out of a file.  */
-      if (input_file_stack->next)
-       {
 #ifndef NO_IMPLICIT_EXTERN_C
-         if (c_header_level && --c_header_level == 0)
-           {
-             if (fc->externc)
-               warning ("badly nested C headers from preprocessor");
-             --pending_lang_change;
-           }
+      if (c_header_level && --c_header_level == 0)
+       {
+         if (new_map->sysp == 2)
+           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, 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) (from_line);
+      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 ? '}' : '{');
        }
-      else
-       error ("leaving more files than we entered");
+#endif
+      pop_srcloc ();
+      
+      (*debug_hooks->end_source_file) (to_line);
     }
 
-  update_header_times (fc->map->to_file);
-  map = fc->map;
-  in_system_header = fc->sysp != 0;
-  input_filename = map->to_file;
-  lineno = SOURCE_LINE (map, fc->line);
+  update_header_times (new_map->to_file);
+  in_system_header = new_map->sysp != 0;
+  input_filename = new_map->to_file;
+  lineno = to_line;
+  map = new_map;
 
   /* Hook for C++.  */
   extract_interface_info ();
@@ -324,13 +335,13 @@ cb_def_pragma (pfile, line)
   if (warn_unknown_pragmas > in_system_header)
     {
       const unsigned char *space, *name = 0;
-      cpp_token s;
+      const cpp_token *s;
 
-      cpp_get_token (pfile, &s);
-      space = cpp_token_as_text (pfile, &s);
-      cpp_get_token (pfile, &s);
-      if (s.type == CPP_NAME)
-       name = cpp_token_as_text (pfile, &s);
+      s = cpp_get_token (pfile);
+      space = cpp_token_as_text (pfile, s);
+      s = cpp_get_token (pfile);
+      if (s->type == CPP_NAME)
+       name = cpp_token_as_text (pfile, s);
 
       lineno = SOURCE_LINE (map, line);
       if (name)
@@ -756,51 +767,51 @@ int
 c_lex (value)
      tree *value;
 {
-  cpp_token tok;
-  enum cpp_ttype type;
+  const cpp_token *tok;
 
   retry:
   timevar_push (TV_CPP);
-  cpp_get_token (parse_in, &tok);
+  do
+    tok = cpp_get_token (parse_in);
+  while (tok->type == CPP_PADDING);
   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.  */
-  lineno = SOURCE_LINE (map, cpp_get_line (parse_in)->line);
+  lineno = src_lineno;
 
   *value = NULL_TREE;
-  type = tok.type;
-  switch (type)
+  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.  */
+    /* Issue this error here, where we can get at tok->val.c.  */
     case CPP_OTHER:
-      if (ISGRAPH (tok.val.c))
-       error ("stray '%c' in program", tok.val.c);
+      if (ISGRAPH (tok->val.c))
+       error ("stray '%c' in program", tok->val.c);
       else
-       error ("stray '\\%o' in program", tok.val.c);
+       error ("stray '\\%o' in program", tok->val.c);
       goto retry;
       
     case CPP_NAME:
-      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok.val.node));
+      *value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
       break;
 
     case CPP_NUMBER:
-      *value = lex_number ((const char *)tok.val.str.text, tok.val.str.len);
+      *value = lex_number ((const char *)tok->val.str.text, tok->val.str.len);
       break;
 
     case CPP_CHAR:
     case CPP_WCHAR:
-      *value = lex_charconst (&tok);
+      *value = lex_charconst (tok);
       break;
 
     case CPP_STRING:
     case CPP_WSTRING:
-      *value = lex_string ((const char *)tok.val.str.text,
-                          tok.val.str.len, tok.type == CPP_WSTRING);
+      *value = lex_string ((const char *)tok->val.str.text,
+                          tok->val.str.len, tok->type == CPP_WSTRING);
       break;
 
       /* These tokens should not be visible outside cpplib.  */
@@ -812,7 +823,7 @@ c_lex (value)
     default: break;
     }
 
-  return type;
+  return tok->type;
 }
 
 #define ERROR(msgid) do { error(msgid); goto syntax_error; } while(0)