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"
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;
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 *));
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;
#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;
#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 ();
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)
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. */
default: break;
}
- return type;
+ return tok->type;
}
#define ERROR(msgid) do { error(msgid); goto syntax_error; } while(0)