Commit 93c80368 by Neil Booth Committed by Neil Booth

New macro expander.

2000-10-28  Neil Booth  <neilb@earthling.net>

	New macro expander.

	* cpplib.c (struct answer): New.
	(struct if_stack): Use cpp_lexer_pos rather than line and col.
	Rename cmacro mi_cmacro.
	(struct directive, KANDR, STDC89, EXTENSION, COND, IF_COND, INCL,
	IN_I): New directive and flags.
	(skip_rest_of_line, check_eol, run_directive, glue_header_name,
	parse_answer, parse_assertion, find_answer): New functions.
	(parse_ifdef, detect_if_not_defined, validate_else): Remove.
	(lex_macro_node): New function to replace parse_ifdef and
	get_define_node.

	(_cpp_handle_directive): New function, combines _cpp_check_directive
	and _cpp_check_linemarker.

	(do_define, do_undef, parse_include, do_include, do_import,
	do_include_next, read_line_number, do_line, do_ident, do_pragma,
	do_pragma_once, do_pragma_poison, do_pragma_dependency):
	Update for new token getting interface.

	(do_ifdef, do_ifndef, do_if, do_else, do_endif, push_conditional)
	: Update for new multiple-include optimisation technique.
	(do_elif): Don't forget to invalidate controlling macros.

	(unwind_if_stack, cpp_defined, cpp_push_buffer, cpp_pop_buffer): Update.
	(parse_assertion, parse_answer, find_answer, _cpp_test_assertion):
	Functions to handle assertions with the new token interface.
	(do_assert, do_unassert): Use them.

	(cpp_define, _cpp_define_builtin, cpp_undef, cpp_assert, cpp_unassert):
	Use run_directive.

	(_cpp_init_stacks): Register directive names.  Don't register special
	nodes.

	* cpperror.c (print_containing_files, _cpp_begin_message): Update to
	new position recording regime.
	(cpp_ice, cpp_fatal, cpp_error, cpp_error_with_line, cpp_warning,
	cpp_warning_with_line, cpp_pedwarn, cpp_pedwarn_with_line,
	cpp_pedwarn_with_file_and_line): Update for _cpp_begin_message changes.
	(cpp_type2name): Move to cpplex.c.

	* cppexp.c (parse_charconst): spec_nodes is no longer a pointer.
	(parse_defined): Update to handle new multiple include optimisation
	method.  Remove poisoned identifier warning.
	(parse_assertion, TYPE_NAME): Delete.
	(lex): Update for multiple include optimisation, removal of
	CPP_DEFINED, to use _cpp_test_assertion for assertions and
	cpp_token_as_text.
	(_cpp_parse_expr): Update for MI optimisation, and to use op_as_text.
	(op_as_text): New function, to wrap cpp_token_as_text.

	* cppfiles.c (stack_include_file, _cpp_pop_file_buffer):
	Update for MI optimisation.
	(_cpp_execute_include): Take a token rather than 3 arguments.  Fix
	segfault on diagnostic.
	(_cpp_compare_file_date): Take a token rather than 3 args.
	(cpp_read_file): Work correctly for zero-length files.

	* cpphash.c (_cpp_init_macros, _cpp_cleanup_macros): Rename
	_cpp_init_hashtable and _cpp_cleanup_hashtable.
	(cpp_lookup): Place identifiers at front of identifier pool
	for _cpp_lookup_with_hash.
	(_cpp_lookup_with_hash): Require identifiers to be at the front of
	the identifier pool.  Commit the memory if not already in the
	hash table.

	* cppinit.c (cpp_reader_init): Move cpp_init_completed test to top.
	Initialise various members of cpp_reader, memory pools, and the
	special nodes.
	(cpp_printer_init): Delete.
	(cpp_cleanup): Update.
	(struct builtin, builtin_array, initialize_builtins): Update for new
	hashnode definition and builtin handling.
	(cpp_start_read, cpp_finish): Don't take or initialise a
	printer.  Update.

	* cpplib.h (cpp_printer, cpp_toklist, CPP_DEFINED, BOL,
	PASTED, VAR_ARGS, BEG_OF_FILE, IN_DIRECTIVE, KNOWN_DIRECTIVE,
	T_VOID, T_SPECLINE, T_DATE, T_FILE, T_BASE_FILE, T_INCLUDE_LEVEL,
	T_TIME, T_STDC, T_OPERATOR, T_POISON, T_MACRO, T_ASSERTION): Delete.
	(struct cpp_pool, struct cpp_macro, struct cpp_lexer_pos,
	struct cpp_lookahead, CPP_DHASH, enum mi_state, enum mi_ind,
	NO_EXPAND, VARARGS_FIRST, struct cpp_token_with_pos,
	struct toklist, struct cpp_context, struct specnodes,
	TOKEN_LOOKAHEAD, TOKEN_BUFFSIZE, NODE_OPERATOR, NODE_POISONED,
	NODE_BUILTIN, NODE_DIAGNOSTIC, NT_VOID, NT_MACRO, NT_ASSERTION,
	enum builtin_type, cpp_can_paste): New.
	(struct cpp_token): Delete line and col members.
	(struct cpp_buffer): New member output_lineno.
	(struct lexer_state): Delete indented, in_lex_line, seen_dot.
	Add va_args_ok, poisoned_ok, prevent_expansion, parsing_args.
	(struct cpp_reader): New members lexer_pos, macro_pos, directive_pos,
	ident_pool, temp_string_pool, macro_pool, argument_pool, string_pool,
	base_context, context, directive, mi_state, mi_if_not_defined,
	mi_lexed, mi_cmacro, mi_ind_cmacro, la_read, la_write, la_unused,
	mlstring_pos, macro_buffer, macro_buffer_len.
	Delete members mls_line, mls_column, token_list, potential_control_macro,
	temp_tokens, temp_cap, temp_alloced, temp_used, first_directive_token,
	context_cap, cur_context, no_expand_level, paste_level, contexts, args,
	save_parameter_spellings, need_newline, .
	Change type of date, time and spec_nodes members.
	Change prototypes for include and ident callbacks.
	(struct cpp_hashnode): Change type of name.  Remove union members
	expansion and code.  Add members macro, operator and builtin.

	(cpp_token_len, cpp_token_as_text, cpp_spell_token, cpp_start_read,
	cpp_finish, cpp_avoid_paste, cpp_get_token, cpp_get_line,
	cpp_get_output_line, cpp_macro_definition, cpp_start_lookahead,
	cpp_stop_lookahead): New prototypes.
	(cpp_printer_init, cpp_dump_definition): Delete prototypes.

	(U_CHAR, U, ustrcmp, ustrncmp, ustrlen, uxstrdup, ustrchr, ufputs):
	Move from cpphash.h.

	* cpphash.h (U_CHAR, U, ustrcmp, ustrncmp, ustrlen, uxstrdup, ustrchr,
	ufputs): Move to cpplib.h.
	(enum spell_type, struct token_spelling, _cpp_token_spellings, TOKEN_SPELL,
	TOKEN_NAME, struct answer, FREE_ANSWER, KANDR, STDC89, EXTENSION,
	COND, EXPAND, INCL, COMMENTS, IN_I, struct directive, directive_handler,
	struct spec_nodes, _cpp_digraph_spellings, _cpp_free_temp_tokens,
	_cpp_init_input_buffer, _cpp_grow_token_buffer, _cpp_init_toklist,
	_cpp_clear_toklist, _cpp_expand_token_space, _cpp_expand_name_space,
	_cpp_equiv_tokens, _cpp_equiv_toklists, _cpp_process_directive,
	_cpp_run_directive, _cpp_get_line, _cpp_get_raw_token, _cpp_glue_header_name,
	_cpp_can_paste, _cpp_check_directive, _cpp_check_linemarker,
	_cpp_parse_assertion, _cpp_find_answer): Delete.
	(VALID_SIGN, ALIGN, POOL_FRONT, POOL_LIMIT, POOL_BASE, POOL_SIZE,
	POOL_USED, POOL_COMMIT, struct cpp_chunk, _cpp_lex_token, _cpp_init_pool,
	_cpp_free_pool, _cpp_pool_reserve, _cpp_pool_alloc, _cpp_next_chunk,
	_cpp_lock_pool, _cpp_unlock_pool, _cpp_test_assertion,
	_cpp_handle_directive, DSC): New.
	(struct include_file): New member defined.

	(DO_NOT_REREAD, _cpp_begin_message, _cpp_execute_include,
	_cpp_compare_file_date): Update.
	(_cpp_pop_context, _cpp_get_token, _cpp_free_lookaheads, _cpp_push_token): New.
	(_cpp_init_macros, _cpp_cleanup_macros): Rename to _cpp_init_hashtable,
	_cpp_cleanup_hashtable.

	* Makefile.in: Remove cppoutput.c.

	* cppoutput.c: Delete

	* fixheader.c (read_scan_file): Update for new cpp_get_token
	prototype.
	(recognized_function): New argument LINE.

	* scan-decls.c (skip_to_closing_brace, scan_decls): Update for
	new cpp_get_token prototype.

	* scan.h (recognized_function): Update prototype.

	* po/POTFILES.in: Remove cppoutput.c.

From-SVN: r37098
parent de48b52d
2000-10-28 Neil Booth <neilb@earthling.net>
New macro expander.
* cpplib.c (struct answer): New.
(struct if_stack): Use cpp_lexer_pos rather than line and col.
Rename cmacro mi_cmacro.
(struct directive, KANDR, STDC89, EXTENSION, COND, IF_COND, INCL,
IN_I): New directive and flags.
(skip_rest_of_line, check_eol, run_directive, glue_header_name,
parse_answer, parse_assertion, find_answer): New functions.
(parse_ifdef, detect_if_not_defined, validate_else): Remove.
(lex_macro_node): New function to replace parse_ifdef and
get_define_node.
(_cpp_handle_directive): New function, combines _cpp_check_directive
and _cpp_check_linemarker.
(do_define, do_undef, parse_include, do_include, do_import,
do_include_next, read_line_number, do_line, do_ident, do_pragma,
do_pragma_once, do_pragma_poison, do_pragma_dependency):
Update for new token getting interface.
(do_ifdef, do_ifndef, do_if, do_else, do_endif, push_conditional)
: Update for new multiple-include optimisation technique.
(do_elif): Don't forget to invalidate controlling macros.
(unwind_if_stack, cpp_defined, cpp_push_buffer, cpp_pop_buffer): Update.
(parse_assertion, parse_answer, find_answer, _cpp_test_assertion):
Functions to handle assertions with the new token interface.
(do_assert, do_unassert): Use them.
(cpp_define, _cpp_define_builtin, cpp_undef, cpp_assert, cpp_unassert):
Use run_directive.
(_cpp_init_stacks): Register directive names. Don't register special
nodes.
* cpperror.c (print_containing_files, _cpp_begin_message): Update to
new position recording regime.
(cpp_ice, cpp_fatal, cpp_error, cpp_error_with_line, cpp_warning,
cpp_warning_with_line, cpp_pedwarn, cpp_pedwarn_with_line,
cpp_pedwarn_with_file_and_line): Update for _cpp_begin_message changes.
(cpp_type2name): Move to cpplex.c.
* cppexp.c (parse_charconst): spec_nodes is no longer a pointer.
(parse_defined): Update to handle new multiple include optimisation
method. Remove poisoned identifier warning.
(parse_assertion, TYPE_NAME): Delete.
(lex): Update for multiple include optimisation, removal of
CPP_DEFINED, to use _cpp_test_assertion for assertions and
cpp_token_as_text.
(_cpp_parse_expr): Update for MI optimisation, and to use op_as_text.
(op_as_text): New function, to wrap cpp_token_as_text.
* cppfiles.c (stack_include_file, _cpp_pop_file_buffer):
Update for MI optimisation.
(_cpp_execute_include): Take a token rather than 3 arguments. Fix
segfault on diagnostic.
(_cpp_compare_file_date): Take a token rather than 3 args.
(cpp_read_file): Work correctly for zero-length files.
* cpphash.c (_cpp_init_macros, _cpp_cleanup_macros): Rename
_cpp_init_hashtable and _cpp_cleanup_hashtable.
(cpp_lookup): Place identifiers at front of identifier pool
for _cpp_lookup_with_hash.
(_cpp_lookup_with_hash): Require identifiers to be at the front of
the identifier pool. Commit the memory if not already in the
hash table.
* cppinit.c (cpp_reader_init): Move cpp_init_completed test to top.
Initialise various members of cpp_reader, memory pools, and the
special nodes.
(cpp_printer_init): Delete.
(cpp_cleanup): Update.
(struct builtin, builtin_array, initialize_builtins): Update for new
hashnode definition and builtin handling.
(cpp_start_read, cpp_finish): Don't take or initialise a
printer. Update.
* cpplib.h (cpp_printer, cpp_toklist, CPP_DEFINED, BOL,
PASTED, VAR_ARGS, BEG_OF_FILE, IN_DIRECTIVE, KNOWN_DIRECTIVE,
T_VOID, T_SPECLINE, T_DATE, T_FILE, T_BASE_FILE, T_INCLUDE_LEVEL,
T_TIME, T_STDC, T_OPERATOR, T_POISON, T_MACRO, T_ASSERTION): Delete.
(struct cpp_pool, struct cpp_macro, struct cpp_lexer_pos,
struct cpp_lookahead, CPP_DHASH, enum mi_state, enum mi_ind,
NO_EXPAND, VARARGS_FIRST, struct cpp_token_with_pos,
struct toklist, struct cpp_context, struct specnodes,
TOKEN_LOOKAHEAD, TOKEN_BUFFSIZE, NODE_OPERATOR, NODE_POISONED,
NODE_BUILTIN, NODE_DIAGNOSTIC, NT_VOID, NT_MACRO, NT_ASSERTION,
enum builtin_type, cpp_can_paste): New.
(struct cpp_token): Delete line and col members.
(struct cpp_buffer): New member output_lineno.
(struct lexer_state): Delete indented, in_lex_line, seen_dot.
Add va_args_ok, poisoned_ok, prevent_expansion, parsing_args.
(struct cpp_reader): New members lexer_pos, macro_pos, directive_pos,
ident_pool, temp_string_pool, macro_pool, argument_pool, string_pool,
base_context, context, directive, mi_state, mi_if_not_defined,
mi_lexed, mi_cmacro, mi_ind_cmacro, la_read, la_write, la_unused,
mlstring_pos, macro_buffer, macro_buffer_len.
Delete members mls_line, mls_column, token_list, potential_control_macro,
temp_tokens, temp_cap, temp_alloced, temp_used, first_directive_token,
context_cap, cur_context, no_expand_level, paste_level, contexts, args,
save_parameter_spellings, need_newline, .
Change type of date, time and spec_nodes members.
Change prototypes for include and ident callbacks.
(struct cpp_hashnode): Change type of name. Remove union members
expansion and code. Add members macro, operator and builtin.
(cpp_token_len, cpp_token_as_text, cpp_spell_token, cpp_start_read,
cpp_finish, cpp_avoid_paste, cpp_get_token, cpp_get_line,
cpp_get_output_line, cpp_macro_definition, cpp_start_lookahead,
cpp_stop_lookahead): New prototypes.
(cpp_printer_init, cpp_dump_definition): Delete prototypes.
(U_CHAR, U, ustrcmp, ustrncmp, ustrlen, uxstrdup, ustrchr, ufputs):
Move from cpphash.h.
* cpphash.h (U_CHAR, U, ustrcmp, ustrncmp, ustrlen, uxstrdup, ustrchr,
ufputs): Move to cpplib.h.
(enum spell_type, struct token_spelling, _cpp_token_spellings, TOKEN_SPELL,
TOKEN_NAME, struct answer, FREE_ANSWER, KANDR, STDC89, EXTENSION,
COND, EXPAND, INCL, COMMENTS, IN_I, struct directive, directive_handler,
struct spec_nodes, _cpp_digraph_spellings, _cpp_free_temp_tokens,
_cpp_init_input_buffer, _cpp_grow_token_buffer, _cpp_init_toklist,
_cpp_clear_toklist, _cpp_expand_token_space, _cpp_expand_name_space,
_cpp_equiv_tokens, _cpp_equiv_toklists, _cpp_process_directive,
_cpp_run_directive, _cpp_get_line, _cpp_get_raw_token, _cpp_glue_header_name,
_cpp_can_paste, _cpp_check_directive, _cpp_check_linemarker,
_cpp_parse_assertion, _cpp_find_answer): Delete.
(VALID_SIGN, ALIGN, POOL_FRONT, POOL_LIMIT, POOL_BASE, POOL_SIZE,
POOL_USED, POOL_COMMIT, struct cpp_chunk, _cpp_lex_token, _cpp_init_pool,
_cpp_free_pool, _cpp_pool_reserve, _cpp_pool_alloc, _cpp_next_chunk,
_cpp_lock_pool, _cpp_unlock_pool, _cpp_test_assertion,
_cpp_handle_directive, DSC): New.
(struct include_file): New member defined.
(DO_NOT_REREAD, _cpp_begin_message, _cpp_execute_include,
_cpp_compare_file_date): Update.
(_cpp_pop_context, _cpp_get_token, _cpp_free_lookaheads, _cpp_push_token): New.
(_cpp_init_macros, _cpp_cleanup_macros): Rename to _cpp_init_hashtable,
_cpp_cleanup_hashtable.
* Makefile.in: Remove cppoutput.c.
* cppoutput.c: Delete
* fixheader.c (read_scan_file): Update for new cpp_get_token
prototype.
(recognized_function): New argument LINE.
* scan-decls.c (skip_to_closing_brace, scan_decls): Update for
new cpp_get_token prototype.
* scan.h (recognized_function): Update prototype.
* po/POTFILES.in: Remove cppoutput.c.
2000-10-27 Mark Mitchell <mark@codesourcery.com> 2000-10-27 Mark Mitchell <mark@codesourcery.com>
* c-typeck.c (check_init_type_bitfields): Remove. * c-typeck.c (check_init_type_bitfields): Remove.
......
...@@ -1841,7 +1841,7 @@ PREPROCESSOR_DEFINES = \ ...@@ -1841,7 +1841,7 @@ PREPROCESSOR_DEFINES = \
-DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\"
LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \ LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o \
cpphash.o cpperror.o cppinit.o cppdefault.o cppoutput.o \ cpphash.o cpperror.o cppinit.o cppdefault.o \
mkdeps.o prefix.o version.o mbchar.o mkdeps.o prefix.o version.o mbchar.o
LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
...@@ -1863,7 +1863,6 @@ cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS) ...@@ -1863,7 +1863,6 @@ cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS) defaults.h cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS) defaults.h
cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS) cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS)
cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS) cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS)
cppoutput.o: cppoutput.c $(CONFIG_H) $(LIBCPP_DEPS)
cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H) cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H) cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS) $(OBSTACK_H)
cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
......
...@@ -57,11 +57,10 @@ print_containing_files (pfile, ip) ...@@ -57,11 +57,10 @@ print_containing_files (pfile, ip)
if (first) if (first)
{ {
first = 0; first = 0;
/* N.B. The current line in each outer source file is one /* The current line in each outer source file is now the
greater than the line of the #include, so we must same as the line of the #include. */
subtract one to correct for that. */
fprintf (stderr, _("In file included from %s:%u"), fprintf (stderr, _("In file included from %s:%u"),
ip->nominal_fname, CPP_BUF_LINE (ip) - 1); ip->nominal_fname, CPP_BUF_LINE (ip));
} }
else else
/* Translators note: this message is used in conjunction /* Translators note: this message is used in conjunction
...@@ -107,12 +106,11 @@ print_file_and_line (filename, line, column) ...@@ -107,12 +106,11 @@ print_file_and_line (filename, line, column)
If it returns 0, this error has been suppressed. */ If it returns 0, this error has been suppressed. */
int int
_cpp_begin_message (pfile, code, file, line, col) _cpp_begin_message (pfile, code, file, pos)
cpp_reader *pfile; cpp_reader *pfile;
enum error_type code; enum error_type code;
const char *file; const char *file;
unsigned int line; const cpp_lexer_pos *pos;
unsigned int col;
{ {
cpp_buffer *ip = CPP_BUFFER (pfile); cpp_buffer *ip = CPP_BUFFER (pfile);
int is_warning = 0; int is_warning = 0;
...@@ -177,11 +175,11 @@ _cpp_begin_message (pfile, code, file, line, col) ...@@ -177,11 +175,11 @@ _cpp_begin_message (pfile, code, file, line, col)
{ {
if (file == NULL) if (file == NULL)
file = ip->nominal_fname; file = ip->nominal_fname;
if (line == 0) if (pos == 0)
line = _cpp_get_line (pfile, &col); pos = cpp_get_line (pfile);
print_containing_files (pfile, ip); print_containing_files (pfile, ip);
print_file_and_line (file, line, print_file_and_line (file, pos->line,
CPP_OPTION (pfile, show_column) ? col : 0); CPP_OPTION (pfile, show_column) ? pos->col : 0);
} }
else else
fprintf (stderr, "%s: ", progname); fprintf (stderr, "%s: ", progname);
...@@ -213,7 +211,7 @@ cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...)) ...@@ -213,7 +211,7 @@ cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, ICE, NULL, 0, 0)) if (_cpp_begin_message (pfile, ICE, NULL, 0))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -240,7 +238,7 @@ cpp_fatal VPARAMS ((cpp_reader *pfile, const char *msgid, ...)) ...@@ -240,7 +238,7 @@ cpp_fatal VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, FATAL, NULL, 0, 0)) if (_cpp_begin_message (pfile, FATAL, NULL, 0))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -261,7 +259,7 @@ cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...)) ...@@ -261,7 +259,7 @@ cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, ERROR, NULL, 0, 0)) if (_cpp_begin_message (pfile, ERROR, NULL, 0))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -277,6 +275,7 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column, ...@@ -277,6 +275,7 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column,
const char *msgid; const char *msgid;
#endif #endif
va_list ap; va_list ap;
cpp_lexer_pos pos;
VA_START (ap, msgid); VA_START (ap, msgid);
...@@ -287,7 +286,9 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column, ...@@ -287,7 +286,9 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column,
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, ERROR, NULL, line, column)) pos.line = line;
pos.col = column;
if (_cpp_begin_message (pfile, ERROR, NULL, &pos))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -317,7 +318,7 @@ cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...)) ...@@ -317,7 +318,7 @@ cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, WARNING, NULL, 0, 0)) if (_cpp_begin_message (pfile, WARNING, NULL, 0))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -333,6 +334,7 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column, ...@@ -333,6 +334,7 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
const char *msgid; const char *msgid;
#endif #endif
va_list ap; va_list ap;
cpp_lexer_pos pos;
VA_START (ap, msgid); VA_START (ap, msgid);
...@@ -343,7 +345,9 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column, ...@@ -343,7 +345,9 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, WARNING, NULL, line, column)) pos.line = line;
pos.col = column;
if (_cpp_begin_message (pfile, WARNING, NULL, &pos))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -364,7 +368,7 @@ cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...)) ...@@ -364,7 +368,7 @@ cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, PEDWARN, NULL, 0, 0)) if (_cpp_begin_message (pfile, PEDWARN, NULL, 0))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -380,6 +384,7 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column, ...@@ -380,6 +384,7 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
const char *msgid; const char *msgid;
#endif #endif
va_list ap; va_list ap;
cpp_lexer_pos pos;
VA_START (ap, msgid); VA_START (ap, msgid);
...@@ -390,7 +395,9 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column, ...@@ -390,7 +395,9 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, PEDWARN, NULL, line, column)) pos.line = line;
pos.col = column;
if (_cpp_begin_message (pfile, PEDWARN, NULL, &pos))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -411,6 +418,7 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile, ...@@ -411,6 +418,7 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile,
const char *msgid; const char *msgid;
#endif #endif
va_list ap; va_list ap;
cpp_lexer_pos pos;
VA_START (ap, msgid); VA_START (ap, msgid);
...@@ -422,7 +430,9 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile, ...@@ -422,7 +430,9 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile,
msgid = va_arg (ap, const char *); msgid = va_arg (ap, const char *);
#endif #endif
if (_cpp_begin_message (pfile, PEDWARN, file, line, col)) pos.line = line;
pos.col = col;
if (_cpp_begin_message (pfile, PEDWARN, file, &pos))
v_message (msgid, ap); v_message (msgid, ap);
va_end(ap); va_end(ap);
} }
...@@ -462,11 +472,3 @@ cpp_notice_from_errno (pfile, name) ...@@ -462,11 +472,3 @@ cpp_notice_from_errno (pfile, name)
name = "stdout"; name = "stdout";
cpp_notice (pfile, "%s: %s", name, xstrerror (errno)); cpp_notice (pfile, "%s: %s", name, xstrerror (errno));
} }
const char *
cpp_type2name (type)
enum cpp_ttype type;
{
return (const char *) _cpp_token_spellings[type].name;
}
...@@ -63,10 +63,10 @@ static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, ...@@ -63,10 +63,10 @@ static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT,
static struct op parse_number PARAMS ((cpp_reader *, const cpp_token *)); static struct op parse_number PARAMS ((cpp_reader *, const cpp_token *));
static struct op parse_charconst PARAMS ((cpp_reader *, const cpp_token *)); static struct op parse_charconst PARAMS ((cpp_reader *, const cpp_token *));
static struct op parse_defined PARAMS ((cpp_reader *)); static struct op parse_defined PARAMS ((cpp_reader *));
static struct op parse_assertion PARAMS ((cpp_reader *));
static HOST_WIDEST_INT parse_escape PARAMS ((cpp_reader *, const U_CHAR **, static HOST_WIDEST_INT parse_escape PARAMS ((cpp_reader *, const U_CHAR **,
const U_CHAR *, HOST_WIDEST_INT)); const U_CHAR *, HOST_WIDEST_INT));
static struct op lex PARAMS ((cpp_reader *, int)); static struct op lex PARAMS ((cpp_reader *, int, cpp_token *));
static const unsigned char *op_as_text PARAMS ((cpp_reader *, enum cpp_ttype));
struct op struct op
{ {
...@@ -291,7 +291,7 @@ parse_charconst (pfile, tok) ...@@ -291,7 +291,7 @@ parse_charconst (pfile, tok)
/* If char type is signed, sign-extend the constant. */ /* If char type is signed, sign-extend the constant. */
num_bits = num_chars * width; num_bits = num_chars * width;
if (pfile->spec_nodes->n__CHAR_UNSIGNED__->type != T_VOID if (pfile->spec_nodes.n__CHAR_UNSIGNED__->type == NT_MACRO
|| ((result >> (num_bits - 1)) & 1) == 0) || ((result >> (num_bits - 1)) & 1) == 0)
op.value = result & ((unsigned HOST_WIDEST_INT) ~0 op.value = result & ((unsigned HOST_WIDEST_INT) ~0
>> (HOST_BITS_PER_WIDEST_INT - num_bits)); >> (HOST_BITS_PER_WIDEST_INT - num_bits));
...@@ -313,85 +313,85 @@ static struct op ...@@ -313,85 +313,85 @@ static struct op
parse_defined (pfile) parse_defined (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
int paren; int paren = 0;
const cpp_token *tok; cpp_hashnode *node = 0;
cpp_token token;
struct op op; struct op op;
paren = 0; /* Don't expand macros. */
tok = _cpp_get_raw_token (pfile); pfile->state.prevent_expansion++;
if (tok->type == CPP_OPEN_PAREN)
_cpp_get_token (pfile, &token);
if (token.type == CPP_OPEN_PAREN)
{ {
paren = 1; paren = 1;
tok = _cpp_get_raw_token (pfile); _cpp_get_token (pfile, &token);
} }
if (tok->type != CPP_NAME) if (token.type == CPP_NAME)
SYNTAX_ERROR ("\"defined\" without an identifier"); {
node = token.val.node;
if (paren && _cpp_get_raw_token (pfile)->type != CPP_CLOSE_PAREN) if (paren)
SYNTAX_ERROR ("missing close paren after \"defined\""); {
_cpp_get_token (pfile, &token);
if (tok->val.node->type == T_POISON) if (token.type != CPP_CLOSE_PAREN)
SYNTAX_ERROR2 ("attempt to use poisoned \"%s\"", tok->val.node->name); {
cpp_error (pfile, "missing ')' after \"defined\"");
op.value = tok->val.node->type != T_VOID; node = 0;
op.unsignedp = 0; }
op.op = CPP_INT; }
return op; }
else
syntax_error: cpp_error (pfile, "\"defined\" without an identifier");
op.op = CPP_ERROR;
return op;
}
static struct op
parse_assertion (pfile)
cpp_reader *pfile;
{
struct op op;
struct answer *answer;
cpp_hashnode *hp;
op.op = CPP_ERROR; if (!node)
hp = _cpp_parse_assertion (pfile, &answer); op.op = CPP_ERROR;
if (hp) else
{ {
/* If we get here, the syntax is valid. */ op.value = node->type == NT_MACRO;
op.op = CPP_INT;
op.unsignedp = 0; op.unsignedp = 0;
op.value = (hp->type == T_ASSERTION && op.op = CPP_INT;
(answer == 0 || *_cpp_find_answer (hp, &answer->list) != 0));
if (answer) /* No macros? At top of file? */
FREE_ANSWER (answer); if (pfile->mi_state == MI_OUTSIDE && pfile->mi_cmacro == 0
&& pfile->mi_if_not_defined == MI_IND_NOT && pfile->mi_lexed == 1)
{
cpp_start_lookahead (pfile);
cpp_get_token (pfile, &token);
if (token.type == CPP_EOF)
pfile->mi_ind_cmacro = node;
cpp_stop_lookahead (pfile, 0);
}
} }
pfile->state.prevent_expansion--;
return op; return op;
} }
/* Read one token. */ /* Read one token. */
static struct op static struct op
lex (pfile, skip_evaluation) lex (pfile, skip_evaluation, token)
cpp_reader *pfile; cpp_reader *pfile;
int skip_evaluation; int skip_evaluation;
cpp_token *token;
{ {
struct op op; struct op op;
const cpp_token *tok;
retry: retry:
tok = _cpp_get_token (pfile); _cpp_get_token (pfile, token);
switch (tok->type) switch (token->type)
{ {
case CPP_PLACEMARKER: case CPP_PLACEMARKER:
goto retry; goto retry;
case CPP_INT: case CPP_INT:
case CPP_NUMBER: case CPP_NUMBER:
return parse_number (pfile, tok); return parse_number (pfile, token);
case CPP_CHAR: case CPP_CHAR:
case CPP_WCHAR: case CPP_WCHAR:
return parse_charconst (pfile, tok); return parse_charconst (pfile, token);
case CPP_STRING: case CPP_STRING:
case CPP_WSTRING: case CPP_WSTRING:
...@@ -401,36 +401,60 @@ lex (pfile, skip_evaluation) ...@@ -401,36 +401,60 @@ lex (pfile, skip_evaluation)
SYNTAX_ERROR ("floating point numbers are not valid in #if"); SYNTAX_ERROR ("floating point numbers are not valid in #if");
case CPP_OTHER: case CPP_OTHER:
if (ISGRAPH (tok->val.aux)) if (ISGRAPH (token->val.aux))
SYNTAX_ERROR2 ("invalid character '%c' in #if", tok->val.aux); SYNTAX_ERROR2 ("invalid character '%c' in #if", token->val.aux);
else else
SYNTAX_ERROR2 ("invalid character '\\%03o' in #if", tok->val.aux); SYNTAX_ERROR2 ("invalid character '\\%03o' in #if", token->val.aux);
case CPP_DEFINED:
return parse_defined (pfile);
case CPP_NAME: case CPP_NAME:
if (token->val.node == pfile->spec_nodes.n_defined)
{
if (pfile->context->prev && CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "\"defined\" operator appears during macro expansion");
return parse_defined (pfile);
}
/* Controlling #if expressions cannot contain identifiers (they
could become macros in the future). */
pfile->mi_state = MI_FAILED;
op.op = CPP_INT; op.op = CPP_INT;
op.unsignedp = 0; op.unsignedp = 0;
op.value = 0; op.value = 0;
if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation) if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
cpp_warning (pfile, "\"%s\" is not defined", tok->val.node->name); cpp_warning (pfile, "\"%s\" is not defined", token->val.node->name);
return op; return op;
case CPP_HASH: case CPP_HASH:
return parse_assertion (pfile); {
int temp;
op.op = CPP_INT;
if (_cpp_test_assertion (pfile, &temp))
op.op = CPP_ERROR;
op.unsignedp = 0;
op.value = temp;
return op;
}
case CPP_NOT:
/* We don't worry about its position here. */
pfile->mi_if_not_defined = MI_IND_NOT;
/* Fall through. */
default: default:
if ((tok->type > CPP_EQ && tok->type < CPP_PLUS_EQ) if ((token->type > CPP_EQ && token->type < CPP_PLUS_EQ)
|| tok->type == CPP_EOF) || token->type == CPP_EOF)
{ {
op.op = tok->type; op.op = token->type;
return op; return op;
} }
SYNTAX_ERROR2("'%s' is not valid in #if expressions", TOKEN_NAME (tok)); SYNTAX_ERROR2 ("\"%s\" is not valid in #if expressions",
} cpp_token_as_text (pfile, token));
}
syntax_error: syntax_error:
op.op = CPP_ERROR; op.op = CPP_ERROR;
...@@ -709,8 +733,6 @@ op_to_prio[] = ...@@ -709,8 +733,6 @@ op_to_prio[] =
/* Parse and evaluate a C expression, reading from PFILE. /* Parse and evaluate a C expression, reading from PFILE.
Returns the truth value of the expression. */ Returns the truth value of the expression. */
#define TYPE_NAME(t) _cpp_token_spellings[t].name
int int
_cpp_parse_expr (pfile) _cpp_parse_expr (pfile)
cpp_reader *pfile; cpp_reader *pfile;
...@@ -729,6 +751,7 @@ _cpp_parse_expr (pfile) ...@@ -729,6 +751,7 @@ _cpp_parse_expr (pfile)
struct op init_stack[INIT_STACK_SIZE]; struct op init_stack[INIT_STACK_SIZE];
struct op *stack = init_stack; struct op *stack = init_stack;
struct op *limit = stack + INIT_STACK_SIZE; struct op *limit = stack + INIT_STACK_SIZE;
cpp_token token;
register struct op *top = stack + 1; register struct op *top = stack + 1;
int skip_evaluation = 0; int skip_evaluation = 0;
int result; int result;
...@@ -737,6 +760,10 @@ _cpp_parse_expr (pfile) ...@@ -737,6 +760,10 @@ _cpp_parse_expr (pfile)
int save_skipping = pfile->skipping; int save_skipping = pfile->skipping;
pfile->skipping = 0; pfile->skipping = 0;
/* Set up detection of #if ! defined(). */
pfile->mi_lexed = 0;
pfile->mi_if_not_defined = MI_IND_NONE;
/* We've finished when we try to reduce this. */ /* We've finished when we try to reduce this. */
top->op = CPP_EOF; top->op = CPP_EOF;
/* Nifty way to catch missing '('. */ /* Nifty way to catch missing '('. */
...@@ -751,7 +778,8 @@ _cpp_parse_expr (pfile) ...@@ -751,7 +778,8 @@ _cpp_parse_expr (pfile)
struct op op; struct op op;
/* Read a token */ /* Read a token */
op = lex (pfile, skip_evaluation); op = lex (pfile, skip_evaluation, &token);
pfile->mi_lexed++;
/* If the token is an operand, push its value and get next /* If the token is an operand, push its value and get next
token. If it is an operator, get its priority and flags, and token. If it is an operator, get its priority and flags, and
...@@ -797,7 +825,7 @@ _cpp_parse_expr (pfile) ...@@ -797,7 +825,7 @@ _cpp_parse_expr (pfile)
SYNTAX_ERROR ("void expression between '(' and ')'"); SYNTAX_ERROR ("void expression between '(' and ')'");
else else
SYNTAX_ERROR2 ("operator '%s' has no right operand", SYNTAX_ERROR2 ("operator '%s' has no right operand",
TYPE_NAME (top->op)); op_as_text (pfile, top->op));
} }
unsigned2 = top->unsignedp, v2 = top->value; unsigned2 = top->unsignedp, v2 = top->value;
...@@ -808,7 +836,8 @@ _cpp_parse_expr (pfile) ...@@ -808,7 +836,8 @@ _cpp_parse_expr (pfile)
switch (top[1].op) switch (top[1].op)
{ {
default: default:
cpp_ice (pfile, "impossible operator type %s", TYPE_NAME (op.op)); cpp_ice (pfile, "impossible operator '%s'",
op_as_text (pfile, top[1].op));
goto syntax_error; goto syntax_error;
case CPP_NOT: UNARY(!); break; case CPP_NOT: UNARY(!); break;
...@@ -967,13 +996,13 @@ _cpp_parse_expr (pfile) ...@@ -967,13 +996,13 @@ _cpp_parse_expr (pfile)
{ {
if (top->flags & HAVE_VALUE) if (top->flags & HAVE_VALUE)
SYNTAX_ERROR2 ("missing binary operator before '%s'", SYNTAX_ERROR2 ("missing binary operator before '%s'",
TYPE_NAME (op.op)); op_as_text (pfile, top->op));
} }
else else
{ {
if (!(top->flags & HAVE_VALUE)) if (!(top->flags & HAVE_VALUE))
SYNTAX_ERROR2 ("operator '%s' has no left operand", SYNTAX_ERROR2 ("operator '%s' has no left operand",
TYPE_NAME (op.op)); op_as_text (pfile, top->op));
} }
/* Check for and handle stack overflow. */ /* Check for and handle stack overflow. */
...@@ -1017,3 +1046,15 @@ _cpp_parse_expr (pfile) ...@@ -1017,3 +1046,15 @@ _cpp_parse_expr (pfile)
pfile->skipping = save_skipping; pfile->skipping = save_skipping;
return result; return result;
} }
static const unsigned char *
op_as_text (pfile, op)
cpp_reader *pfile;
enum cpp_ttype op;
{
cpp_token token;
token.type = op;
token.flags = 0;
return cpp_token_as_text (pfile, &token);
}
...@@ -217,6 +217,10 @@ stack_include_file (pfile, inc) ...@@ -217,6 +217,10 @@ stack_include_file (pfile, inc)
if (fp == 0) if (fp == 0)
return 0; return 0;
/* Initialise controlling macro state. */
pfile->mi_state = MI_OUTSIDE;
pfile->mi_cmacro = 0;
fp->inc = inc; fp->inc = inc;
fp->nominal_fname = inc->name; fp->nominal_fname = inc->name;
fp->buf = inc->buffer; fp->buf = inc->buffer;
...@@ -233,8 +237,10 @@ stack_include_file (pfile, inc) ...@@ -233,8 +237,10 @@ stack_include_file (pfile, inc)
fp->inc->refcnt++; fp->inc->refcnt++;
pfile->include_depth++; pfile->include_depth++;
pfile->input_stack_listing_current = 0; pfile->input_stack_listing_current = 0;
if (pfile->cb.enter_file) if (pfile->cb.enter_file)
(*pfile->cb.enter_file) (pfile); (*pfile->cb.enter_file) (pfile);
return 1; return 1;
} }
...@@ -562,17 +568,21 @@ report_missing_guard (n, b) ...@@ -562,17 +568,21 @@ report_missing_guard (n, b)
#define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth)) #define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
void void
_cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets) _cpp_execute_include (pfile, header, no_reinclude, search_start)
cpp_reader *pfile; cpp_reader *pfile;
const U_CHAR *f; const cpp_token *header;
unsigned int len;
int no_reinclude; int no_reinclude;
struct file_name_list *search_start; struct file_name_list *search_start;
int angle_brackets;
{ {
unsigned int len = header->val.str.len;
unsigned int angle_brackets = header->type == CPP_HEADER_NAME;
struct include_file *inc; struct include_file *inc;
char *fname; char *fname;
fname = alloca (len + 1);
memcpy (fname, header->val.str.text, len);
fname[len] = '\0';
if (!search_start) if (!search_start)
{ {
if (angle_brackets) if (angle_brackets)
...@@ -581,18 +591,14 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets) ...@@ -581,18 +591,14 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
search_start = CPP_OPTION (pfile, quote_include); search_start = CPP_OPTION (pfile, quote_include);
else else
search_start = CPP_BUFFER (pfile)->actual_dir; search_start = CPP_BUFFER (pfile)->actual_dir;
}
if (!search_start) if (!search_start)
{ {
cpp_error (pfile, "No include path in which to find %s", f); cpp_error (pfile, "No include path in which to find %s", fname);
return; return;
}
} }
fname = alloca (len + 1);
memcpy (fname, f, len);
fname[len] = '\0';
inc = find_include_file (pfile, fname, search_start); inc = find_include_file (pfile, fname, search_start);
if (inc) if (inc)
...@@ -666,20 +672,17 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets) ...@@ -666,20 +672,17 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
/* Locate file F, and determine whether it is newer than PFILE. Return -1, /* Locate file F, and determine whether it is newer than PFILE. Return -1,
if F cannot be located or dated, 1, if it is newer and 0 if older. */ if F cannot be located or dated, 1, if it is newer and 0 if older. */
int int
_cpp_compare_file_date (pfile, f, len, angle_brackets) _cpp_compare_file_date (pfile, f)
cpp_reader *pfile; cpp_reader *pfile;
const U_CHAR *f; const cpp_token *f;
unsigned int len;
int angle_brackets;
{ {
unsigned int len = f->val.str.len;
char *fname; char *fname;
struct file_name_list *search_start; struct file_name_list *search_start;
struct include_file *inc; struct include_file *inc;
struct include_file *current_include = CPP_BUFFER (pfile)->inc;
if (angle_brackets) if (f->type == CPP_HEADER_NAME)
search_start = CPP_OPTION (pfile, bracket_include); search_start = CPP_OPTION (pfile, bracket_include);
else if (CPP_OPTION (pfile, ignore_srcdir)) else if (CPP_OPTION (pfile, ignore_srcdir))
search_start = CPP_OPTION (pfile, quote_include); search_start = CPP_OPTION (pfile, quote_include);
...@@ -687,7 +690,7 @@ _cpp_compare_file_date (pfile, f, len, angle_brackets) ...@@ -687,7 +690,7 @@ _cpp_compare_file_date (pfile, f, len, angle_brackets)
search_start = CPP_BUFFER (pfile)->actual_dir; search_start = CPP_BUFFER (pfile)->actual_dir;
fname = alloca (len + 1); fname = alloca (len + 1);
memcpy (fname, f, len); memcpy (fname, f->val.str.text, len);
fname[len] = '\0'; fname[len] = '\0';
inc = find_include_file (pfile, fname, search_start); inc = find_include_file (pfile, fname, search_start);
...@@ -699,7 +702,7 @@ _cpp_compare_file_date (pfile, f, len, angle_brackets) ...@@ -699,7 +702,7 @@ _cpp_compare_file_date (pfile, f, len, angle_brackets)
inc->fd = -1; inc->fd = -1;
} }
return inc->st.st_mtime > current_include->st.st_mtime; return inc->st.st_mtime > CPP_BUFFER (pfile)->inc->st.st_mtime;
} }
...@@ -723,6 +726,10 @@ cpp_read_file (pfile, fname) ...@@ -723,6 +726,10 @@ cpp_read_file (pfile, fname)
return 0; return 0;
} }
/* Return success for zero-length files. */
if (DO_NOT_REREAD (f))
return 1;
return stack_include_file (pfile, f); return stack_include_file (pfile, f);
} }
...@@ -739,13 +746,18 @@ _cpp_pop_file_buffer (pfile, buf) ...@@ -739,13 +746,18 @@ _cpp_pop_file_buffer (pfile, buf)
pfile->system_include_depth--; pfile->system_include_depth--;
if (pfile->include_depth) if (pfile->include_depth)
pfile->include_depth--; pfile->include_depth--;
if (pfile->potential_control_macro) pfile->input_stack_listing_current = 0;
/* Record the inclusion-preventing macro and its definedness. */
if (pfile->mi_state == MI_OUTSIDE && inc->cmacro != NEVER_REREAD)
{ {
if (inc->cmacro != NEVER_REREAD) /* This could be NULL meaning no controlling macro. */
inc->cmacro = pfile->potential_control_macro; inc->cmacro = pfile->mi_cmacro;
pfile->potential_control_macro = 0; inc->defined = 1;
} }
pfile->input_stack_listing_current = 0;
/* Invalidate control macros in the #including file. */
pfile->mi_state = MI_FAILED;
inc->refcnt--; inc->refcnt--;
if (inc->refcnt == 0 && DO_NOT_REREAD (inc)) if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
......
...@@ -49,7 +49,7 @@ static unsigned long higher_prime_number PARAMS ((unsigned long)); ...@@ -49,7 +49,7 @@ static unsigned long higher_prime_number PARAMS ((unsigned long));
/* Set up and tear down internal structures for macro expansion. */ /* Set up and tear down internal structures for macro expansion. */
void void
_cpp_init_macros (pfile) _cpp_init_hashtable (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
pfile->hash_ob = xnew (struct obstack); pfile->hash_ob = xnew (struct obstack);
...@@ -63,7 +63,7 @@ _cpp_init_macros (pfile) ...@@ -63,7 +63,7 @@ _cpp_init_macros (pfile)
} }
void void
_cpp_cleanup_macros (pfile) _cpp_cleanup_hashtable (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_hashnode **p, **limit; cpp_hashnode **p, **limit;
...@@ -101,29 +101,32 @@ cpp_lookup (pfile, name, len) ...@@ -101,29 +101,32 @@ cpp_lookup (pfile, name, len)
size_t n = len; size_t n = len;
unsigned int r = 0; unsigned int r = 0;
const U_CHAR *str = name; const U_CHAR *str = name;
U_CHAR *dest = _cpp_pool_reserve (&pfile->ident_pool, len + 1);
do do
{ {
r = HASHSTEP (r, *str); r = HASHSTEP (r, *str);
str++; *dest++ = *str++;
} }
while (--n); while (--n);
*dest = '\0';
return _cpp_lookup_with_hash (pfile, name, len, r); return _cpp_lookup_with_hash (pfile, len, r);
} }
/* NAME is a null-terminated identifier of length len. It is assumed
to have been placed at the front of the identifier pool. */
cpp_hashnode * cpp_hashnode *
_cpp_lookup_with_hash (pfile, name, len, hash) _cpp_lookup_with_hash (pfile, len, hash)
cpp_reader *pfile; cpp_reader *pfile;
const U_CHAR *name;
size_t len; size_t len;
unsigned int hash; unsigned int hash;
{ {
unsigned int index; unsigned int index;
unsigned int hash2;
size_t size; size_t size;
cpp_hashnode *entry; cpp_hashnode *entry;
cpp_hashnode **entries; cpp_hashnode **entries;
unsigned char *name = POOL_FRONT (&pfile->ident_pool);
entries = pfile->hashtab->entries; entries = pfile->hashtab->entries;
size = pfile->hashtab->size; size = pfile->hashtab->size;
...@@ -132,48 +135,49 @@ _cpp_lookup_with_hash (pfile, name, len, hash) ...@@ -132,48 +135,49 @@ _cpp_lookup_with_hash (pfile, name, len, hash)
index = hash % size; index = hash % size;
entry = entries[index]; entry = entries[index];
if (entry == NULL) if (entry)
goto insert;
if (entry->hash == hash && entry->length == len
&& !memcmp (entry->name, name, len))
return entry;
hash2 = 1 + hash % (size - 2);
for (;;)
{ {
index += hash2; unsigned int hash2;
if (index >= size)
index -= size;
entry = entries[index];
if (entry == NULL)
goto insert;
if (entry->hash == hash && entry->length == len if (entry->hash == hash && entry->length == len
&& !memcmp (entry->name, name, len)) && !memcmp (entry->name, name, len))
return entry; return entry;
hash2 = 1 + hash % (size - 2);
for (;;)
{
index += hash2;
if (index >= size)
index -= size;
entry = entries[index];
if (entry == NULL)
break;
if (entry->hash == hash && entry->length == len
&& !memcmp (entry->name, name, len))
return entry;
}
} }
insert: /* Commit the memory for the identifier. */
pfile->hashtab->nelts++; POOL_COMMIT (&pfile->ident_pool, len + 1);
/* Create a new hash node. */ /* Create a new hash node and insert it in the table. */
{ entries[index] = obstack_alloc (pfile->hash_ob, sizeof (cpp_hashnode));
U_CHAR *p = obstack_alloc (pfile->hash_ob, sizeof (cpp_hashnode) + len);
entry = (cpp_hashnode *)p;
p += offsetof (cpp_hashnode, name);
entry->type = T_VOID;
entry->fe_value = 0;
entry->length = len;
entry->hash = hash;
entry->value.expansion = NULL;
memcpy (p, name, len);
p[len] = 0;
entries[index] = entry;
}
entry = entries[index];
entry->type = NT_VOID;
entry->flags = 0;
entry->fe_value = 0;
entry->directive_index = 0;
entry->arg_index = 0;
entry->length = len;
entry->hash = hash;
entry->name = name;
entry->value.macro = 0;
pfile->hashtab->nelts++;
if (size * 3 <= pfile->hashtab->nelts * 4) if (size * 3 <= pfile->hashtab->nelts * 4)
expand_hash (pfile->hashtab); expand_hash (pfile->hashtab);
......
...@@ -517,8 +517,9 @@ recognized_extern (name) ...@@ -517,8 +517,9 @@ recognized_extern (name)
'f' for other function declarations. */ 'f' for other function declarations. */
void void
recognized_function (fname, kind, have_arg_list, file_seen) recognized_function (fname, line, kind, have_arg_list, file_seen)
const cpp_token *fname; const cpp_token *fname;
unsigned int line;
int kind; /* One of 'f' 'F' or 'I' */ int kind; /* One of 'f' 'F' or 'I' */
int have_arg_list; int have_arg_list;
const char *file_seen; const char *file_seen;
...@@ -566,7 +567,7 @@ recognized_function (fname, kind, have_arg_list, file_seen) ...@@ -566,7 +567,7 @@ recognized_function (fname, kind, have_arg_list, file_seen)
partial_count++; partial_count++;
partial = (struct partial_proto *) partial = (struct partial_proto *)
obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto)); obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
partial->line_seen = fname->line; partial->line_seen = line;
partial->fn = fn; partial->fn = fn;
fn->partial = partial; fn->partial = partial;
partial->next = partial_proto_list; partial->next = partial_proto_list;
...@@ -622,7 +623,7 @@ read_scan_file (in_fname, argc, argv) ...@@ -622,7 +623,7 @@ read_scan_file (in_fname, argc, argv)
if (CPP_FATAL_ERRORS (&scan_in)) if (CPP_FATAL_ERRORS (&scan_in))
exit (FATAL_EXIT_CODE); exit (FATAL_EXIT_CODE);
if (! cpp_start_read (&scan_in, 0, in_fname)) if (! cpp_start_read (&scan_in, in_fname))
exit (FATAL_EXIT_CODE); exit (FATAL_EXIT_CODE);
/* We are scanning a system header, so mark it as such. */ /* We are scanning a system header, so mark it as such. */
...@@ -647,15 +648,16 @@ read_scan_file (in_fname, argc, argv) ...@@ -647,15 +648,16 @@ read_scan_file (in_fname, argc, argv)
/* Scan the macro expansion of "getchar();". */ /* Scan the macro expansion of "getchar();". */
for (;;) for (;;)
{ {
const cpp_token *t = cpp_get_token (&scan_in); cpp_token t;
if (t->type == CPP_EOF) cpp_get_token (&scan_in, &t);
if (t.type == CPP_EOF)
{ {
cpp_pop_buffer (&scan_in); cpp_pop_buffer (&scan_in);
if (CPP_BUFFER (&scan_in) == buf) if (CPP_BUFFER (&scan_in) == buf)
break; break;
} }
else if (cpp_ideq (t, "_filbuf")) else if (cpp_ideq (&t, "_filbuf"))
seen_filbuf++; seen_filbuf++;
} }
if (seen_filbuf) if (seen_filbuf)
......
...@@ -582,7 +582,6 @@ cpplex.c ...@@ -582,7 +582,6 @@ cpplex.c
cpplib.c cpplib.c
cpplib.h cpplib.h
cppmain.c cppmain.c
cppoutput.c
cppspec.c cppspec.c
#crtstuff.c is part of the GCC library #crtstuff.c is part of the GCC library
cse.c cse.c
......
...@@ -45,7 +45,11 @@ skip_to_closing_brace (pfile) ...@@ -45,7 +45,11 @@ skip_to_closing_brace (pfile)
int nesting = 1; int nesting = 1;
for (;;) for (;;)
{ {
enum cpp_ttype token = cpp_get_token (pfile)->type; cpp_token tok;
enum cpp_ttype token;
cpp_get_token (pfile, &tok);
token = tok.type;
if (token == CPP_EOF) if (token == CPP_EOF)
break; break;
if (token == CPP_OPEN_BRACE) if (token == CPP_OPEN_BRACE)
...@@ -84,17 +88,16 @@ scan_decls (pfile, argc, argv) ...@@ -84,17 +88,16 @@ scan_decls (pfile, argc, argv)
char **argv ATTRIBUTE_UNUSED; char **argv ATTRIBUTE_UNUSED;
{ {
int saw_extern, saw_inline; int saw_extern, saw_inline;
const cpp_token *prev_id; cpp_token token, prev_id;
const cpp_token *token;
new_statement: new_statement:
token = cpp_get_token (pfile); cpp_get_token (pfile, &token);
handle_statement: handle_statement:
current_extern_C = 0; current_extern_C = 0;
saw_extern = 0; saw_extern = 0;
saw_inline = 0; saw_inline = 0;
if (token->type == CPP_OPEN_BRACE) if (token.type == CPP_OPEN_BRACE)
{ {
/* Pop an 'extern "C"' nesting level, if appropriate. */ /* Pop an 'extern "C"' nesting level, if appropriate. */
if (extern_C_braces_length if (extern_C_braces_length
...@@ -103,12 +106,12 @@ scan_decls (pfile, argc, argv) ...@@ -103,12 +106,12 @@ scan_decls (pfile, argc, argv)
brace_nesting--; brace_nesting--;
goto new_statement; goto new_statement;
} }
if (token->type == CPP_OPEN_BRACE) if (token.type == CPP_OPEN_BRACE)
{ {
brace_nesting++; brace_nesting++;
goto new_statement; goto new_statement;
} }
if (token->type == CPP_EOF) if (token.type == CPP_EOF)
{ {
cpp_pop_buffer (pfile); cpp_pop_buffer (pfile);
if (CPP_BUFFER (pfile) == NULL) if (CPP_BUFFER (pfile) == NULL)
...@@ -116,15 +119,15 @@ scan_decls (pfile, argc, argv) ...@@ -116,15 +119,15 @@ scan_decls (pfile, argc, argv)
goto new_statement; goto new_statement;
} }
if (token->type == CPP_SEMICOLON) if (token.type == CPP_SEMICOLON)
goto new_statement; goto new_statement;
if (token->type != CPP_NAME) if (token.type != CPP_NAME)
goto new_statement; goto new_statement;
prev_id = 0; prev_id.type = CPP_EOF;
for (;;) for (;;)
{ {
switch (token->type) switch (token.type)
{ {
default: default:
goto handle_statement; goto handle_statement;
...@@ -136,11 +139,11 @@ scan_decls (pfile, argc, argv) ...@@ -136,11 +139,11 @@ scan_decls (pfile, argc, argv)
case CPP_COMMA: case CPP_COMMA:
case CPP_SEMICOLON: case CPP_SEMICOLON:
if (prev_id && saw_extern) if (prev_id.type != CPP_EOF && saw_extern)
{ {
recognized_extern (prev_id); recognized_extern (&prev_id);
} }
if (token->type == CPP_COMMA) if (token.type == CPP_COMMA)
break; break;
/* ... fall through ... */ /* ... fall through ... */
case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE: case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE:
...@@ -154,60 +157,61 @@ scan_decls (pfile, argc, argv) ...@@ -154,60 +157,61 @@ scan_decls (pfile, argc, argv)
case CPP_OPEN_PAREN: case CPP_OPEN_PAREN:
/* Looks like this is the start of a formal parameter list. */ /* Looks like this is the start of a formal parameter list. */
if (prev_id) if (prev_id.type != CPP_EOF)
{ {
int nesting = 1; int nesting = 1;
int have_arg_list = 0; int have_arg_list = 0;
for (;;) for (;;)
{ {
token = cpp_get_token (pfile); cpp_get_token (pfile, &token);
if (token->type == CPP_OPEN_PAREN) if (token.type == CPP_OPEN_PAREN)
nesting++; nesting++;
else if (token->type == CPP_CLOSE_PAREN) else if (token.type == CPP_CLOSE_PAREN)
{ {
nesting--; nesting--;
if (nesting == 0) if (nesting == 0)
break; break;
} }
else if (token->type == CPP_EOF) else if (token.type == CPP_EOF)
break; break;
else if (token->type == CPP_NAME else if (token.type == CPP_NAME
|| token->type == CPP_ELLIPSIS) || token.type == CPP_ELLIPSIS)
have_arg_list = 1; have_arg_list = 1;
} }
recognized_function (prev_id, recognized_function (&prev_id,
cpp_get_line (pfile)->line,
(saw_inline ? 'I' (saw_inline ? 'I'
: in_extern_C_brace || current_extern_C : in_extern_C_brace || current_extern_C
? 'F' : 'f'), have_arg_list, ? 'F' : 'f'), have_arg_list,
CPP_BUFFER (pfile)->nominal_fname); CPP_BUFFER (pfile)->nominal_fname);
token = cpp_get_token (pfile); cpp_get_token (pfile, &token);
if (token->type == CPP_OPEN_BRACE) if (token.type == CPP_OPEN_BRACE)
{ {
/* skip body of (normally) inline function */ /* skip body of (normally) inline function */
skip_to_closing_brace (pfile); skip_to_closing_brace (pfile);
goto new_statement; goto new_statement;
} }
if (token->type == CPP_SEMICOLON) if (token.type == CPP_SEMICOLON)
goto new_statement; goto new_statement;
} }
break; break;
case CPP_NAME: case CPP_NAME:
/* "inline" and "extern" are recognized but skipped */ /* "inline" and "extern" are recognized but skipped */
if (cpp_ideq (token, "inline")) if (cpp_ideq (&token, "inline"))
{ {
saw_inline = 1; saw_inline = 1;
} }
else if (cpp_ideq (token, "extern")) else if (cpp_ideq (&token, "extern"))
{ {
saw_extern = 1; saw_extern = 1;
token = cpp_get_token (pfile); cpp_get_token (pfile, &token);
if (token->type == CPP_STRING if (token.type == CPP_STRING
&& token->val.str.len == 1 && token.val.str.len == 1
&& token->val.str.text[0] == 'C') && token.val.str.text[0] == 'C')
{ {
current_extern_C = 1; current_extern_C = 1;
token = cpp_get_token (pfile); cpp_get_token (pfile, &token);
if (token->type == CPP_OPEN_BRACE) if (token.type == CPP_OPEN_BRACE)
{ {
brace_nesting++; brace_nesting++;
extern_C_braces[extern_C_braces_length++] extern_C_braces[extern_C_braces_length++]
...@@ -223,6 +227,6 @@ scan_decls (pfile, argc, argv) ...@@ -223,6 +227,6 @@ scan_decls (pfile, argc, argv)
prev_id = token; prev_id = token;
break; break;
} }
token = cpp_get_token (pfile); cpp_get_token (pfile, &token);
} }
} }
...@@ -60,7 +60,8 @@ extern int scan_ident _PARAMS((FILE *, sstring *, int)); ...@@ -60,7 +60,8 @@ extern int scan_ident _PARAMS((FILE *, sstring *, int));
extern int scan_string _PARAMS((FILE *, sstring *, int)); extern int scan_string _PARAMS((FILE *, sstring *, int));
extern int read_upto _PARAMS((FILE *, sstring *, int)); extern int read_upto _PARAMS((FILE *, sstring *, int));
extern unsigned long hash _PARAMS((const char *)); extern unsigned long hash _PARAMS((const char *));
extern void recognized_function _PARAMS((const struct cpp_token *, int, int, extern void recognized_function _PARAMS((const struct cpp_token *,
unsigned int, int, int,
const char *)); const char *));
extern void recognized_extern _PARAMS((const struct cpp_token *)); extern void recognized_extern _PARAMS((const struct cpp_token *));
extern unsigned int hashstr _PARAMS((const char *, unsigned int)); extern unsigned int hashstr _PARAMS((const char *, unsigned int));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment