c-lex.c (cb_enter_file, [...]): Combine into the new function cb_change_file.
* c-lex.c (cb_enter_file, cb_leave_file, cb_rename_file): Combine into the new function cb_change_file. (init_c_lex): Update. * cppfiles.c (stack_include_file): Use _cpp_do_file_change. (cpp_syshdr_flags): Delete. * cpphash.h (_cpp_do_file_change): New prototype. Move struct cpp_buffer here from... * cpplib.h (struct cpp_buffer): ... here. (enum cpp_fc_reason, struct cpp_file_loc, struct_cpp_file_change, change_file): New. (enter_file, leave_file, rename_file, cpp_syshdr_flags): Delete. * cpplib.c (do_line): Update for new cb_change_file callback. (_cpp_do_file_change): New function. (_cpp_pop_buffer): Update to use it. * cppmain.c (move_printer): Delete. (main): Set up single callback cb_change_file. (cb_enter_file, cb_leave_file, cb_rename_file): Delete. (cb_change_file): New. * fix-header.c (cur_file, cb_change_file): New. (recognized_function, read_scan_file): Update. * scan-decls.c (scan_decls): Update. * scan.h (recognized_function): Update prototype. From-SVN: r37784
This commit is contained in:
parent
9ccb25d582
commit
27e2564ac8
10 changed files with 271 additions and 476 deletions
|
@ -1,3 +1,28 @@
|
|||
2000-11-27 Neil Booth <neilb@earthling.net>
|
||||
|
||||
* c-lex.c (cb_enter_file, cb_leave_file, cb_rename_file):
|
||||
Combine into the new function cb_change_file.
|
||||
(init_c_lex): Update.
|
||||
* cppfiles.c (stack_include_file): Use _cpp_do_file_change.
|
||||
(cpp_syshdr_flags): Delete.
|
||||
* cpphash.h (_cpp_do_file_change): New prototype.
|
||||
Move struct cpp_buffer here from...
|
||||
* cpplib.h (struct cpp_buffer): ... here.
|
||||
(enum cpp_fc_reason, struct cpp_file_loc,
|
||||
struct_cpp_file_change, change_file): New.
|
||||
(enter_file, leave_file, rename_file, cpp_syshdr_flags): Delete.
|
||||
* cpplib.c (do_line): Update for new cb_change_file callback.
|
||||
(_cpp_do_file_change): New function.
|
||||
(_cpp_pop_buffer): Update to use it.
|
||||
* cppmain.c (move_printer): Delete.
|
||||
(main): Set up single callback cb_change_file.
|
||||
(cb_enter_file, cb_leave_file, cb_rename_file): Delete.
|
||||
(cb_change_file): New.
|
||||
* fix-header.c (cur_file, cb_change_file): New.
|
||||
(recognized_function, read_scan_file): Update.
|
||||
* scan-decls.c (scan_decls): Update.
|
||||
* scan.h (recognized_function): Update prototype.
|
||||
|
||||
2000-11-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* tree.h (mark_tree_hashtable): New function.
|
||||
|
|
371
gcc/c-lex.c
371
gcc/c-lex.c
|
@ -93,9 +93,7 @@ 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 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_change_file PARAMS ((cpp_reader *, const cpp_file_change *));
|
||||
static void cb_def_pragma PARAMS ((cpp_reader *));
|
||||
|
||||
const char *
|
||||
|
@ -125,9 +123,7 @@ init_c_lex (filename)
|
|||
#endif
|
||||
|
||||
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.change_file = cb_change_file;
|
||||
parse_in.cb.def_pragma = cb_def_pragma;
|
||||
|
||||
/* Make sure parse_in.digraphs matches flag_digraphs. */
|
||||
|
@ -218,240 +214,6 @@ dump_time_statistics ()
|
|||
splay_tree_foreach (file_info_tree, dump_one_header, 0);
|
||||
}
|
||||
|
||||
#if 0 /* Keep this code for a while for reference. */
|
||||
static void
|
||||
process_directive ()
|
||||
{
|
||||
enum cpp_ttype token;
|
||||
tree value;
|
||||
int saw_line;
|
||||
enum { act_none, act_push, act_pop } action;
|
||||
int action_number, l;
|
||||
const 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 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"))
|
||||
{
|
||||
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)
|
||||
{
|
||||
ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
|
||||
}
|
||||
#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 if (action == act_pop)
|
||||
{
|
||||
/* Popping out of a file. */
|
||||
if (input_file_stack->next)
|
||||
{
|
||||
#ifndef NO_IMPLICIT_EXTERN_C
|
||||
if (c_header_level && --c_header_level == 0)
|
||||
{
|
||||
if (entering_c_header)
|
||||
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
|
||||
pop_srcloc ();
|
||||
debug_end_source_file (input_file_stack->line);
|
||||
}
|
||||
else
|
||||
error ("#-lines for entering and leaving files don't match");
|
||||
}
|
||||
|
||||
update_header_times (new_file);
|
||||
|
||||
input_filename = new_file;
|
||||
lex_lineno = l;
|
||||
|
||||
/* Hook for C++. */
|
||||
extract_interface_info ();
|
||||
|
||||
/* skip the rest of this line. */
|
||||
skipline:
|
||||
linemode = 0;
|
||||
|
||||
while (getch () != '\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Not yet handled: #pragma, #define, #undef.
|
||||
No need to deal with linemarkers under normal conditions. */
|
||||
|
||||
|
@ -471,93 +233,72 @@ cb_ident (pfile, str)
|
|||
}
|
||||
|
||||
static void
|
||||
cb_enter_file (pfile)
|
||||
cpp_reader *pfile;
|
||||
cb_change_file (pfile, fc)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
const cpp_file_change *fc;
|
||||
{
|
||||
cpp_buffer *ip = CPP_BUFFER (pfile);
|
||||
/* Bleah, need a better interface to this. */
|
||||
const char *flags = cpp_syshdr_flags (pfile, ip);
|
||||
if (fc->from.filename == 0)
|
||||
main_input_filename = fc->to.filename;
|
||||
in_system_header = fc->sysp;
|
||||
|
||||
/* Mustn't stack the main buffer on the input stack. (Ick.) */
|
||||
if (ip->prev)
|
||||
/* Do the actions implied by the preceding numbers. */
|
||||
if (fc->reason == FC_ENTER)
|
||||
{
|
||||
lex_lineno = lineno = ip->prev->lineno - 1;
|
||||
push_srcloc (ip->nominal_fname, 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)
|
||||
/* FIXME. Don't stack the main buffer on the input stack. */
|
||||
if (fc->from.filename)
|
||||
{
|
||||
if (flags[2] != 0)
|
||||
warning ("badly nested C headers from preprocessor");
|
||||
--pending_lang_change;
|
||||
lineno = lex_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)
|
||||
{
|
||||
c_header_level = 1;
|
||||
++pending_lang_change;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (fc->reason == FC_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;
|
||||
}
|
||||
#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 ? '}' : '{');
|
||||
}
|
||||
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);
|
||||
pop_srcloc ();
|
||||
debug_end_source_file (input_file_stack->line);
|
||||
}
|
||||
else
|
||||
error ("leaving more files than we entered");
|
||||
}
|
||||
else if (fc->reason == FC_RENAME)
|
||||
input_filename = fc->to.filename;
|
||||
|
||||
in_system_header = (flags[0] != 0);
|
||||
lex_lineno = CPP_BUFFER (pfile)->lineno;
|
||||
update_header_times (fc->to.filename);
|
||||
|
||||
update_header_times (input_file_stack->name);
|
||||
/* Hook for C++. */
|
||||
extract_interface_info ();
|
||||
}
|
||||
input_filename = fc->to.filename;
|
||||
lex_lineno = fc->to.lineno;
|
||||
|
||||
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 = ip->nominal_fname;
|
||||
lex_lineno = ip->lineno;
|
||||
in_system_header = (flags[0] != 0);
|
||||
|
||||
update_header_times (ip->nominal_fname);
|
||||
/* Hook for C++. */
|
||||
extract_interface_info ();
|
||||
}
|
||||
|
|
|
@ -212,8 +212,16 @@ stack_include_file (pfile, inc)
|
|||
cpp_reader *pfile;
|
||||
struct include_file *inc;
|
||||
{
|
||||
const char *filename = 0;
|
||||
unsigned int lineno = 0;
|
||||
cpp_buffer *fp;
|
||||
|
||||
if (pfile->buffer)
|
||||
{
|
||||
filename = pfile->buffer->nominal_fname;
|
||||
lineno = pfile->buffer->lineno;
|
||||
}
|
||||
|
||||
if (pfile->context->prev)
|
||||
cpp_ice (pfile, "attempt to push file buffer with contexts stacked");
|
||||
|
||||
|
@ -237,7 +245,7 @@ stack_include_file (pfile, inc)
|
|||
fp->buf = inc->buffer;
|
||||
fp->rlimit = fp->buf + inc->st.st_size;
|
||||
fp->cur = fp->buf;
|
||||
fp->lineno = 1;
|
||||
fp->lineno = 0;
|
||||
fp->line_base = fp->buf;
|
||||
|
||||
/* The ->actual_dir field is only used when ignore_srcdir is not in effect;
|
||||
|
@ -249,9 +257,9 @@ stack_include_file (pfile, inc)
|
|||
pfile->include_depth++;
|
||||
pfile->input_stack_listing_current = 0;
|
||||
|
||||
if (pfile->cb.enter_file)
|
||||
(*pfile->cb.enter_file) (pfile);
|
||||
_cpp_do_file_change (pfile, FC_ENTER, filename, lineno);
|
||||
|
||||
fp->lineno = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -531,20 +539,6 @@ cpp_make_system_header (pfile, pbuf, flag)
|
|||
pbuf->inc->sysp = flag;
|
||||
}
|
||||
|
||||
const char *
|
||||
cpp_syshdr_flags (pfile, pbuf)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
cpp_buffer *pbuf;
|
||||
{
|
||||
#ifndef NO_IMPLICIT_EXTERN_C
|
||||
if (CPP_OPTION (pfile, cplusplus) && pbuf->inc->sysp == 2)
|
||||
return " 3 4";
|
||||
#endif
|
||||
if (pbuf->inc->sysp)
|
||||
return " 3";
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Report on all files that might benefit from a multiple include guard.
|
||||
Triggered by -H. */
|
||||
void
|
||||
|
|
|
@ -98,6 +98,58 @@ struct include_file
|
|||
((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
|
||||
|| ((inc)->cmacro->type == NT_MACRO) == (inc)->defined))
|
||||
|
||||
struct cpp_buffer
|
||||
{
|
||||
const unsigned char *cur; /* current position */
|
||||
const unsigned char *rlimit; /* end of valid data */
|
||||
const unsigned char *line_base; /* start of current line */
|
||||
cppchar_t read_ahead; /* read ahead character */
|
||||
cppchar_t extra_char; /* extra read-ahead for long tokens. */
|
||||
|
||||
struct cpp_reader *pfile; /* Owns this buffer. */
|
||||
struct cpp_buffer *prev;
|
||||
|
||||
const unsigned char *buf; /* entire buffer */
|
||||
|
||||
/* Filename specified with #line command. */
|
||||
const char *nominal_fname;
|
||||
|
||||
/* Actual directory of this file, used only for "" includes */
|
||||
struct file_name_list *actual_dir;
|
||||
|
||||
/* Pointer into the include table. Used for include_next and
|
||||
to record control macros. */
|
||||
struct include_file *inc;
|
||||
|
||||
/* Value of if_stack at start of this file.
|
||||
Used to prohibit unmatched #endif (etc) in an include file. */
|
||||
struct if_stack *if_stack;
|
||||
|
||||
/* Token column position adjustment owing to tabs in whitespace. */
|
||||
unsigned int col_adjust;
|
||||
|
||||
/* Line number at line_base (above). */
|
||||
unsigned int lineno;
|
||||
|
||||
/* Because of the way the lexer works, -Wtrigraphs can sometimes
|
||||
warn twice for the same trigraph. This helps prevent that. */
|
||||
const unsigned char *last_Wtrigraphs;
|
||||
|
||||
/* True if we have already warned about C++ comments in this file.
|
||||
The warning happens only for C89 extended mode with -pedantic on,
|
||||
or for -Wtraditional, and only once per file (otherwise it would
|
||||
be far too noisy). */
|
||||
unsigned char warned_cplusplus_comments;
|
||||
|
||||
/* True if we don't process trigraphs and escaped newlines. True
|
||||
for preprocessed input, command line directives, and _Pragma
|
||||
buffers. */
|
||||
unsigned char from_stage3;
|
||||
|
||||
/* Temporary storage for pfile->skipping whilst in a directive. */
|
||||
unsigned char was_skipping;
|
||||
};
|
||||
|
||||
/* Character classes.
|
||||
If the definition of `numchar' looks odd to you, please look up the
|
||||
definition of a pp-number in the C standard [section 6.4.8 of C99].
|
||||
|
@ -208,6 +260,8 @@ extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
|
|||
extern void _cpp_init_stacks PARAMS ((cpp_reader *));
|
||||
extern void _cpp_cleanup_stacks PARAMS ((cpp_reader *));
|
||||
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
|
||||
extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum cpp_fc_reason,
|
||||
const char *, unsigned int));
|
||||
|
||||
/* Utility routines and macros. */
|
||||
#define DSC(str) (const U_CHAR *)str, sizeof str - 1
|
||||
|
|
96
gcc/cpplib.c
96
gcc/cpplib.c
|
@ -718,13 +718,17 @@ static void
|
|||
do_line (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
cpp_buffer *ip = CPP_BUFFER (pfile);
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
const char *filename = buffer->nominal_fname;
|
||||
unsigned int lineno = buffer->lineno;
|
||||
enum cpp_fc_reason reason = (enum cpp_fc_reason) -1;
|
||||
unsigned long new_lineno;
|
||||
/* C99 raised the minimum limit on #line numbers. */
|
||||
unsigned int cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
|
||||
int enter = 0, leave = 0, rename = 0;
|
||||
unsigned int cap;
|
||||
cpp_token token;
|
||||
|
||||
/* C99 raised the minimum limit on #line numbers. */
|
||||
cap = CPP_OPTION (pfile, c99) ? 2147483647 : 32767;
|
||||
|
||||
/* #line commands expand macros. */
|
||||
cpp_get_token (pfile, &token);
|
||||
if (token.type != CPP_NUMBER
|
||||
|
@ -739,32 +743,24 @@ do_line (pfile)
|
|||
cpp_pedwarn (pfile, "line number out of range");
|
||||
|
||||
cpp_get_token (pfile, &token);
|
||||
|
||||
if (token.type != CPP_EOF)
|
||||
if (token.type == CPP_STRING)
|
||||
{
|
||||
char *fname;
|
||||
unsigned int len;
|
||||
int action_number = 0;
|
||||
|
||||
if (token.type != CPP_STRING)
|
||||
{
|
||||
cpp_error (pfile, "\"%s\" is not a valid filename",
|
||||
cpp_token_as_text (pfile, &token));
|
||||
return;
|
||||
}
|
||||
|
||||
len = token.val.str.len;
|
||||
fname = alloca (len + 1);
|
||||
memcpy (fname, token.val.str.text, len);
|
||||
fname[len] = '\0';
|
||||
|
||||
if (strcmp (fname, ip->nominal_fname))
|
||||
if (strcmp (fname, buffer->nominal_fname))
|
||||
{
|
||||
rename = 1;
|
||||
if (!strcmp (fname, ip->inc->name))
|
||||
ip->nominal_fname = ip->inc->name;
|
||||
reason = FC_RENAME;
|
||||
if (!strcmp (fname, buffer->inc->name))
|
||||
buffer->nominal_fname = buffer->inc->name;
|
||||
else
|
||||
ip->nominal_fname = _cpp_fake_include (pfile, fname);
|
||||
buffer->nominal_fname = _cpp_fake_include (pfile, fname);
|
||||
}
|
||||
|
||||
if (read_line_number (pfile, &action_number) != 0)
|
||||
|
@ -774,39 +770,66 @@ do_line (pfile)
|
|||
|
||||
if (action_number == 1)
|
||||
{
|
||||
enter = 1;
|
||||
cpp_make_system_header (pfile, ip, 0);
|
||||
reason = FC_ENTER;
|
||||
cpp_make_system_header (pfile, buffer, 0);
|
||||
read_line_number (pfile, &action_number);
|
||||
}
|
||||
else if (action_number == 2)
|
||||
{
|
||||
leave = 1;
|
||||
cpp_make_system_header (pfile, ip, 0);
|
||||
reason = FC_LEAVE;
|
||||
cpp_make_system_header (pfile, buffer, 0);
|
||||
read_line_number (pfile, &action_number);
|
||||
}
|
||||
if (action_number == 3)
|
||||
{
|
||||
cpp_make_system_header (pfile, ip, 1);
|
||||
cpp_make_system_header (pfile, buffer, 1);
|
||||
read_line_number (pfile, &action_number);
|
||||
}
|
||||
if (action_number == 4)
|
||||
{
|
||||
cpp_make_system_header (pfile, ip, 2);
|
||||
cpp_make_system_header (pfile, buffer, 2);
|
||||
read_line_number (pfile, &action_number);
|
||||
}
|
||||
}
|
||||
|
||||
check_eol (pfile);
|
||||
}
|
||||
else if (token.type != CPP_EOF)
|
||||
{
|
||||
cpp_error (pfile, "\"%s\" is not a valid filename",
|
||||
cpp_token_as_text (pfile, &token));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Our line number is incremented after the directive is processed. */
|
||||
ip->lineno = new_lineno - 1;
|
||||
pfile->lexer_pos.output_line = ip->lineno;
|
||||
if (enter && pfile->cb.enter_file)
|
||||
(*pfile->cb.enter_file) (pfile);
|
||||
if (leave && pfile->cb.leave_file)
|
||||
(*pfile->cb.leave_file) (pfile);
|
||||
if (rename && pfile->cb.rename_file)
|
||||
(*pfile->cb.rename_file) (pfile);
|
||||
buffer->lineno = new_lineno - 1;
|
||||
if (reason != (enum cpp_fc_reason) -1)
|
||||
_cpp_do_file_change (pfile, reason, filename, lineno);
|
||||
}
|
||||
|
||||
/* Arrange the file_change callback. The assumption is that the
|
||||
current buffer's lineno is one less than the next line. */
|
||||
void
|
||||
_cpp_do_file_change (pfile, reason, from_file, from_lineno)
|
||||
cpp_reader *pfile;
|
||||
enum cpp_fc_reason reason;
|
||||
const char *from_file;
|
||||
unsigned int from_lineno;
|
||||
{
|
||||
if (pfile->cb.change_file)
|
||||
{
|
||||
cpp_file_change fc;
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
|
||||
fc.reason = reason;
|
||||
fc.from.filename = from_file;
|
||||
fc.from.lineno = from_lineno;
|
||||
fc.to.filename = buffer->nominal_fname;
|
||||
fc.to.lineno = buffer->lineno + 1;
|
||||
fc.sysp = buffer->inc->sysp;
|
||||
fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->inc->sysp == 2;
|
||||
pfile->cb.change_file (pfile, &fc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1745,8 +1768,10 @@ cpp_pop_buffer (pfile)
|
|||
cpp_reader *pfile;
|
||||
{
|
||||
cpp_buffer *buffer = pfile->buffer;
|
||||
const char *filename = buffer->nominal_fname;
|
||||
unsigned int lineno = buffer->lineno;
|
||||
struct if_stack *ifs = buffer->if_stack;
|
||||
int wfb;
|
||||
int wfb = (buffer->inc != 0);
|
||||
|
||||
/* Walk back up the conditional stack till we reach its level at
|
||||
entry to this file, issuing error messages. */
|
||||
|
@ -1754,7 +1779,6 @@ cpp_pop_buffer (pfile)
|
|||
cpp_error_with_line (pfile, ifs->pos.line, ifs->pos.col,
|
||||
"unterminated #%s", dtable[ifs->type].name);
|
||||
|
||||
wfb = (buffer->inc != 0);
|
||||
if (wfb)
|
||||
_cpp_pop_file_buffer (pfile, buffer);
|
||||
|
||||
|
@ -1762,8 +1786,8 @@ cpp_pop_buffer (pfile)
|
|||
obstack_free (pfile->buffer_ob, buffer);
|
||||
pfile->buffer_stack_depth--;
|
||||
|
||||
if (pfile->buffer && wfb && pfile->cb.leave_file)
|
||||
(*pfile->cb.leave_file) (pfile);
|
||||
if (pfile->buffer && wfb)
|
||||
_cpp_do_file_change (pfile, FC_LEAVE, filename, lineno);
|
||||
|
||||
return pfile->buffer;
|
||||
}
|
||||
|
|
76
gcc/cpplib.h
76
gcc/cpplib.h
|
@ -249,58 +249,6 @@ struct cpp_context
|
|||
same reason we use unsigned char - to avoid signedness issues. */
|
||||
typedef int cppchar_t;
|
||||
|
||||
struct cpp_buffer
|
||||
{
|
||||
const unsigned char *cur; /* current position */
|
||||
const unsigned char *rlimit; /* end of valid data */
|
||||
const unsigned char *line_base; /* start of current line */
|
||||
cppchar_t read_ahead; /* read ahead character */
|
||||
cppchar_t extra_char; /* extra read-ahead for long tokens. */
|
||||
|
||||
struct cpp_reader *pfile; /* Owns this buffer. */
|
||||
struct cpp_buffer *prev;
|
||||
|
||||
const unsigned char *buf; /* entire buffer */
|
||||
|
||||
/* Filename specified with #line command. */
|
||||
const char *nominal_fname;
|
||||
|
||||
/* Actual directory of this file, used only for "" includes */
|
||||
struct file_name_list *actual_dir;
|
||||
|
||||
/* Pointer into the include table. Used for include_next and
|
||||
to record control macros. */
|
||||
struct include_file *inc;
|
||||
|
||||
/* Value of if_stack at start of this file.
|
||||
Used to prohibit unmatched #endif (etc) in an include file. */
|
||||
struct if_stack *if_stack;
|
||||
|
||||
/* Token column position adjustment owing to tabs in whitespace. */
|
||||
unsigned int col_adjust;
|
||||
|
||||
/* Line number at line_base (above). */
|
||||
unsigned int lineno;
|
||||
|
||||
/* Because of the way the lexer works, -Wtrigraphs can sometimes
|
||||
warn twice for the same trigraph. This helps prevent that. */
|
||||
const unsigned char *last_Wtrigraphs;
|
||||
|
||||
/* True if we have already warned about C++ comments in this file.
|
||||
The warning happens only for C89 extended mode with -pedantic on,
|
||||
or for -Wtraditional, and only once per file (otherwise it would
|
||||
be far too noisy). */
|
||||
unsigned char warned_cplusplus_comments;
|
||||
|
||||
/* True if we don't process trigraphs and escaped newlines. True
|
||||
for preprocessed input, command line directives, and _Pragma
|
||||
buffers. */
|
||||
unsigned char from_stage3;
|
||||
|
||||
/* Temporary storage for pfile->skipping whilst in a directive. */
|
||||
unsigned char was_skipping;
|
||||
};
|
||||
|
||||
/* Maximum nesting of cpp_buffers. We use a static limit, partly for
|
||||
efficiency, and partly to limit runaway recursion. */
|
||||
#define CPP_STACK_MAX 200
|
||||
|
@ -523,6 +471,25 @@ struct spec_nodes
|
|||
cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
|
||||
};
|
||||
|
||||
/* This structure is passed to the call back when changing file. */
|
||||
enum cpp_fc_reason {FC_ENTER = 0, FC_LEAVE, FC_RENAME};
|
||||
|
||||
struct cpp_file_loc
|
||||
{
|
||||
const char *filename;
|
||||
unsigned int lineno;
|
||||
};
|
||||
|
||||
typedef struct cpp_file_change cpp_file_change;
|
||||
struct cpp_file_change
|
||||
{
|
||||
struct cpp_file_loc from; /* Line of #include or #line. */
|
||||
struct cpp_file_loc to; /* Line after #include or #line, or start. */
|
||||
enum cpp_fc_reason reason; /* Reason for change. */
|
||||
unsigned char sysp; /* Nonzero if system header. */
|
||||
unsigned char externc; /* Nonzero if wrapper needed. */
|
||||
};
|
||||
|
||||
/* A cpp_reader encapsulates the "state" of a pre-processor run.
|
||||
Applying cpp_get_token repeatedly yields a stream of pre-processor
|
||||
tokens. Usually, there is only one cpp_reader object active. */
|
||||
|
@ -624,9 +591,7 @@ struct cpp_reader
|
|||
|
||||
/* Call backs. */
|
||||
struct {
|
||||
void (*enter_file) PARAMS ((cpp_reader *));
|
||||
void (*leave_file) PARAMS ((cpp_reader *));
|
||||
void (*rename_file) PARAMS ((cpp_reader *));
|
||||
void (*change_file) PARAMS ((cpp_reader *, const cpp_file_change *));
|
||||
void (*include) PARAMS ((cpp_reader *, const unsigned char *,
|
||||
const cpp_token *));
|
||||
void (*define) PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
|
@ -826,7 +791,6 @@ extern void cpp_stop_lookahead PARAMS ((cpp_reader *, int));
|
|||
extern int cpp_included PARAMS ((cpp_reader *, const char *));
|
||||
extern int cpp_read_file PARAMS ((cpp_reader *, const char *));
|
||||
extern void cpp_make_system_header PARAMS ((cpp_reader *, cpp_buffer *, int));
|
||||
extern const char *cpp_syshdr_flags PARAMS ((cpp_reader *, cpp_buffer *));
|
||||
|
||||
/* These are inline functions instead of macros so we can get type
|
||||
checking. */
|
||||
|
|
|
@ -46,7 +46,6 @@ static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
|||
|
||||
static void print_line PARAMS ((const char *));
|
||||
static void maybe_print_line PARAMS ((unsigned int));
|
||||
static void move_printer PARAMS ((cpp_reader *, unsigned int, const char *));
|
||||
|
||||
/* Callback routines for the parser. Most of these are active only
|
||||
in specific modes. */
|
||||
|
@ -55,9 +54,7 @@ static void cb_undef PARAMS ((cpp_reader *, cpp_hashnode *));
|
|||
static void cb_include PARAMS ((cpp_reader *, const unsigned char *,
|
||||
const cpp_token *));
|
||||
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_change_file PARAMS ((cpp_reader *, const cpp_file_change *));
|
||||
static void cb_def_pragma PARAMS ((cpp_reader *));
|
||||
static void do_pragma_implementation PARAMS ((cpp_reader *));
|
||||
|
||||
|
@ -108,11 +105,7 @@ main (argc, argv)
|
|||
pfile->cb.ident = cb_ident;
|
||||
pfile->cb.def_pragma = cb_def_pragma;
|
||||
if (! CPP_OPTION (pfile, no_line_commands))
|
||||
{
|
||||
pfile->cb.enter_file = cb_enter_file;
|
||||
pfile->cb.leave_file = cb_leave_file;
|
||||
pfile->cb.rename_file = cb_rename_file;
|
||||
}
|
||||
pfile->cb.change_file = cb_change_file;
|
||||
}
|
||||
|
||||
if (CPP_OPTION (pfile, dump_includes))
|
||||
|
@ -285,18 +278,6 @@ print_line (special_flags)
|
|||
print.lineno, print.last_fname, special_flags, print.syshdr_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
move_printer (pfile, line, special_flags)
|
||||
cpp_reader *pfile;
|
||||
unsigned int line;
|
||||
const char *special_flags;
|
||||
{
|
||||
print.lineno = line;
|
||||
print.last_fname = pfile->buffer->nominal_fname;
|
||||
print.syshdr_flags = cpp_syshdr_flags (pfile, pfile->buffer);
|
||||
print_line (special_flags);
|
||||
}
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
static void
|
||||
|
@ -354,29 +335,33 @@ cb_include (pfile, dir, header)
|
|||
}
|
||||
|
||||
static void
|
||||
cb_enter_file (pfile)
|
||||
cpp_reader *pfile;
|
||||
cb_change_file (pfile, fc)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
const cpp_file_change *fc;
|
||||
{
|
||||
/* Bring current file to correct line (except main file). FIXME: we
|
||||
may be using the same buffer via a # NUMBER "file" 1 directive. */
|
||||
if (pfile->done_initializing && pfile->buffer->prev)
|
||||
maybe_print_line (pfile->buffer->prev->lineno);
|
||||
const char *flags;
|
||||
|
||||
move_printer (pfile, 1, pfile->done_initializing ? " 1": "");
|
||||
}
|
||||
/* Bring current file to correct line (except first file). */
|
||||
if (fc->reason == FC_ENTER && fc->from.filename)
|
||||
maybe_print_line (fc->from.lineno);
|
||||
|
||||
static void
|
||||
cb_leave_file (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
move_printer (pfile, pfile->buffer->lineno + 1, " 2");
|
||||
}
|
||||
print.lineno = fc->to.lineno;
|
||||
print.last_fname = fc->to.filename;
|
||||
if (fc->externc)
|
||||
print.syshdr_flags = " 3 4";
|
||||
else if (fc->sysp)
|
||||
print.syshdr_flags = " 3";
|
||||
else
|
||||
print.syshdr_flags = "";
|
||||
|
||||
static void
|
||||
cb_rename_file (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
move_printer (pfile, pfile->buffer->lineno + 1, "");
|
||||
switch (fc->reason)
|
||||
{
|
||||
case FC_ENTER : flags = fc->from.filename ? " 1": ""; break;
|
||||
case FC_LEAVE : flags = " 2"; break;
|
||||
case FC_RENAME: flags = ""; break;
|
||||
}
|
||||
|
||||
print_line (flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -114,6 +114,7 @@ static char *files_to_ignore[] = {
|
|||
char *inf_buffer;
|
||||
char *inf_limit;
|
||||
char *inf_ptr;
|
||||
static const char *cur_file;
|
||||
|
||||
/* Certain standard files get extra treatment */
|
||||
|
||||
|
@ -198,6 +199,7 @@ static int inf_skip_spaces PARAMS ((int));
|
|||
static int inf_read_upto PARAMS ((sstring *, int));
|
||||
static int inf_scan_ident PARAMS ((sstring *, int));
|
||||
static int check_protection PARAMS ((int *, int *));
|
||||
static void cb_change_file PARAMS ((cpp_reader *, const cpp_file_change *));
|
||||
|
||||
static void
|
||||
add_symbols (flags, names)
|
||||
|
@ -511,18 +513,16 @@ recognized_extern (name)
|
|||
}
|
||||
|
||||
/* Called by scan_decls if it saw a function definition for a function
|
||||
named FNAME, in source file FILE_SEEN on line LINE_SEEN. KIND is
|
||||
'I' for an inline function; 'F' if a normal function declaration
|
||||
preceded by 'extern "C"' (or nested inside 'extern "C"' braces); or
|
||||
'f' for other function declarations. */
|
||||
named FNAME. KIND is 'I' for an inline function; 'F' if a normal
|
||||
function declaration preceded by 'extern "C"' (or nested inside
|
||||
'extern "C"' braces); or 'f' for other function declarations. */
|
||||
|
||||
void
|
||||
recognized_function (fname, line, kind, have_arg_list, file_seen)
|
||||
recognized_function (fname, line, kind, have_arg_list)
|
||||
const cpp_token *fname;
|
||||
unsigned int line;
|
||||
int kind; /* One of 'f' 'F' or 'I' */
|
||||
int have_arg_list;
|
||||
const char *file_seen;
|
||||
{
|
||||
struct partial_proto *partial;
|
||||
int i;
|
||||
|
@ -552,9 +552,9 @@ recognized_function (fname, line, kind, have_arg_list, file_seen)
|
|||
|
||||
/* If the partial prototype was included from some other file,
|
||||
we don't need to patch it up (in this run). */
|
||||
i = strlen (file_seen);
|
||||
i = strlen (cur_file);
|
||||
if (i < inc_filename_length
|
||||
|| strcmp (inc_filename, file_seen + (i - inc_filename_length)) != 0)
|
||||
|| strcmp (inc_filename, cur_file + (i - inc_filename_length)) != 0)
|
||||
return;
|
||||
|
||||
if (fn == NULL)
|
||||
|
@ -597,6 +597,15 @@ check_macro_names (pfile, names)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cb_change_file (pfile, fc)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
const cpp_file_change *fc;
|
||||
{
|
||||
/* Just keep track of current file name. */
|
||||
cur_file = fc->to.filename;
|
||||
}
|
||||
|
||||
static void
|
||||
read_scan_file (in_fname, argc, argv)
|
||||
char *in_fname;
|
||||
|
@ -612,6 +621,7 @@ read_scan_file (in_fname, argc, argv)
|
|||
|
||||
cpp_init (); /* Initialize cpplib. */
|
||||
cpp_reader_init (&scan_in, CLK_GNUC89);
|
||||
scan_in.cb.change_file = cb_change_file;
|
||||
|
||||
/* We are going to be scanning a header file out of its proper context,
|
||||
so ignore warnings and errors. */
|
||||
|
|
|
@ -181,8 +181,7 @@ scan_decls (pfile, argc, argv)
|
|||
cpp_get_line (pfile)->line,
|
||||
(saw_inline ? 'I'
|
||||
: in_extern_C_brace || current_extern_C
|
||||
? 'F' : 'f'), have_arg_list,
|
||||
CPP_BUFFER (pfile)->nominal_fname);
|
||||
? 'F' : 'f'), have_arg_list);
|
||||
cpp_get_token (pfile, &token);
|
||||
if (token.type == CPP_OPEN_BRACE)
|
||||
{
|
||||
|
|
|
@ -61,8 +61,7 @@ extern int scan_string _PARAMS((FILE *, sstring *, int));
|
|||
extern int read_upto _PARAMS((FILE *, sstring *, int));
|
||||
extern unsigned long hash _PARAMS((const char *));
|
||||
extern void recognized_function _PARAMS((const struct cpp_token *,
|
||||
unsigned int, int, int,
|
||||
const char *));
|
||||
unsigned int, int, int));
|
||||
extern void recognized_extern _PARAMS((const struct cpp_token *));
|
||||
extern unsigned int hashstr _PARAMS((const char *, unsigned int));
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue