top level:
2000-07-03 Zack Weinberg <zack@wolery.cumb.org> * fix-header.c (struct partial_proto): Remove unnecessary fields. (recognized_extern, recognized_function, read_scan_file): Update for new scheme. (check_protection): It's still a multiple include guard even if it doesn't always trigger. * scan-decls.c (skip_to_closing_brace, scan_decls): Update for new scheme. * scan.h: Declare struct cpp_token. Update prototypes. 2000-07-03 Neil Booth <neilb@earthling.net> Zack Weinberg <zack@wolery.cumb.org> Complete overhaul of the lexer and macro expander. * cpphash.c (object_defn, funct_defn, push_macro_expansion, arg, arglist, argdata, reflist, collect_objlike_expansion, collect_funlike_expansion, collect_params, warn_trad_stringify, trad_stringify, duplicate_arg_p, add_pat, unsafe_chars, macarg, compare_defs, special_symbol, scan_arguments, stringify, funlike_macroexpand, _cpp_quote_string, monthnames): Delete. (cpp_lookup, _cpp_free_definition, dump_funlike_macro, _cpp_create_definition, _cpp_dump_definition, dump_hash_helper): Adjust. (find_param, count_params, parse_define, var_args_str, check_macro_redefinition, save_expansion): New. * cpplex.c (skip_block_comment, skip_line_comment, parse_name, parse_string, output_line_command, trigraph_replace, lex_line, cpp_push_buffer, cpp_pop_buffer, cpp_output_tokens, cpp_scan_buffer_nooutput, cpp_scan_buffer, cpp_free_toklist, cpp_idcmp, _cpp_get_directive_token, _cpp_init_input_buffer, _cpp_skip_rest_of_line): Modify. (maybe_macroexpand, skip_comment, copy_comment, skip_string, find_position, null_warning, bump_column, expand_name_space, pedantic_whitespace, _cpp_output_list, _cpp_slice_toklist, _cpp_squeeze_toklist, _cpp_scan_until, _cpp_skip_hspace, _cpp_parse_name, _cpp_lex_token, cpp_get_non_space_token, _cpp_prescan): Delete. (dump_param_spelling, process_directive, lex_next, is_macro_disabled, stringify_arg, expand_context_stack, output_token, make_string_token, alloc_number_token, special_symbol, duplicate_token, maybe_paste_with_next, can_paste, prevent_macro_expansion, restore_macro_expansion, get_temp_token, release_temp_tokens, quote_string, token_names, token_spellings, _cpp_expand_name_space, _cpp_glue_header_name, _cpp_reserve_name_space, digraph_spellings, trigraph_ok, skip_whitespace, save_comment, placemarker_token, eof_token, cpp_context, macro_args, get_raw_token, parse_arg, parse_args, save_token, push_arg_context, push_macro_context, pop_context, do_pop_context, free_macro_args, _cpp_get_line, _cpp_run_directive): New. * cpplib.c (validate_else, parse_include, push_conditional, pass_thru_directive, read_line_number, parse_ifdef, detect_if_not_defined, _cpp_check_directive, do_define, do_undef, do_include, do_import, do_include_next, do_error, do_warning, do_ident, do_pragma, pragma_dispatch, gcc_pragmas, top_pragmas, do_pragma_gcc, do_pragma_implementation, do_pragma_poison, do_pragma_system_header, do_pragma_dependency, do_sccs, do_ifdef, do_ifndef, do_else, dl_elif, do_endif, _cpp_unwind_if_stack, do_assert, do_unassert, cpp_define, cpp_undef, cpp_assert, cpp_unassert, cpp_defined): Update for new scheme. (strtoul_for_line, get_define_node, dump_macro_name, _cpp_check_linemarker, _cpp_parse_assertion): New. (_cpp_handle_directive, do_pragma_default): Delete. * cpphash.h (struct predicate): Now struct answer. (enum spell_type, struct token_spelling, struct directive, directive_handler): New. Update prototypes. Remove unused macros. * cpplib.h: Update prototypes. Remove unused macros, structure definitions, and fields. * cpperror.c (print_containing_files, v_message): Adjust. * cppexp.c (parse_assertion, lex, parse_escape, _cpp_parse_expr): Adjust. * cppfiles.c (open_include_file, _cpp_execute_include, _cpp_compare_file_date, cpp_read_file, read_include_file): Adjust. * cppinit.c (dump_special_to_buffer): Delete. (append_include_chain, merge_include_chains, cpp_reader_init, cpp_cleanup, initialize_builtins, builtin_array, cpp_start_read, cpp_finish, handle_option, print_help): Adjust. * cppmain.c (main): Adjust. testsuite: 2000-07-03 Zack Weinberg <zack@wolery.cumb.org> * testsuite/gcc.dg/cpp/19951025-1.c: Adjust regexps. * testsuite/gcc.dg/cpp/19990703-1.c: Likewise. * testsuite/gcc.dg/cpp/20000625-1.c: Likewise. * testsuite/gcc.dg/cpp/20000625-2.c: Likewise. * testsuite/gcc.dg/cpp/macro1.c, testsuite/gcc.dg/cpp/paste1.c, testsuite/gcc.dg/cpp/paste2.c, testsuite/gcc.dg/cpp/paste3.c, testsuite/gcc.dg/cpp/paste4.c, testsuite/gcc.dg/cpp/strify1.c, testsuite/gcc.dg/cpp/strify2.c: New tests. From-SVN: r34859
This commit is contained in:
parent
4f647814ce
commit
041c31944c
26 changed files with 3856 additions and 5027 deletions
|
@ -1,3 +1,95 @@
|
|||
2000-07-03 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* fix-header.c (struct partial_proto): Remove unnecessary fields.
|
||||
(recognized_extern, recognized_function, read_scan_file):
|
||||
Update for new scheme.
|
||||
(check_protection): It's still a multiple include guard even
|
||||
if it doesn't always trigger.
|
||||
* scan-decls.c (skip_to_closing_brace, scan_decls): Update for
|
||||
new scheme.
|
||||
* scan.h: Declare struct cpp_token. Update prototypes.
|
||||
|
||||
2000-07-03 Neil Booth <neilb@earthling.net>
|
||||
Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
Complete overhaul of the lexer and macro expander.
|
||||
|
||||
* cpphash.c (object_defn, funct_defn, push_macro_expansion,
|
||||
arg, arglist, argdata, reflist, collect_objlike_expansion,
|
||||
collect_funlike_expansion, collect_params,
|
||||
warn_trad_stringify, trad_stringify, duplicate_arg_p, add_pat,
|
||||
unsafe_chars, macarg, compare_defs, special_symbol,
|
||||
scan_arguments, stringify, funlike_macroexpand,
|
||||
_cpp_quote_string, monthnames): Delete.
|
||||
(cpp_lookup, _cpp_free_definition, dump_funlike_macro,
|
||||
_cpp_create_definition, _cpp_dump_definition,
|
||||
dump_hash_helper): Adjust.
|
||||
(find_param, count_params, parse_define, var_args_str,
|
||||
check_macro_redefinition, save_expansion): New.
|
||||
|
||||
* cpplex.c (skip_block_comment, skip_line_comment, parse_name,
|
||||
parse_string, output_line_command, trigraph_replace,
|
||||
lex_line, cpp_push_buffer, cpp_pop_buffer, cpp_output_tokens,
|
||||
cpp_scan_buffer_nooutput, cpp_scan_buffer, cpp_free_toklist,
|
||||
cpp_idcmp, _cpp_get_directive_token, _cpp_init_input_buffer,
|
||||
_cpp_skip_rest_of_line): Modify.
|
||||
|
||||
(maybe_macroexpand, skip_comment, copy_comment, skip_string,
|
||||
find_position, null_warning, bump_column, expand_name_space,
|
||||
pedantic_whitespace, _cpp_output_list, _cpp_slice_toklist,
|
||||
_cpp_squeeze_toklist, _cpp_scan_until, _cpp_skip_hspace,
|
||||
_cpp_parse_name, _cpp_lex_token, cpp_get_non_space_token,
|
||||
_cpp_prescan): Delete.
|
||||
|
||||
(dump_param_spelling, process_directive, lex_next,
|
||||
is_macro_disabled, stringify_arg, expand_context_stack,
|
||||
output_token, make_string_token, alloc_number_token,
|
||||
special_symbol, duplicate_token, maybe_paste_with_next,
|
||||
can_paste, prevent_macro_expansion, restore_macro_expansion,
|
||||
get_temp_token, release_temp_tokens, quote_string,
|
||||
token_names, token_spellings, _cpp_expand_name_space,
|
||||
_cpp_glue_header_name, _cpp_reserve_name_space,
|
||||
digraph_spellings, trigraph_ok, skip_whitespace, save_comment,
|
||||
placemarker_token, eof_token, cpp_context, macro_args,
|
||||
get_raw_token, parse_arg, parse_args, save_token,
|
||||
push_arg_context, push_macro_context, pop_context,
|
||||
do_pop_context, free_macro_args, _cpp_get_line,
|
||||
_cpp_run_directive): New.
|
||||
|
||||
* cpplib.c (validate_else, parse_include, push_conditional,
|
||||
pass_thru_directive, read_line_number, parse_ifdef,
|
||||
detect_if_not_defined, _cpp_check_directive, do_define,
|
||||
do_undef, do_include, do_import, do_include_next, do_error,
|
||||
do_warning, do_ident, do_pragma, pragma_dispatch, gcc_pragmas,
|
||||
top_pragmas, do_pragma_gcc, do_pragma_implementation,
|
||||
do_pragma_poison, do_pragma_system_header,
|
||||
do_pragma_dependency, do_sccs, do_ifdef, do_ifndef, do_else,
|
||||
dl_elif, do_endif, _cpp_unwind_if_stack, do_assert,
|
||||
do_unassert, cpp_define, cpp_undef, cpp_assert, cpp_unassert,
|
||||
cpp_defined): Update for new scheme.
|
||||
(strtoul_for_line, get_define_node, dump_macro_name,
|
||||
_cpp_check_linemarker, _cpp_parse_assertion): New.
|
||||
(_cpp_handle_directive, do_pragma_default): Delete.
|
||||
|
||||
* cpphash.h (struct predicate): Now struct answer.
|
||||
(enum spell_type, struct token_spelling, struct directive,
|
||||
directive_handler): New.
|
||||
Update prototypes. Remove unused macros.
|
||||
* cpplib.h: Update prototypes. Remove unused macros,
|
||||
structure definitions, and fields.
|
||||
|
||||
* cpperror.c (print_containing_files, v_message): Adjust.
|
||||
* cppexp.c (parse_assertion, lex, parse_escape,
|
||||
_cpp_parse_expr): Adjust.
|
||||
* cppfiles.c (open_include_file, _cpp_execute_include,
|
||||
_cpp_compare_file_date, cpp_read_file, read_include_file):
|
||||
Adjust.
|
||||
* cppinit.c (dump_special_to_buffer): Delete.
|
||||
(append_include_chain, merge_include_chains, cpp_reader_init,
|
||||
cpp_cleanup, initialize_builtins, builtin_array, cpp_start_read,
|
||||
cpp_finish, handle_option, print_help): Adjust.
|
||||
* cppmain.c (main): Adjust.
|
||||
|
||||
2000-07-03 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* cppspec.c (lang_specific_driver): Use double quotes in error
|
||||
|
|
|
@ -58,23 +58,27 @@ print_containing_files (pfile, ip)
|
|||
if (first)
|
||||
{
|
||||
first = 0;
|
||||
/* N.B. The current line in each outer source file is one
|
||||
greater than the line of the #include, so we must
|
||||
subtract one to correct for that. */
|
||||
fprintf (stderr, _("In file included from %s:%u"),
|
||||
ip->nominal_fname, CPP_BUF_LINE (ip));
|
||||
ip->nominal_fname, CPP_BUF_LINE (ip) - 1);
|
||||
}
|
||||
else
|
||||
/* Translators note: this message is used in conjunction
|
||||
with "In file included from %s:%ld" and some other
|
||||
tricks. We want something like this:
|
||||
|
||||
In file included from sys/select.h:123,
|
||||
from sys/types.h:234,
|
||||
from userfile.c:31:
|
||||
bits/select.h:45: <error message here>
|
||||
| In file included from sys/select.h:123,
|
||||
| from sys/types.h:234,
|
||||
| from userfile.c:31:
|
||||
| bits/select.h:45: <error message here>
|
||||
|
||||
with all the "from"s lined up.
|
||||
The trailing comma is at the beginning of this message,
|
||||
and the trailing colon is not translated. */
|
||||
fprintf (stderr, _(",\n from %s:%u"),
|
||||
ip->nominal_fname, CPP_BUF_LINE (ip));
|
||||
ip->nominal_fname, CPP_BUF_LINE (ip) - 1);
|
||||
}
|
||||
if (first == 0)
|
||||
fputs (":\n", stderr);
|
||||
|
@ -111,17 +115,14 @@ v_message (pfile, is_error, file, line, col, msg, ap)
|
|||
const char *msg;
|
||||
va_list ap;
|
||||
{
|
||||
cpp_buffer *ip = cpp_file_buffer (pfile);
|
||||
cpp_buffer *ip = CPP_BUFFER (pfile);
|
||||
|
||||
if (ip)
|
||||
{
|
||||
if (file == NULL)
|
||||
file = ip->nominal_fname;
|
||||
if (line == 0)
|
||||
{
|
||||
line = CPP_BUF_LINE (ip);
|
||||
col = CPP_BUF_COL (ip);
|
||||
}
|
||||
line = _cpp_get_line (pfile, &col);
|
||||
print_containing_files (pfile, ip);
|
||||
print_file_and_line (file, line,
|
||||
CPP_OPTION (pfile, show_column) ? col : 0);
|
||||
|
@ -132,8 +133,12 @@ v_message (pfile, is_error, file, line, col, msg, ap)
|
|||
switch (is_error)
|
||||
{
|
||||
case 0:
|
||||
fprintf (stderr, _("warning: "));
|
||||
break;
|
||||
if (! CPP_OPTION (pfile, warnings_are_errors))
|
||||
{
|
||||
fprintf (stderr, _("warning: "));
|
||||
break;
|
||||
}
|
||||
/* else fall through */
|
||||
case 1:
|
||||
if (pfile->errors < CPP_FATAL_LIMIT)
|
||||
pfile->errors++;
|
||||
|
|
112
gcc/cppexp.c
112
gcc/cppexp.c
|
@ -394,74 +394,22 @@ parse_assertion (pfile)
|
|||
cpp_reader *pfile;
|
||||
{
|
||||
struct operation op;
|
||||
struct answer *answer;
|
||||
cpp_hashnode *hp;
|
||||
struct predicate *pred;
|
||||
cpp_toklist query;
|
||||
enum cpp_ttype type;
|
||||
U_CHAR *tok;
|
||||
size_t len;
|
||||
unsigned int old_written;
|
||||
int specific = 0;
|
||||
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
CPP_PUTC (pfile, '#');
|
||||
pfile->no_macro_expand++;
|
||||
type = _cpp_get_directive_token (pfile);
|
||||
if (type == CPP_VSPACE)
|
||||
SYNTAX_ERROR ("assertion without predicate");
|
||||
else if (type != CPP_NAME)
|
||||
SYNTAX_ERROR ("assertion predicate is not an identifier");
|
||||
|
||||
tok = pfile->token_buffer + old_written;
|
||||
len = CPP_WRITTEN (pfile) - old_written;
|
||||
hp = cpp_lookup (pfile, tok, len);
|
||||
|
||||
/* Look ahead for an open paren. */
|
||||
_cpp_skip_hspace (pfile);
|
||||
if (CPP_BUF_PEEK (CPP_BUFFER (pfile)) == '(')
|
||||
{
|
||||
if (_cpp_get_directive_token (pfile) != CPP_OPEN_PAREN)
|
||||
CPP_ICE ("impossible token, expecting ( in parse_assertion");
|
||||
|
||||
_cpp_init_toklist (&query, NO_DUMMY_TOKEN);
|
||||
specific = 1;
|
||||
if (_cpp_scan_until (pfile, &query, CPP_CLOSE_PAREN) != CPP_CLOSE_PAREN)
|
||||
SYNTAX_ERROR ("missing close paren on assertion answer");
|
||||
|
||||
if (_cpp_get_directive_token (pfile) != CPP_CLOSE_PAREN)
|
||||
CPP_ICE ("impossible token, expecting ) in parse_assertion");
|
||||
}
|
||||
|
||||
/* If we get here, the syntax is valid. */
|
||||
op.op = INT;
|
||||
op.value = 0;
|
||||
/* Has this predicate been asserted at all? */
|
||||
if (hp->type == T_ASSERTION)
|
||||
{
|
||||
if (specific)
|
||||
{
|
||||
for (pred = hp->value.pred; pred; pred = pred->next)
|
||||
if (_cpp_equiv_toklists (&query, &pred->answer))
|
||||
{
|
||||
op.value = 1;
|
||||
break;
|
||||
}
|
||||
_cpp_free_toklist (&query);
|
||||
}
|
||||
else
|
||||
op.value = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
pfile->no_macro_expand--;
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
return op;
|
||||
|
||||
syntax_error:
|
||||
if (specific)
|
||||
_cpp_free_toklist (&query);
|
||||
op.op = ERROR;
|
||||
goto out;
|
||||
hp = _cpp_parse_assertion (pfile, &answer);
|
||||
if (hp)
|
||||
{
|
||||
/* If we get here, the syntax is valid. */
|
||||
op.op = INT;
|
||||
op.value = (hp->type == T_ASSERTION &&
|
||||
(answer == 0 || *find_answer (hp, &answer->list) != 0));
|
||||
|
||||
if (answer)
|
||||
FREE_ANSWER (answer);
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
struct token
|
||||
|
@ -480,8 +428,6 @@ static const struct token tokentab2[] =
|
|||
{"!=", NOTEQUAL},
|
||||
{"<=", LEQ},
|
||||
{">=", GEQ},
|
||||
{"++", ERROR},
|
||||
{"--", ERROR},
|
||||
{NULL, ERROR}
|
||||
};
|
||||
|
||||
|
@ -496,16 +442,20 @@ lex (pfile, skip_evaluation)
|
|||
enum cpp_ttype token;
|
||||
struct operation op;
|
||||
U_CHAR *tok_start, *tok_end;
|
||||
long old_written;
|
||||
long old_written = CPP_WRITTEN (pfile);
|
||||
|
||||
old_written = CPP_WRITTEN (pfile);
|
||||
retry:
|
||||
token = _cpp_get_directive_token (pfile);
|
||||
|
||||
tok_start = pfile->token_buffer + old_written;
|
||||
tok_end = CPP_PWRITTEN (pfile);
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case CPP_PLACEMARKER:
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
goto retry;
|
||||
|
||||
case CPP_EOF: /* Should not happen ... */
|
||||
case CPP_VSPACE:
|
||||
op.op = 0;
|
||||
|
@ -524,6 +474,7 @@ lex (pfile, skip_evaluation)
|
|||
return parse_charconst (pfile, tok_start, tok_end);
|
||||
|
||||
case CPP_NAME:
|
||||
/* FIXME: could this not overflow the tok_start buffer? */
|
||||
if (!ustrncmp (tok_start, U"defined", 7))
|
||||
return parse_defined (pfile);
|
||||
|
||||
|
@ -539,7 +490,16 @@ lex (pfile, skip_evaluation)
|
|||
case CPP_HASH:
|
||||
return parse_assertion (pfile);
|
||||
|
||||
case CPP_OTHER:
|
||||
case CPP_AND_AND: op.op = ANDAND; return op;
|
||||
case CPP_OR_OR: op.op = OROR; return op;
|
||||
case CPP_LSHIFT: op.op = LSH; return op;
|
||||
case CPP_RSHIFT: op.op = RSH; return op;
|
||||
case CPP_EQ_EQ: op.op = EQUAL; return op;
|
||||
case CPP_NOT_EQ: op.op = NOTEQUAL; return op;
|
||||
case CPP_LESS_EQ: op.op = LEQ; return op;
|
||||
case CPP_GREATER_EQ:op.op = GEQ; return op;
|
||||
|
||||
default:
|
||||
/* See if it is a special token of length 2. */
|
||||
if (tok_start + 2 == tok_end)
|
||||
{
|
||||
|
@ -553,8 +513,6 @@ lex (pfile, skip_evaluation)
|
|||
op.op = toktab->token;
|
||||
return op;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
op.op = *tok_start;
|
||||
return op;
|
||||
}
|
||||
|
@ -612,7 +570,7 @@ parse_escape (pfile, string_ptr, result_mask)
|
|||
case 'e':
|
||||
case 'E':
|
||||
if (CPP_PEDANTIC (pfile))
|
||||
cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, '\\%c'", c);
|
||||
cpp_pedwarn (pfile, "non-ISO-standard escape sequence, '\\%c'", c);
|
||||
return TARGET_ESC;
|
||||
case 'f':
|
||||
return TARGET_FF;
|
||||
|
@ -844,9 +802,7 @@ _cpp_parse_expr (pfile)
|
|||
char buff[5];
|
||||
|
||||
/* Save parser state and set it to something sane. */
|
||||
int save_only_seen_white = pfile->only_seen_white;
|
||||
int save_skipping = pfile->skipping;
|
||||
pfile->only_seen_white = 0;
|
||||
pfile->skipping = 0;
|
||||
|
||||
/* We've finished when we try to reduce this. */
|
||||
|
@ -875,7 +831,8 @@ _cpp_parse_expr (pfile)
|
|||
case ERROR:
|
||||
goto syntax_error;
|
||||
default:
|
||||
SYNTAX_ERROR ("invalid character in #if");
|
||||
SYNTAX_ERROR2 ("invalid character '%s' in #if",
|
||||
op_to_str (op.op, buff));
|
||||
|
||||
push_immediate:
|
||||
case INT:
|
||||
|
@ -1168,7 +1125,6 @@ _cpp_parse_expr (pfile)
|
|||
if (stack != init_stack)
|
||||
free (stack);
|
||||
CPP_SET_WRITTEN (pfile, old_written);
|
||||
pfile->only_seen_white = save_only_seen_white;
|
||||
pfile->skipping = save_skipping;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ open_include_file (pfile, filename)
|
|||
#ifdef EACCES
|
||||
if (errno == EACCES)
|
||||
{
|
||||
cpp_error (pfile, "included file `%s' exists but is not readable",
|
||||
cpp_error (pfile, "included file \"%s\" exists but is not readable",
|
||||
filename);
|
||||
}
|
||||
#endif
|
||||
|
@ -360,16 +360,16 @@ cpp_make_system_header (pfile, pbuf, flag)
|
|||
|
||||
#define PRINT_THIS_DEP(p, b) (CPP_PRINT_DEPS(p) > (b||p->system_include_depth))
|
||||
void
|
||||
_cpp_execute_include (pfile, f, len, no_reinclude, search_start)
|
||||
_cpp_execute_include (pfile, f, len, no_reinclude, search_start, angle_brackets)
|
||||
cpp_reader *pfile;
|
||||
U_CHAR *f;
|
||||
const U_CHAR *f;
|
||||
unsigned int len;
|
||||
int no_reinclude;
|
||||
struct file_name_list *search_start;
|
||||
int angle_brackets;
|
||||
{
|
||||
struct include_file *inc;
|
||||
char *fname = (char *)f;
|
||||
int angle_brackets = fname[0] == '<';
|
||||
char *fname;
|
||||
|
||||
if (!search_start)
|
||||
{
|
||||
|
@ -387,9 +387,8 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Remove quote marks. */
|
||||
fname++;
|
||||
len -= 2;
|
||||
fname = alloca (len + 1);
|
||||
memcpy (fname, f, len);
|
||||
fname[len] = '\0';
|
||||
|
||||
inc = find_include_file (pfile, fname, search_start);
|
||||
|
@ -470,32 +469,27 @@ _cpp_execute_include (pfile, f, len, no_reinclude, search_start)
|
|||
if F cannot be located or dated, 1, if it is newer and 0 if older. */
|
||||
|
||||
int
|
||||
_cpp_compare_file_date (pfile, f, len, search_start)
|
||||
_cpp_compare_file_date (pfile, f, len, angle_brackets)
|
||||
cpp_reader *pfile;
|
||||
U_CHAR *f;
|
||||
const U_CHAR *f;
|
||||
unsigned int len;
|
||||
struct file_name_list *search_start;
|
||||
int angle_brackets;
|
||||
{
|
||||
char *fname = (char *)f;
|
||||
int angle_brackets = fname[0] == '<';
|
||||
char *fname;
|
||||
struct file_name_list *search_start;
|
||||
struct include_file *inc;
|
||||
struct include_file *current_include = cpp_file_buffer (pfile)->inc;
|
||||
struct include_file *current_include = CPP_BUFFER (pfile)->inc;
|
||||
|
||||
if (!search_start)
|
||||
{
|
||||
if (angle_brackets)
|
||||
search_start = CPP_OPTION (pfile, bracket_include);
|
||||
else if (CPP_OPTION (pfile, ignore_srcdir))
|
||||
search_start = CPP_OPTION (pfile, quote_include);
|
||||
else
|
||||
search_start = CPP_BUFFER (pfile)->actual_dir;
|
||||
}
|
||||
if (angle_brackets)
|
||||
search_start = CPP_OPTION (pfile, bracket_include);
|
||||
else if (CPP_OPTION (pfile, ignore_srcdir))
|
||||
search_start = CPP_OPTION (pfile, quote_include);
|
||||
else
|
||||
search_start = CPP_BUFFER (pfile)->actual_dir;
|
||||
|
||||
/* Remove quote marks. */
|
||||
fname++;
|
||||
len -= 2;
|
||||
fname = alloca (len + 1);
|
||||
memcpy (fname, f, len);
|
||||
fname[len] = '\0';
|
||||
|
||||
inc = find_include_file (pfile, fname, search_start);
|
||||
|
||||
if (!inc)
|
||||
|
@ -534,6 +528,12 @@ cpp_read_file (pfile, fname)
|
|||
|
||||
f = open_include_file (pfile, fname);
|
||||
|
||||
if (f == NULL)
|
||||
{
|
||||
cpp_error_from_errno (pfile, fname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return read_include_file (pfile, f);
|
||||
}
|
||||
|
||||
|
@ -550,12 +550,17 @@ read_include_file (pfile, inc)
|
|||
cpp_buffer *fp;
|
||||
int fd = inc->fd;
|
||||
|
||||
/* Ensures we dump our current line before entering an include file. */
|
||||
if (CPP_BUFFER (pfile) && pfile->printer)
|
||||
cpp_output_tokens (pfile, pfile->printer,
|
||||
CPP_BUF_LINE (CPP_BUFFER (pfile)));
|
||||
|
||||
fp = cpp_push_buffer (pfile, NULL, 0);
|
||||
|
||||
if (fp == 0)
|
||||
goto push_fail;
|
||||
|
||||
if (fstat (fd, &st) < 0)
|
||||
if (fd < 0 || fstat (fd, &st) < 0)
|
||||
goto perror_fail;
|
||||
|
||||
inc->date = st.st_mtime;
|
||||
|
@ -622,9 +627,6 @@ read_include_file (pfile, inc)
|
|||
|
||||
if (length == 0)
|
||||
inc->cmacro = NEVER_REREAD;
|
||||
else
|
||||
/* Temporary - I hope. */
|
||||
length = _cpp_prescan (pfile, fp, length);
|
||||
|
||||
fp->rlimit = fp->buf + length;
|
||||
fp->cur = fp->buf;
|
||||
|
@ -637,13 +639,13 @@ read_include_file (pfile, inc)
|
|||
fp->actual_dir = actual_directory (pfile, inc->name);
|
||||
|
||||
pfile->input_stack_listing_current = 0;
|
||||
pfile->only_seen_white = 2;
|
||||
return 1;
|
||||
|
||||
perror_fail:
|
||||
cpp_error_from_errno (pfile, inc->name);
|
||||
/* Do not try to read this file again. */
|
||||
close (fd);
|
||||
if (fd != -1)
|
||||
close (fd);
|
||||
inc->fd = -1;
|
||||
inc->cmacro = NEVER_REREAD;
|
||||
fail:
|
||||
|
|
2106
gcc/cpphash.c
2106
gcc/cpphash.c
File diff suppressed because it is too large
Load diff
162
gcc/cpphash.h
162
gcc/cpphash.h
|
@ -25,11 +25,60 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
typedef unsigned char U_CHAR;
|
||||
#define U (const U_CHAR *) /* Intended use: U"string" */
|
||||
|
||||
/* Structure used for assertion predicates. */
|
||||
struct predicate
|
||||
/* Order here matters. Those beyond SPELL_NONE store their spelling
|
||||
in the token list, and it's length in the token->val.name.len. */
|
||||
enum spell_type
|
||||
{
|
||||
struct predicate *next;
|
||||
struct cpp_toklist answer;
|
||||
SPELL_OPERATOR = 0,
|
||||
SPELL_CHAR,
|
||||
SPELL_NONE,
|
||||
SPELL_IDENT,
|
||||
SPELL_STRING
|
||||
};
|
||||
|
||||
struct token_spelling
|
||||
{
|
||||
ENUM_BITFIELD(spell_type) type : CHAR_BIT;
|
||||
const U_CHAR *spelling;
|
||||
};
|
||||
|
||||
extern const struct token_spelling token_spellings[];
|
||||
|
||||
/* Chained list of answers to an assertion. */
|
||||
struct answer
|
||||
{
|
||||
struct answer *next;
|
||||
cpp_toklist list;
|
||||
};
|
||||
#define FREE_ANSWER(answer) do {_cpp_free_toklist (&answer->list); \
|
||||
free (answer); } while (0)
|
||||
|
||||
/* Values for the origin field of struct directive. KANDR directives
|
||||
come from traditional (K&R) C. STDC89 directives come from the
|
||||
1989 C standard. EXTENSION directives are extensions. */
|
||||
#define KANDR 0
|
||||
#define STDC89 1
|
||||
#define EXTENSION 2
|
||||
|
||||
/* Values for the flags field of struct directive. COND indicates a
|
||||
conditional. EXPAND means that macros are to be expanded on the
|
||||
directive line. INCL means to treat "..." and <...> as
|
||||
q-char-sequence and h-char-sequence respectively. COMMENTS means
|
||||
preserve comments in the directive if -C. */
|
||||
#define COND (1 << 0)
|
||||
#define EXPAND (1 << 1)
|
||||
#define INCL (1 << 2)
|
||||
#define COMMENTS (1 << 3)
|
||||
|
||||
/* Defines one #-directive, including how to handle it. */
|
||||
typedef int (*directive_handler) PARAMS ((cpp_reader *));
|
||||
struct directive
|
||||
{
|
||||
directive_handler handler; /* Function to handle directive. */
|
||||
const U_CHAR *name; /* Name of directive. */
|
||||
unsigned short length; /* Length of name. */
|
||||
unsigned char origin; /* Origin of directive. */
|
||||
unsigned char flags; /* Flags describing this directive. */
|
||||
};
|
||||
|
||||
/* List of directories to look for include files in. */
|
||||
|
@ -105,12 +154,6 @@ extern unsigned char _cpp_IStable[256];
|
|||
|
||||
/* Macros. */
|
||||
|
||||
/* One character lookahead in the input buffer. Note that if this
|
||||
returns EOF, it does *not* necessarily mean the file's end has been
|
||||
reached. */
|
||||
#define CPP_BUF_PEEK(BUFFER) \
|
||||
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
|
||||
|
||||
/* Make sure PFILE->token_buffer has space for at least N more characters. */
|
||||
#define CPP_RESERVE(PFILE, N) \
|
||||
(CPP_WRITTEN (PFILE) + (size_t)(N) > (PFILE)->token_buffer_size \
|
||||
|
@ -127,53 +170,15 @@ extern unsigned char _cpp_IStable[256];
|
|||
/* Append character CH to PFILE's output buffer. Make space if need be. */
|
||||
#define CPP_PUTC(PFILE, CH) (CPP_RESERVE (PFILE, 1), CPP_PUTC_Q (PFILE, CH))
|
||||
|
||||
/* Advance the current line by one. */
|
||||
#define CPP_BUMP_BUFFER_LINE(PBUF) ((PBUF)->lineno++,\
|
||||
(PBUF)->line_base = (PBUF)->cur)
|
||||
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
|
||||
#define CPP_BUMP_BUFFER_LINE_CUR(PBUF, CUR) ((PBUF)->lineno++,\
|
||||
(PBUF)->line_base = CUR)
|
||||
#define CPP_BUMP_LINE_CUR(PFILE, CUR) \
|
||||
CPP_BUMP_BUFFER_LINE_CUR(CPP_BUFFER(PFILE), CUR)
|
||||
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
|
||||
|
||||
/* Are we in column 1 right now? Used mainly for -traditional handling
|
||||
of directives. */
|
||||
#define CPP_IN_COLUMN_1(PFILE) \
|
||||
(CPP_BUFFER (PFILE)->cur - CPP_BUFFER (PFILE)->line_base == 1)
|
||||
|
||||
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
|
||||
#define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional)
|
||||
#define CPP_IN_SYSTEM_HEADER(PFILE) (cpp_file_buffer (PFILE)->inc->sysp)
|
||||
#define CPP_IN_SYSTEM_HEADER(PFILE) (CPP_BUFFER (PFILE)->inc->sysp)
|
||||
#define CPP_PEDANTIC(PF) \
|
||||
(CPP_OPTION (PF, pedantic) && !CPP_IN_SYSTEM_HEADER (PF))
|
||||
#define CPP_WTRADITIONAL(PF) \
|
||||
(CPP_OPTION (PF, warn_traditional) && !CPP_IN_SYSTEM_HEADER (PF))
|
||||
|
||||
/* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion.
|
||||
(Note that it is false while we're expanding macro *arguments*.) */
|
||||
#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->macro != NULL)
|
||||
|
||||
/* Remember the current position of PFILE so it may be returned to
|
||||
after looking ahead a bit.
|
||||
|
||||
Note that when you set a mark, you _must_ return to that mark. You
|
||||
may not forget about it and continue parsing. You may not pop a
|
||||
buffer with an active mark. You may not call CPP_BUMP_LINE while a
|
||||
mark is active. */
|
||||
#define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur)
|
||||
#define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->mark, (IP)->mark = 0)
|
||||
#define CPP_SET_MARK(PFILE) CPP_SET_BUF_MARK(CPP_BUFFER(PFILE))
|
||||
#define CPP_GOTO_MARK(PFILE) CPP_GOTO_BUF_MARK(CPP_BUFFER(PFILE))
|
||||
|
||||
/* ACTIVE_MARK_P is true if there's a live mark in the buffer. */
|
||||
#define ACTIVE_MARK_P(PFILE) (CPP_BUFFER (PFILE)->mark != 0)
|
||||
|
||||
/* Are mark and point adjacent characters? Used mostly to deal with
|
||||
the somewhat annoying semantic of #define. */
|
||||
#define ADJACENT_TO_MARK(PFILE) \
|
||||
(CPP_BUFFER(PFILE)->cur - CPP_BUFFER(PFILE)->mark == 1)
|
||||
|
||||
/* Flags for _cpp_init_toklist. */
|
||||
#define DUMMY_TOKEN 0
|
||||
#define NO_DUMMY_TOKEN 1
|
||||
|
@ -181,22 +186,19 @@ extern unsigned char _cpp_IStable[256];
|
|||
/* In cpphash.c */
|
||||
extern unsigned int _cpp_calc_hash PARAMS ((const U_CHAR *, size_t));
|
||||
extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
|
||||
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_toklist *,
|
||||
cpp_hashnode *));
|
||||
extern int _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
extern void _cpp_dump_definition PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
extern void _cpp_quote_string PARAMS ((cpp_reader *, const U_CHAR *));
|
||||
extern void _cpp_macroexpand PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
extern void _cpp_init_macro_hash PARAMS ((cpp_reader *));
|
||||
extern void _cpp_dump_macro_hash PARAMS ((cpp_reader *));
|
||||
|
||||
/* In cppfiles.c */
|
||||
extern void _cpp_simplify_pathname PARAMS ((char *));
|
||||
extern void _cpp_execute_include PARAMS ((cpp_reader *, U_CHAR *,
|
||||
extern void _cpp_execute_include PARAMS ((cpp_reader *, const U_CHAR *,
|
||||
unsigned int, int,
|
||||
struct file_name_list *));
|
||||
extern int _cpp_compare_file_date PARAMS ((cpp_reader *, U_CHAR *,
|
||||
unsigned int,
|
||||
struct file_name_list *));
|
||||
struct file_name_list *,
|
||||
int));
|
||||
extern int _cpp_compare_file_date PARAMS ((cpp_reader *, const U_CHAR *,
|
||||
unsigned int, int));
|
||||
extern void _cpp_init_include_table PARAMS ((cpp_reader *));
|
||||
extern const char *_cpp_fake_include PARAMS ((cpp_reader *, const char *));
|
||||
|
||||
|
@ -204,40 +206,46 @@ extern const char *_cpp_fake_include PARAMS ((cpp_reader *, const char *));
|
|||
extern int _cpp_parse_expr PARAMS ((cpp_reader *));
|
||||
|
||||
/* In cpplex.c */
|
||||
extern void _cpp_parse_name PARAMS ((cpp_reader *, int));
|
||||
extern void _cpp_skip_rest_of_line PARAMS ((cpp_reader *));
|
||||
extern void _cpp_skip_hspace PARAMS ((cpp_reader *));
|
||||
extern void _cpp_expand_to_buffer PARAMS ((cpp_reader *,
|
||||
const unsigned char *, int));
|
||||
extern int _cpp_parse_assertion PARAMS ((cpp_reader *));
|
||||
extern enum cpp_ttype _cpp_lex_token PARAMS ((cpp_reader *));
|
||||
extern ssize_t _cpp_prescan PARAMS ((cpp_reader *, cpp_buffer *,
|
||||
ssize_t));
|
||||
extern void _cpp_free_temp_tokens PARAMS ((cpp_reader *));
|
||||
extern void _cpp_init_input_buffer PARAMS ((cpp_reader *));
|
||||
extern void _cpp_grow_token_buffer PARAMS ((cpp_reader *, long));
|
||||
extern enum cpp_ttype _cpp_get_directive_token
|
||||
PARAMS ((cpp_reader *));
|
||||
extern enum cpp_ttype _cpp_get_define_token
|
||||
PARAMS ((cpp_reader *));
|
||||
extern enum cpp_ttype _cpp_scan_until PARAMS ((cpp_reader *, cpp_toklist *,
|
||||
enum cpp_ttype));
|
||||
extern void _cpp_init_toklist PARAMS ((cpp_toklist *, int));
|
||||
extern void _cpp_clear_toklist PARAMS ((cpp_toklist *));
|
||||
extern void _cpp_free_toklist PARAMS ((cpp_toklist *));
|
||||
extern void _cpp_slice_toklist PARAMS ((cpp_toklist *,
|
||||
const cpp_token *,
|
||||
const cpp_token *));
|
||||
extern void _cpp_squeeze_toklist PARAMS ((cpp_toklist *));
|
||||
extern void _cpp_free_toklist PARAMS ((const cpp_toklist *));
|
||||
extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
|
||||
const cpp_token *));
|
||||
extern int _cpp_equiv_toklists PARAMS ((const cpp_toklist *,
|
||||
const cpp_toklist *));
|
||||
extern void _cpp_expand_token_space PARAMS ((cpp_toklist *, unsigned int));
|
||||
extern void _cpp_reserve_name_space PARAMS ((cpp_toklist *, unsigned int));
|
||||
extern void _cpp_expand_name_space PARAMS ((cpp_toklist *, unsigned int));
|
||||
extern void _cpp_dump_list PARAMS ((cpp_reader *,
|
||||
const cpp_toklist *,
|
||||
const cpp_token *, int));
|
||||
extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
|
||||
const cpp_token *));
|
||||
extern void _cpp_run_directive PARAMS ((cpp_reader *,
|
||||
const struct directive *,
|
||||
const char *, size_t));
|
||||
extern unsigned int _cpp_get_line PARAMS ((cpp_reader *,
|
||||
unsigned int *));
|
||||
extern const cpp_token *_cpp_get_raw_token PARAMS ((cpp_reader *));
|
||||
extern void _cpp_push_token PARAMS ((cpp_reader *, const cpp_token*));
|
||||
extern const cpp_token *_cpp_glue_header_name PARAMS ((cpp_reader *));
|
||||
|
||||
/* In cpplib.c */
|
||||
extern int _cpp_handle_directive PARAMS ((cpp_reader *));
|
||||
extern const struct directive *_cpp_check_directive
|
||||
PARAMS ((cpp_reader *, const cpp_token *, int));
|
||||
extern const struct directive *_cpp_check_linemarker
|
||||
PARAMS ((cpp_reader *, const cpp_token *, int));
|
||||
extern void _cpp_unwind_if_stack PARAMS ((cpp_reader *, cpp_buffer *));
|
||||
extern void _cpp_check_directive PARAMS ((cpp_toklist *, cpp_token *));
|
||||
extern cpp_hashnode * _cpp_parse_assertion PARAMS ((cpp_reader *,
|
||||
struct answer **));
|
||||
extern struct answer** find_answer PARAMS ((cpp_hashnode *,
|
||||
const cpp_toklist *));
|
||||
|
||||
/* Utility routines and macros. */
|
||||
#define xnew(T) (T *) xmalloc (sizeof(T))
|
||||
|
|
151
gcc/cppinit.c
151
gcc/cppinit.c
|
@ -215,8 +215,6 @@ static void append_include_chain PARAMS ((cpp_reader *,
|
|||
char *, int, int));
|
||||
static void merge_include_chains PARAMS ((cpp_reader *));
|
||||
|
||||
static void dump_special_to_buffer PARAMS ((cpp_reader *, const U_CHAR *,
|
||||
size_t));
|
||||
static void initialize_dependency_output PARAMS ((cpp_reader *));
|
||||
static void initialize_standard_includes PARAMS ((cpp_reader *));
|
||||
static void new_pending_directive PARAMS ((struct cpp_pending *,
|
||||
|
@ -345,7 +343,7 @@ append_include_chain (pfile, pend, dir, path, cxx_aware)
|
|||
if (errno != ENOENT)
|
||||
cpp_notice_from_errno (pfile, dir);
|
||||
else if (CPP_OPTION (pfile, verbose))
|
||||
fprintf (stderr, _("ignoring nonexistent directory `%s'\n"), dir);
|
||||
fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), dir);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -442,7 +440,7 @@ merge_include_chains (pfile)
|
|||
&& cur->dev == other->dev)
|
||||
{
|
||||
if (CPP_OPTION (pfile, verbose))
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"),
|
||||
cur->name);
|
||||
|
||||
prev->next = cur->next;
|
||||
|
@ -462,7 +460,7 @@ merge_include_chains (pfile)
|
|||
&& cur->dev == other->dev)
|
||||
{
|
||||
if (CPP_OPTION (pfile, verbose))
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"),
|
||||
cur->name);
|
||||
|
||||
prev->next = cur->next;
|
||||
|
@ -481,7 +479,7 @@ merge_include_chains (pfile)
|
|||
if (quote == qtail)
|
||||
{
|
||||
if (CPP_OPTION (pfile, verbose))
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"),
|
||||
quote->name);
|
||||
|
||||
free (quote->name);
|
||||
|
@ -495,7 +493,7 @@ merge_include_chains (pfile)
|
|||
cur = cur->next;
|
||||
cur->next = brack;
|
||||
if (CPP_OPTION (pfile, verbose))
|
||||
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
|
||||
fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"),
|
||||
qtail->name);
|
||||
|
||||
free (qtail->name);
|
||||
|
@ -513,24 +511,6 @@ merge_include_chains (pfile)
|
|||
}
|
||||
|
||||
|
||||
/* Write out a #define command for the special named MACRO_NAME
|
||||
to PFILE's token_buffer. */
|
||||
|
||||
static void
|
||||
dump_special_to_buffer (pfile, macro_name, macro_len)
|
||||
cpp_reader *pfile;
|
||||
const U_CHAR *macro_name;
|
||||
size_t macro_len;
|
||||
{
|
||||
static const char define_directive[] = "#define ";
|
||||
CPP_RESERVE (pfile, sizeof(define_directive) + macro_len);
|
||||
CPP_PUTS_Q (pfile, define_directive, sizeof(define_directive)-1);
|
||||
CPP_PUTS_Q (pfile, macro_name, macro_len);
|
||||
CPP_PUTC_Q (pfile, ' ');
|
||||
_cpp_expand_to_buffer (pfile, macro_name, macro_len);
|
||||
CPP_PUTC (pfile, '\n');
|
||||
}
|
||||
|
||||
/* Initialize a cpp_reader structure. */
|
||||
void
|
||||
cpp_reader_init (pfile)
|
||||
|
@ -545,6 +525,7 @@ cpp_reader_init (pfile)
|
|||
CPP_OPTION (pfile, dollars_in_ident) = 1;
|
||||
CPP_OPTION (pfile, cplusplus_comments) = 1;
|
||||
CPP_OPTION (pfile, warn_import) = 1;
|
||||
CPP_OPTION (pfile, warn_paste) = 1;
|
||||
CPP_OPTION (pfile, discard_comments) = 1;
|
||||
CPP_OPTION (pfile, show_column) = 1;
|
||||
CPP_OPTION (pfile, tabstop) = 8;
|
||||
|
@ -596,25 +577,19 @@ cpp_cleanup (pfile)
|
|||
pfile->token_buffer = NULL;
|
||||
}
|
||||
|
||||
if (pfile->input_buffer)
|
||||
{
|
||||
free (pfile->input_buffer);
|
||||
pfile->input_buffer = NULL;
|
||||
pfile->input_buffer_len = 0;
|
||||
}
|
||||
|
||||
if (pfile->deps)
|
||||
deps_free (pfile->deps);
|
||||
|
||||
htab_delete (pfile->hashtab);
|
||||
splay_tree_delete (pfile->all_include_files);
|
||||
_cpp_free_temp_tokens (pfile);
|
||||
}
|
||||
|
||||
|
||||
/* This structure defines one built-in macro. A node of type TYPE will
|
||||
be entered in the macro hash table under the name NAME, with value
|
||||
VALUE (if any). FLAGS tweaks the behavior a little:
|
||||
DUMP write debug info for this macro
|
||||
VALUE (if any). Two values are not compile time constants, so we tag
|
||||
them in the FLAGS field instead:
|
||||
VERS value is the global version_string, quoted
|
||||
ULP value is the global user_label_prefix
|
||||
*/
|
||||
|
@ -622,18 +597,17 @@ cpp_cleanup (pfile)
|
|||
struct builtin
|
||||
{
|
||||
const U_CHAR *name;
|
||||
const U_CHAR *value;
|
||||
const char *value;
|
||||
unsigned short type;
|
||||
unsigned short flags;
|
||||
unsigned int len;
|
||||
};
|
||||
#define DUMP 0x01
|
||||
#define VERS 0x02
|
||||
#define ULP 0x04
|
||||
#define VERS 0x01
|
||||
#define ULP 0x02
|
||||
|
||||
#define B(n, t) { U n, 0, t, 0, sizeof n - 1 }
|
||||
#define C(n, v) { U n, U v, T_CONST, DUMP, sizeof n - 1 }
|
||||
#define X(n, v, t, f) { U n, U v, t, DUMP|f, sizeof n - 1 }
|
||||
#define B(n, t) { U n, 0, t, 0, sizeof n - 1 }
|
||||
#define C(n, v) { U n, v, T_MACRO, 0, sizeof n - 1 }
|
||||
#define X(n, f) { U n, 0, T_MACRO, f, sizeof n - 1 }
|
||||
static const struct builtin builtin_array[] =
|
||||
{
|
||||
B("__TIME__", T_TIME),
|
||||
|
@ -642,10 +616,10 @@ static const struct builtin builtin_array[] =
|
|||
B("__BASE_FILE__", T_BASE_FILE),
|
||||
B("__LINE__", T_SPECLINE),
|
||||
B("__INCLUDE_LEVEL__", T_INCLUDE_LEVEL),
|
||||
B("__STDC__", T_STDC),
|
||||
|
||||
X("__VERSION__", 0, T_XCONST, VERS),
|
||||
X("__USER_LABEL_PREFIX__", 0, T_CONST, ULP),
|
||||
X("__STDC__", "1", T_STDC, 0),
|
||||
X("__VERSION__", VERS),
|
||||
X("__USER_LABEL_PREFIX__", ULP),
|
||||
C("__REGISTER_PREFIX__", REGISTER_PREFIX),
|
||||
C("__HAVE_BUILTIN_SETJMP__", "1"),
|
||||
#ifndef NO_BUILTIN_SIZE_TYPE
|
||||
|
@ -671,35 +645,47 @@ initialize_builtins (pfile)
|
|||
cpp_reader *pfile;
|
||||
{
|
||||
const struct builtin *b;
|
||||
const U_CHAR *val;
|
||||
cpp_hashnode *hp;
|
||||
for(b = builtin_array; b < builtin_array_end; b++)
|
||||
{
|
||||
if (b->type == T_STDC && CPP_TRADITIONAL (pfile))
|
||||
continue;
|
||||
|
||||
if (b->flags & ULP)
|
||||
val = (const U_CHAR *) user_label_prefix;
|
||||
else if (b->flags & VERS)
|
||||
if (b->type == T_MACRO)
|
||||
{
|
||||
val = (const U_CHAR *) xmalloc (strlen (version_string) + 3);
|
||||
sprintf ((char *)val, "\"%s\"", version_string);
|
||||
const char *val;
|
||||
char *str;
|
||||
|
||||
if (b->flags & VERS)
|
||||
{
|
||||
/* Allocate enough space for 'name="value"\0'. */
|
||||
str = xmalloc (b->len + strlen (version_string) + 4);
|
||||
sprintf (str, "%s=\"%s\"", b->name, version_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (b->flags & ULP)
|
||||
val = user_label_prefix;
|
||||
else
|
||||
val = b->value;
|
||||
|
||||
/* Allocate enough space for "name=value\0". */
|
||||
str = xmalloc (b->len + strlen (val) + 2);
|
||||
sprintf(str, "%s=%s", b->name, val);
|
||||
}
|
||||
cpp_define (pfile, str);
|
||||
}
|
||||
else
|
||||
val = b->value;
|
||||
{
|
||||
cpp_hashnode *hp;
|
||||
|
||||
if (b->type == T_STDC && CPP_TRADITIONAL (pfile))
|
||||
continue;
|
||||
|
||||
hp = cpp_lookup (pfile, b->name, b->len);
|
||||
hp->value.cpval = val;
|
||||
hp->type = b->type;
|
||||
|
||||
if ((b->flags & DUMP) && CPP_OPTION (pfile, debug_output))
|
||||
dump_special_to_buffer (pfile, b->name, b->len);
|
||||
hp = cpp_lookup (pfile, b->name, b->len);
|
||||
hp->type = b->type;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef DUMP
|
||||
#undef STDC
|
||||
#undef VERS
|
||||
#undef ULP
|
||||
#undef builtin_array_end
|
||||
|
||||
/* Another subroutine of cpp_start_read. This one sets up to do
|
||||
dependency-file output. */
|
||||
|
@ -889,6 +875,13 @@ cpp_start_read (pfile, print, fname)
|
|||
if (CPP_OPTION (pfile, cplusplus))
|
||||
CPP_OPTION (pfile, warn_traditional) = 0;
|
||||
|
||||
/* Do not warn about illegal token pasting if -traditional,
|
||||
-lang-fortran, or -lang-asm. */
|
||||
if (CPP_OPTION (pfile, traditional)
|
||||
|| CPP_OPTION (pfile, lang_fortran)
|
||||
|| CPP_OPTION (pfile, lang_asm))
|
||||
CPP_OPTION (pfile, warn_paste) = 0;
|
||||
|
||||
/* Set this if it hasn't been set already. */
|
||||
if (user_label_prefix == NULL)
|
||||
user_label_prefix = USER_LABEL_PREFIX;
|
||||
|
@ -898,6 +891,16 @@ cpp_start_read (pfile, print, fname)
|
|||
if (CPP_OPTION (pfile, preprocessed))
|
||||
pfile->no_macro_expand++;
|
||||
|
||||
/* Figure out if we need to save function macro parameter spellings.
|
||||
We don't use CPP_PEDANTIC() here because that depends on whether
|
||||
or not the current file is a system header, and there is no
|
||||
current file yet. */
|
||||
pfile->save_parameter_spellings =
|
||||
CPP_OPTION (pfile, pedantic)
|
||||
|| CPP_OPTION (pfile, debug_output)
|
||||
|| CPP_OPTION (pfile, dump_macros) == dump_definitions
|
||||
|| CPP_OPTION (pfile, dump_macros) == dump_only;
|
||||
|
||||
/* Set up the IStable. This doesn't do anything if we were compiled
|
||||
with a compiler that supports C99 designated initializers. */
|
||||
init_IStable ();
|
||||
|
@ -946,13 +949,12 @@ cpp_start_read (pfile, print, fname)
|
|||
as line 0. */
|
||||
|
||||
CPP_BUFFER (pfile)->lineno = 0;
|
||||
|
||||
if (print)
|
||||
{
|
||||
print->lineno = 0;
|
||||
print->last_fname = CPP_BUFFER (pfile)->nominal_fname;
|
||||
print->last_id = pfile->include_depth;
|
||||
print->written = CPP_WRITTEN (pfile);
|
||||
print->lineno = 0;
|
||||
}
|
||||
|
||||
/* Install __LINE__, etc. */
|
||||
|
@ -968,10 +970,13 @@ cpp_start_read (pfile, print, fname)
|
|||
p = q;
|
||||
}
|
||||
pfile->done_initializing = 1;
|
||||
pfile->only_seen_white = 2;
|
||||
|
||||
/* Now flush any output recorded during initialization, and advance
|
||||
to line 1 of the main input file. */
|
||||
CPP_BUFFER (pfile)->lineno = 1;
|
||||
|
||||
if (print && ! CPP_OPTION (pfile, no_output))
|
||||
cpp_output_tokens (pfile, print);
|
||||
cpp_output_tokens (pfile, print, 1);
|
||||
|
||||
/* The -imacros files can be scanned now, but the -include files
|
||||
have to be pushed onto the include stack and processed later,
|
||||
|
@ -992,7 +997,7 @@ cpp_start_read (pfile, print, fname)
|
|||
{
|
||||
if (cpp_read_file (pfile, p->arg)
|
||||
&& print && ! CPP_OPTION (pfile, no_output))
|
||||
cpp_output_tokens (pfile, print);
|
||||
cpp_output_tokens (pfile, print, 1); /* record entry to file */
|
||||
q = p->next;
|
||||
free (p);
|
||||
p = q;
|
||||
|
@ -1073,7 +1078,7 @@ cpp_finish (pfile, print)
|
|||
/* Flush any pending output. */
|
||||
if (print)
|
||||
{
|
||||
cpp_output_tokens (pfile, print);
|
||||
cpp_output_tokens (pfile, print, print->lineno);
|
||||
if (ferror (print->outf) || fclose (print->outf))
|
||||
cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
|
||||
}
|
||||
|
@ -1753,6 +1758,8 @@ handle_option (pfile, argc, argv)
|
|||
CPP_OPTION (pfile, warn_undef) = 1;
|
||||
else if (!strcmp (argv[i], "-Wimport"))
|
||||
CPP_OPTION (pfile, warn_import) = 1;
|
||||
else if (!strcmp (argv[i], "-Wpaste"))
|
||||
CPP_OPTION (pfile, warn_paste) = 1;
|
||||
else if (!strcmp (argv[i], "-Werror"))
|
||||
CPP_OPTION (pfile, warnings_are_errors) = 1;
|
||||
else if (!strcmp (argv[i], "-Wno-traditional"))
|
||||
|
@ -1767,6 +1774,8 @@ handle_option (pfile, argc, argv)
|
|||
CPP_OPTION (pfile, warn_undef) = 0;
|
||||
else if (!strcmp (argv[i], "-Wno-import"))
|
||||
CPP_OPTION (pfile, warn_import) = 0;
|
||||
else if (!strcmp (argv[i], "-Wno-paste"))
|
||||
CPP_OPTION (pfile, warn_paste) = 0;
|
||||
else if (!strcmp (argv[i], "-Wno-error"))
|
||||
CPP_OPTION (pfile, warnings_are_errors) = 0;
|
||||
break;
|
||||
|
@ -1836,10 +1845,10 @@ Switches:\n\
|
|||
(dirs specified with -isystem will still be used)\n\
|
||||
-nostdinc++ Do not search system include directories for C++\n\
|
||||
-o <file> Put output into <file>\n\
|
||||
-pedantic Issue all warnings demanded by strict ANSI C\n\
|
||||
-pedantic Issue all warnings demanded by strict ISO C\n\
|
||||
-pedantic-errors Issue -pedantic warnings as errors instead\n\
|
||||
-traditional Follow K&R pre-processor behaviour\n\
|
||||
-trigraphs Support ANSI C trigraphs\n\
|
||||
-trigraphs Support ISO C trigraphs\n\
|
||||
-lang-c Assume that the input sources are in C\n\
|
||||
-lang-c89 Assume that the input sources are in C89\n\
|
||||
-lang-c++ Assume that the input sources are in C++\n\
|
||||
|
|
3793
gcc/cpplex.c
3793
gcc/cpplex.c
File diff suppressed because it is too large
Load diff
1621
gcc/cpplib.c
1621
gcc/cpplib.c
File diff suppressed because it is too large
Load diff
212
gcc/cpplib.h
212
gcc/cpplib.h
|
@ -108,7 +108,8 @@ typedef struct cpp_hashnode cpp_hashnode;
|
|||
T(CPP_DOT_STAR, ".*") \
|
||||
T(CPP_MIN, "<?") /* extension */ \
|
||||
T(CPP_MAX, ">?") \
|
||||
C(CPP_OTHER, 0) /* stray punctuation */ \
|
||||
T(CPP_PLACEMARKER, "") /* Placemarker token. */ \
|
||||
C(CPP_OTHER, 0) /* stray punctuation */ \
|
||||
\
|
||||
I(CPP_NAME, 0) /* word */ \
|
||||
I(CPP_INT, 0) /* 23 */ \
|
||||
|
@ -121,15 +122,11 @@ typedef struct cpp_hashnode cpp_hashnode;
|
|||
\
|
||||
I(CPP_COMMENT, 0) /* Only if output comments. */ \
|
||||
N(CPP_MACRO_ARG, 0) /* Macro argument. */ \
|
||||
N(CPP_SUBLIST, 0) /* Sublist. */ \
|
||||
N(CPP_EOF, 0) /* End of file. */ \
|
||||
N(CPP_HEADER_NAME, 0) /* <stdio.h> in #include */ \
|
||||
I(CPP_HEADER_NAME, 0) /* <stdio.h> in #include */ \
|
||||
\
|
||||
/* Obsolete - will be removed when no code uses them still. */ \
|
||||
T(CPP_VSPACE, "\n") /* End of line. */ \
|
||||
N(CPP_HSPACE, 0) /* Horizontal white space. */ \
|
||||
N(CPP_DIRECTIVE, 0) /* #define and the like */ \
|
||||
N(CPP_MACRO, 0) /* Like a NAME, but expanded. */
|
||||
T(CPP_VSPACE, "\n") /* End of line. */
|
||||
|
||||
#define T(e, s) e,
|
||||
#define I(e, s) e,
|
||||
|
@ -154,49 +151,42 @@ struct cpp_name
|
|||
const unsigned char *text;
|
||||
};
|
||||
|
||||
/* Accessor macros for token lists - all expect you have a
|
||||
list and an index. */
|
||||
|
||||
#define TOK_TYPE(l_, i_) ((l_)->tokens[i_].type)
|
||||
#define TOK_FLAGS(l_, i_) ((l_)->tokens[i_].flags)
|
||||
#define TOK_AUX(l_, i_) ((l_)->tokens[i_].aux)
|
||||
#define TOK_COL(l_, i_) ((l_)->tokens[i_].col)
|
||||
#define TOK_INT(l_, i_) ((l_)->tokens[i_].val.integer)
|
||||
#define TOK_NAME(l_, i_) ((l_)->tokens[i_].val.name.text)
|
||||
#define TOK_LEN(l_, i_) ((l_)->tokens[i_].val.name.len)
|
||||
|
||||
#define TOK_PREV_WHITE(l_, i_) (TOK_FLAGS(l_, i_) & PREV_WHITESPACE)
|
||||
|
||||
/* Flags for the cpp_token structure. */
|
||||
#define PREV_WHITESPACE 1 /* If whitespace before this token. */
|
||||
#define BOL 2 /* Beginning of line. */
|
||||
#define DIGRAPH 4 /* If it was a digraph. */
|
||||
#define UNSIGNED_INT 8 /* If int preprocessing token unsigned. */
|
||||
#define PREV_WHITE (1 << 0) /* If whitespace before this token. */
|
||||
#define BOL (1 << 1) /* Beginning of logical line. */
|
||||
#define DIGRAPH (1 << 2) /* If it was a digraph. */
|
||||
#define STRINGIFY_ARG (1 << 3) /* If macro argument to be stringified. */
|
||||
#define PASTE_LEFT (1 << 4) /* If on LHS of a ## operator. */
|
||||
#define PASTED (1 << 5) /* The result of a ## operator. */
|
||||
#define GNU_VARARGS (1 << 6) /* GNU ## kludge. */
|
||||
|
||||
/* A preprocessing token. This has been carefully packed and should
|
||||
occupy 16 bytes on both 32- and 64-bit hosts. */
|
||||
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
|
||||
struct cpp_token
|
||||
{
|
||||
unsigned short col; /* starting column of this token */
|
||||
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* node type */
|
||||
unsigned char flags; /* flags - see above */
|
||||
unsigned int aux; /* CPP_OTHER character. Hash of a
|
||||
NAME, or something - see uses
|
||||
in the code */
|
||||
unsigned int line; /* starting line number of this token */
|
||||
unsigned short col; /* starting column of this token */
|
||||
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
|
||||
unsigned char flags; /* flags - see above */
|
||||
|
||||
union
|
||||
{
|
||||
struct cpp_name name; /* a string */
|
||||
HOST_WIDEST_INT integer; /* an integer */
|
||||
HOST_WIDEST_INT integer; /* an integer */
|
||||
struct cpp_name name; /* a string */
|
||||
unsigned int aux; /* argument no. for a CPP_MACRO_ARG, or
|
||||
character represented by CPP_OTHER. */
|
||||
} val;
|
||||
};
|
||||
|
||||
/* General flags. */
|
||||
#define LIST_OFFSET (1 << 0)
|
||||
/* cpp_toklist flags. */
|
||||
#define LIST_OFFSET (1 << 0)
|
||||
#define VAR_ARGS (1 << 1)
|
||||
#define BEG_OF_FILE (1 << 2)
|
||||
|
||||
/* Directive flags. */
|
||||
#define SYNTAX_INCLUDE (1 << 8)
|
||||
|
||||
typedef int (*directive_handler) PARAMS ((cpp_reader *));
|
||||
struct directive; /* These are deliberately incomplete. */
|
||||
struct answer;
|
||||
struct macro_args;
|
||||
struct cpp_context;
|
||||
|
||||
struct cpp_toklist
|
||||
{
|
||||
|
@ -208,11 +198,15 @@ struct cpp_toklist
|
|||
unsigned int name_used; /* _bytes_ used */
|
||||
unsigned int name_cap; /* _bytes_ allocated */
|
||||
|
||||
/* If the list represents a directive, this points to it. */
|
||||
const struct directive *directive;
|
||||
|
||||
const char *file; /* in file name */
|
||||
unsigned int line; /* starting line number */
|
||||
|
||||
/* The handler to call after lexing the rest of this line.
|
||||
-1 for none */
|
||||
short dirno;
|
||||
unsigned short params_len; /* length of macro parameter names. */
|
||||
|
||||
short int paramc; /* no. of macro params (-1 = obj-like). */
|
||||
|
||||
/* Per-list flags, see above */
|
||||
unsigned short flags;
|
||||
|
@ -224,12 +218,12 @@ struct cpp_buffer
|
|||
const unsigned char *rlimit; /* end of valid data */
|
||||
const unsigned char *buf; /* entire buffer */
|
||||
const unsigned char *line_base; /* start of current line */
|
||||
const unsigned char *mark; /* Saved position for lengthy backtrack. */
|
||||
|
||||
struct cpp_buffer *prev;
|
||||
|
||||
/* Filename specified with #line command. */
|
||||
const char *nominal_fname;
|
||||
|
||||
/* Actual directory of this file, used only for "" includes */
|
||||
struct file_name_list *actual_dir;
|
||||
|
||||
|
@ -237,10 +231,6 @@ struct cpp_buffer
|
|||
to record control macros. */
|
||||
struct include_file *inc;
|
||||
|
||||
/* If the buffer is the expansion of a macro, this points to the
|
||||
macro's hash table entry. */
|
||||
struct cpp_hashnode *macro;
|
||||
|
||||
/* Value of if_stack at start of this file.
|
||||
Used to prohibit unmatched #endif (etc) in an include file. */
|
||||
struct if_stack *if_stack;
|
||||
|
@ -248,29 +238,13 @@ struct cpp_buffer
|
|||
/* Line number at line_base (above). */
|
||||
unsigned int lineno;
|
||||
|
||||
/* True if buffer contains escape sequences.
|
||||
Currently there are two kinds:
|
||||
"\r-" means following identifier should not be macro-expanded.
|
||||
"\r " means a token-separator. This turns into " " in final output
|
||||
if not stringizing and needed to separate tokens; otherwise nothing.
|
||||
Any other two-character sequence beginning with \r is an error.
|
||||
|
||||
If this is NOT set, then \r is a one-character escape meaning backslash
|
||||
newline. This is guaranteed not to occur in the middle of a token.
|
||||
The two interpretations of \r do not conflict, because the two-character
|
||||
escapes are used only in macro buffers, and backslash-newline is removed
|
||||
from macro expansion text in collect_expansion and/or macarg. */
|
||||
char has_escapes;
|
||||
|
||||
/* 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). */
|
||||
char warned_cplusplus_comments;
|
||||
|
||||
/* In a file buffer, true if this buffer's data is mmapped
|
||||
(currently never the case). In a macro buffer, true if this
|
||||
buffer's data must be freed. */
|
||||
/* True if this buffer's data is mmapped. */
|
||||
char mapped;
|
||||
};
|
||||
|
||||
|
@ -354,7 +328,7 @@ struct cpp_options
|
|||
/* Nonzero means don't copy comments into the output file. */
|
||||
unsigned char discard_comments;
|
||||
|
||||
/* Nonzero means process the ANSI trigraph sequences. */
|
||||
/* Nonzero means process the ISO trigraph sequences. */
|
||||
unsigned char trigraphs;
|
||||
|
||||
/* Nonzero means print the names of included files rather than the
|
||||
|
@ -396,6 +370,10 @@ struct cpp_options
|
|||
with the # indented from the beginning of the line. */
|
||||
unsigned char warn_traditional;
|
||||
|
||||
/* Nonzero means warn if ## is applied to two tokens that cannot be
|
||||
pasted together. */
|
||||
unsigned char warn_paste;
|
||||
|
||||
/* Nonzero means turn warnings into errors. */
|
||||
unsigned char warnings_are_errors;
|
||||
|
||||
|
@ -417,7 +395,7 @@ struct cpp_options
|
|||
/* Zero means dollar signs are punctuation. */
|
||||
unsigned char dollars_in_ident;
|
||||
|
||||
/* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */
|
||||
/* Nonzero means try to imitate old fashioned non-ISO preprocessor. */
|
||||
unsigned char traditional;
|
||||
|
||||
/* Nonzero means warn if undefined identifiers are evaluated in an #if. */
|
||||
|
@ -460,19 +438,18 @@ struct cpp_options
|
|||
unsigned char show_column;
|
||||
};
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
||||
struct cpp_reader
|
||||
{
|
||||
/* HACK FIXME. Maybe make into cpp_printer printer later. */
|
||||
cpp_printer *printer;
|
||||
|
||||
/* Top of buffer stack. */
|
||||
cpp_buffer *buffer;
|
||||
|
||||
/* Token list used by get_directive_token. */
|
||||
cpp_toklist directbuf;
|
||||
|
||||
/* A buffer used for both for cpp_get_token's output, and also internally. */
|
||||
unsigned char *token_buffer;
|
||||
/* Allocated size of token_buffer. CPP_RESERVE allocates space. */
|
||||
|
@ -483,8 +460,9 @@ struct cpp_reader
|
|||
/* Error counter for exit code */
|
||||
unsigned int errors;
|
||||
|
||||
/* Line where a newline was first seen in a string constant. */
|
||||
/* Line and column where a newline was first seen in a string constant. */
|
||||
unsigned int multiline_string_line;
|
||||
unsigned int multiline_string_column;
|
||||
|
||||
/* Current depth in #include directives that use <...>. */
|
||||
unsigned int system_include_depth;
|
||||
|
@ -509,19 +487,46 @@ struct cpp_reader
|
|||
for include files. (Altered as we get more of them.) */
|
||||
unsigned int max_include_len;
|
||||
|
||||
/* Potential controlling macro for the current buffer. This is only
|
||||
live between the #endif and the end of file, and there can only
|
||||
be one at a time, so it is per-reader not per-buffer. */
|
||||
const cpp_hashnode *potential_control_macro;
|
||||
|
||||
/* Token column position adjustment owing to tabs in whitespace. */
|
||||
unsigned int col_adjust;
|
||||
|
||||
/* Token list used to store logical lines with new lexer. */
|
||||
cpp_toklist token_list;
|
||||
|
||||
/* Temporary token store. */
|
||||
cpp_token **temp_tokens;
|
||||
unsigned int temp_cap;
|
||||
unsigned int temp_alloced;
|
||||
unsigned int temp_used;
|
||||
|
||||
/* Date and time tokens. Calculated together if either is requested. */
|
||||
cpp_token *date;
|
||||
cpp_token *time;
|
||||
|
||||
/* The # of a the current directive. It may not be first in line if
|
||||
we append, and finding it is tedious. */
|
||||
const cpp_token *first_directive_token;
|
||||
|
||||
/* Context stack. Used for macro expansion and for determining
|
||||
which macros are disabled. */
|
||||
unsigned int context_cap;
|
||||
unsigned int cur_context;
|
||||
unsigned int no_expand_level;
|
||||
unsigned int paste_level;
|
||||
struct cpp_context *contexts;
|
||||
|
||||
/* Current arguments when scanning arguments. Used for pointer
|
||||
fix-up. */
|
||||
struct macro_args *args;
|
||||
|
||||
/* Buffer of -M output. */
|
||||
struct deps *deps;
|
||||
|
||||
/* A buffer used only by read_and_prescan (in cppfiles.c), which is
|
||||
allocated once per cpp_reader object to keep it off the stack. */
|
||||
unsigned char *input_buffer;
|
||||
size_t input_buffer_len;
|
||||
|
||||
/* User visible options. */
|
||||
struct cpp_options opts;
|
||||
|
||||
|
@ -532,31 +537,24 @@ struct cpp_reader
|
|||
/* If non-zero, macros are not expanded. */
|
||||
unsigned char no_macro_expand;
|
||||
|
||||
/* If non-zero, directives cause a hard error. Used when parsing
|
||||
macro arguments. */
|
||||
unsigned char no_directives;
|
||||
|
||||
/* We're printed a warning recommending against using #import. */
|
||||
unsigned char import_warning;
|
||||
|
||||
/* If true, characters between '<' and '>' are a single (string) token. */
|
||||
unsigned char parsing_include_directive;
|
||||
|
||||
/* True if escape sequences (as described for has_escapes in
|
||||
parse_buffer) should be emitted. */
|
||||
unsigned char output_escapes;
|
||||
|
||||
/* 0: Have seen non-white-space on this line.
|
||||
1: Only seen white space so far on this line.
|
||||
2: Only seen white space so far in this file. */
|
||||
unsigned char only_seen_white;
|
||||
|
||||
/* True after cpp_start_read completes. Used to inhibit some
|
||||
warnings while parsing the command line. */
|
||||
unsigned char done_initializing;
|
||||
|
||||
/* True if we are skipping a failed conditional group. */
|
||||
unsigned char skipping;
|
||||
|
||||
/* Do we need to save paramter spellings. */
|
||||
unsigned char save_parameter_spellings;
|
||||
|
||||
/* If we're in lex_line. */
|
||||
unsigned char in_lex_line;
|
||||
|
||||
/* True if output_line_command needs to output a newline. */
|
||||
unsigned char need_newline;
|
||||
};
|
||||
|
||||
/* struct cpp_printer encapsulates state used to convert the stream of
|
||||
|
@ -611,13 +609,8 @@ enum node_type
|
|||
T_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */
|
||||
T_TIME, /* `__TIME__' */
|
||||
T_STDC, /* `__STDC__' */
|
||||
T_CONST, /* Constant string, used by `__SIZE_TYPE__' etc */
|
||||
T_XCONST, /* Ditto, but the string is malloced memory */
|
||||
T_POISON, /* poisoned identifier */
|
||||
T_MACRO, /* object-like macro */
|
||||
T_FMACRO, /* function-like macro */
|
||||
T_IDENTITY, /* macro defined to itself */
|
||||
T_EMPTY, /* macro defined to nothing */
|
||||
T_MACRO, /* a macro, either object-like or function-like */
|
||||
T_ASSERTION /* predicate for #assert */
|
||||
};
|
||||
|
||||
|
@ -634,11 +627,10 @@ struct cpp_hashnode
|
|||
ENUM_BITFIELD(node_type) type : 8; /* node type */
|
||||
char disabled; /* macro turned off for rescan? */
|
||||
|
||||
union {
|
||||
const unsigned char *cpval; /* some predefined macros */
|
||||
const struct object_defn *odefn; /* #define foo bar */
|
||||
const struct funct_defn *fdefn; /* #define foo(x) bar(x) */
|
||||
struct predicate *pred; /* #assert */
|
||||
union
|
||||
{
|
||||
const cpp_toklist *expansion; /* a macro's replacement list. */
|
||||
struct answer *answers; /* answers to an assertion. */
|
||||
} value;
|
||||
|
||||
union tree_node *fe_value; /* front end value */
|
||||
|
@ -646,23 +638,17 @@ struct cpp_hashnode
|
|||
const unsigned char name[1]; /* name[length] */
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern void _cpp_lex_file PARAMS((cpp_reader *));
|
||||
extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
|
||||
extern enum cpp_ttype cpp_get_token PARAMS ((cpp_reader *));
|
||||
extern enum cpp_ttype cpp_get_non_space_token PARAMS ((cpp_reader *));
|
||||
|
||||
extern void cpp_reader_init PARAMS ((cpp_reader *));
|
||||
extern cpp_printer *cpp_printer_init PARAMS ((cpp_reader *, cpp_printer *));
|
||||
extern int cpp_start_read PARAMS ((cpp_reader *, cpp_printer *, const char *));
|
||||
extern void cpp_output_tokens PARAMS ((cpp_reader *, cpp_printer *));
|
||||
extern void cpp_output_list PARAMS ((cpp_reader *, cpp_printer *,
|
||||
const cpp_toklist *));
|
||||
extern void cpp_output_tokens PARAMS ((cpp_reader *, cpp_printer *,
|
||||
unsigned int));
|
||||
extern void cpp_finish PARAMS ((cpp_reader *, cpp_printer *));
|
||||
extern void cpp_cleanup PARAMS ((cpp_reader *));
|
||||
|
||||
extern cpp_buffer *cpp_file_buffer PARAMS((cpp_reader *));
|
||||
extern const cpp_token *cpp_get_token PARAMS ((cpp_reader *));
|
||||
|
||||
extern void cpp_define PARAMS ((cpp_reader *, const char *));
|
||||
extern void cpp_assert PARAMS ((cpp_reader *, const char *));
|
||||
extern void cpp_undef PARAMS ((cpp_reader *, const char *));
|
||||
|
|
|
@ -68,6 +68,7 @@ main (argc, argv)
|
|||
print = cpp_printer_init (pfile, &parse_out);
|
||||
if (! print)
|
||||
return (FATAL_EXIT_CODE);
|
||||
pfile->printer = print;
|
||||
|
||||
if (! cpp_start_read (pfile, print, CPP_OPTION (pfile, in_fname)))
|
||||
return (FATAL_EXIT_CODE);
|
||||
|
|
|
@ -432,8 +432,6 @@ write_lbrac ()
|
|||
struct partial_proto
|
||||
{
|
||||
struct partial_proto *next;
|
||||
char *fname; /* name of function */
|
||||
char *rtype; /* return type */
|
||||
struct fn_decl *fn;
|
||||
int line_seen;
|
||||
};
|
||||
|
@ -497,15 +495,13 @@ recognized_macro (fname)
|
|||
}
|
||||
|
||||
void
|
||||
recognized_extern (name, name_length, type, type_length)
|
||||
const char *name;
|
||||
const char *type ATTRIBUTE_UNUSED;
|
||||
int name_length, type_length ATTRIBUTE_UNUSED;
|
||||
recognized_extern (name)
|
||||
const cpp_token *name;
|
||||
{
|
||||
switch (special_file_handling)
|
||||
{
|
||||
case errno_h:
|
||||
if (name_length == 5 && strncmp (name, "errno", 5) == 0 && !seen_errno)
|
||||
if (!cpp_idcmp (name->val.name.text, name->val.name.len, "errno"))
|
||||
seen_errno = 1, required_other--;
|
||||
break;
|
||||
|
||||
|
@ -515,25 +511,17 @@ recognized_extern (name, name_length, type, type_length)
|
|||
}
|
||||
|
||||
/* Called by scan_decls if it saw a function definition for a function
|
||||
named FNAME, with return type RTYPE, and argument list ARGS,
|
||||
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
|
||||
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. */
|
||||
|
||||
void
|
||||
recognized_function (fname, fname_length,
|
||||
kind, rtype, rtype_length,
|
||||
have_arg_list, file_seen, line_seen)
|
||||
const char *fname;
|
||||
int fname_length;
|
||||
recognized_function (fname, kind, have_arg_list, file_seen)
|
||||
const cpp_token *fname;
|
||||
int kind; /* One of 'f' 'F' or 'I' */
|
||||
const char *rtype;
|
||||
int rtype_length;
|
||||
int have_arg_list;
|
||||
const char *file_seen;
|
||||
int line_seen;
|
||||
{
|
||||
struct partial_proto *partial;
|
||||
int i;
|
||||
|
@ -543,7 +531,8 @@ recognized_function (fname, fname_length,
|
|||
missing_extern_C_count++;
|
||||
#endif
|
||||
|
||||
fn = lookup_std_proto (fname, fname_length);
|
||||
fn = lookup_std_proto ((const char *)fname->val.name.text,
|
||||
fname->val.name.len);
|
||||
|
||||
/* Remove the function from the list of required function. */
|
||||
if (fn)
|
||||
|
@ -577,12 +566,7 @@ recognized_function (fname, fname_length,
|
|||
partial_count++;
|
||||
partial = (struct partial_proto *)
|
||||
obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
|
||||
partial->fname = obstack_alloc (&scan_file_obstack, fname_length + 1);
|
||||
bcopy (fname, partial->fname, fname_length);
|
||||
partial->fname[fname_length] = 0;
|
||||
partial->rtype = obstack_alloc (&scan_file_obstack, rtype_length + 1);
|
||||
sprintf (partial->rtype, "%.*s", rtype_length, rtype);
|
||||
partial->line_seen = line_seen;
|
||||
partial->line_seen = fname->line;
|
||||
partial->fn = fn;
|
||||
fn->partial = partial;
|
||||
partial->next = partial_proto_list;
|
||||
|
@ -590,7 +574,7 @@ recognized_function (fname, fname_length,
|
|||
if (verbose)
|
||||
{
|
||||
fprintf (stderr, "(%s: %s non-prototype function declaration.)\n",
|
||||
inc_filename, partial->fname);
|
||||
inc_filename, fn->fname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,19 +630,12 @@ read_scan_file (in_fname, argc, argv)
|
|||
for (cur_symbols = &symbol_table[0]; cur_symbols->names; cur_symbols++)
|
||||
check_macro_names (&scan_in, cur_symbols->names);
|
||||
|
||||
if (verbose && (scan_in.errors + warnings) > 0)
|
||||
fprintf (stderr, "(%s: %d errors and %d warnings from cpp)\n",
|
||||
inc_filename, scan_in.errors, warnings);
|
||||
if (scan_in.errors)
|
||||
exit (SUCCESS_EXIT_CODE);
|
||||
|
||||
/* Traditionally, getc and putc are defined in terms of _filbuf and _flsbuf.
|
||||
If so, those functions are also required. */
|
||||
if (special_file_handling == stdio_h
|
||||
&& (fn = lookup_std_proto ("_filbuf", 7)) != NULL)
|
||||
{
|
||||
static const unsigned char getchar_call[] = "getchar();";
|
||||
int old_written = CPP_WRITTEN (&scan_in);
|
||||
int seen_filbuf = 0;
|
||||
cpp_buffer *buf = CPP_BUFFER (&scan_in);
|
||||
if (cpp_push_buffer (&scan_in, getchar_call,
|
||||
|
@ -668,14 +645,17 @@ read_scan_file (in_fname, argc, argv)
|
|||
/* Scan the macro expansion of "getchar();". */
|
||||
for (;;)
|
||||
{
|
||||
enum cpp_ttype token = cpp_get_token (&scan_in);
|
||||
int length = CPP_WRITTEN (&scan_in) - old_written;
|
||||
unsigned char *id = scan_in.token_buffer + old_written;
|
||||
|
||||
CPP_SET_WRITTEN (&scan_in, old_written);
|
||||
if (token == CPP_EOF && CPP_BUFFER (&scan_in) == buf)
|
||||
break;
|
||||
if (token == CPP_NAME && cpp_idcmp (id, length, "_filbuf") == 0)
|
||||
const cpp_token *t = cpp_get_token (&scan_in);
|
||||
|
||||
if (t->type == CPP_EOF)
|
||||
{
|
||||
cpp_pop_buffer (&scan_in);
|
||||
if (CPP_BUFFER (&scan_in) == buf)
|
||||
break;
|
||||
}
|
||||
else if (t->type == CPP_NAME && cpp_idcmp (t->val.name.text,
|
||||
t->val.name.len,
|
||||
"_filbuf") == 0)
|
||||
seen_filbuf++;
|
||||
}
|
||||
if (seen_filbuf)
|
||||
|
@ -1030,8 +1010,6 @@ check_protection (ifndef_line, endif_line)
|
|||
}
|
||||
else if (!strcmp (buf.base, "define"))
|
||||
{
|
||||
if (if_nesting != 1)
|
||||
goto skip_to_eol;
|
||||
c = inf_skip_spaces (c);
|
||||
c = inf_scan_ident (&buf, c);
|
||||
if (buf.base[0] > 0 && strcmp (buf.base, protect_name) == 0)
|
||||
|
|
159
gcc/scan-decls.c
159
gcc/scan-decls.c
|
@ -45,7 +45,7 @@ skip_to_closing_brace (pfile)
|
|||
int nesting = 1;
|
||||
for (;;)
|
||||
{
|
||||
enum cpp_ttype token = cpp_get_token (pfile);
|
||||
enum cpp_ttype token = cpp_get_token (pfile)->type;
|
||||
if (token == CPP_EOF)
|
||||
break;
|
||||
if (token == CPP_OPEN_BRACE)
|
||||
|
@ -84,24 +84,17 @@ scan_decls (pfile, argc, argv)
|
|||
char **argv ATTRIBUTE_UNUSED;
|
||||
{
|
||||
int saw_extern, saw_inline;
|
||||
int start_written;
|
||||
/* If declarator_start is non-zero, it marks the start of the current
|
||||
declarator. If it is zero, we are either still parsing the
|
||||
decl-specs, or prev_id_start marks the start of the declarator. */
|
||||
int declarator_start;
|
||||
int prev_id_start, prev_id_end = 0;
|
||||
enum cpp_ttype token;
|
||||
const cpp_token *prev_id;
|
||||
const cpp_token *token;
|
||||
|
||||
new_statement:
|
||||
CPP_SET_WRITTEN (pfile, 0);
|
||||
start_written = 0;
|
||||
token = cpp_get_token (pfile);
|
||||
|
||||
handle_statement:
|
||||
current_extern_C = 0;
|
||||
saw_extern = 0;
|
||||
saw_inline = 0;
|
||||
if (token == CPP_OPEN_BRACE)
|
||||
if (token->type == CPP_OPEN_BRACE)
|
||||
{
|
||||
/* Pop an 'extern "C"' nesting level, if appropriate. */
|
||||
if (extern_C_braces_length
|
||||
|
@ -110,120 +103,112 @@ scan_decls (pfile, argc, argv)
|
|||
brace_nesting--;
|
||||
goto new_statement;
|
||||
}
|
||||
if (token == CPP_OPEN_BRACE)
|
||||
if (token->type == CPP_OPEN_BRACE)
|
||||
{
|
||||
brace_nesting++;
|
||||
goto new_statement;
|
||||
}
|
||||
if (token == CPP_EOF)
|
||||
if (token->type == CPP_EOF)
|
||||
{
|
||||
cpp_pop_buffer (pfile);
|
||||
if (CPP_BUFFER (pfile) == NULL)
|
||||
return 0;
|
||||
else
|
||||
goto new_statement;
|
||||
|
||||
goto new_statement;
|
||||
}
|
||||
if (token == CPP_SEMICOLON)
|
||||
if (token->type == CPP_SEMICOLON)
|
||||
goto new_statement;
|
||||
if (token != CPP_NAME)
|
||||
if (token->type != CPP_NAME)
|
||||
goto new_statement;
|
||||
|
||||
prev_id_start = 0;
|
||||
declarator_start = 0;
|
||||
prev_id = 0;
|
||||
for (;;)
|
||||
{
|
||||
switch (token)
|
||||
switch (token->type)
|
||||
{
|
||||
default:
|
||||
goto handle_statement;
|
||||
case CPP_MULT:
|
||||
case CPP_AND:
|
||||
case CPP_PLACEMARKER:
|
||||
/* skip */
|
||||
break;
|
||||
|
||||
case CPP_COMMA:
|
||||
case CPP_SEMICOLON:
|
||||
if (prev_id && saw_extern)
|
||||
{
|
||||
recognized_extern (prev_id);
|
||||
}
|
||||
if (token->type == CPP_COMMA)
|
||||
break;
|
||||
/* ... fall through ... */
|
||||
case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE:
|
||||
goto new_statement;
|
||||
|
||||
case CPP_EOF:
|
||||
cpp_pop_buffer (pfile);
|
||||
if (CPP_BUFFER (pfile) == NULL)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case CPP_OPEN_PAREN:
|
||||
/* Looks like this is the start of a formal parameter list. */
|
||||
if (prev_id_start)
|
||||
if (prev_id)
|
||||
{
|
||||
int nesting = 1;
|
||||
int have_arg_list = 0;
|
||||
cpp_buffer *fbuf = cpp_file_buffer (pfile);
|
||||
unsigned int func_lineno = CPP_BUF_LINE (fbuf);
|
||||
for (;;)
|
||||
{
|
||||
token = cpp_get_token (pfile);
|
||||
if (token == CPP_OPEN_PAREN)
|
||||
if (token->type == CPP_OPEN_PAREN)
|
||||
nesting++;
|
||||
else if (token == CPP_CLOSE_PAREN)
|
||||
else if (token->type == CPP_CLOSE_PAREN)
|
||||
{
|
||||
nesting--;
|
||||
if (nesting == 0)
|
||||
break;
|
||||
}
|
||||
else if (token == CPP_EOF)
|
||||
else if (token->type == CPP_EOF)
|
||||
break;
|
||||
else if (token == CPP_NAME || token == CPP_ELLIPSIS)
|
||||
else if (token->type == CPP_NAME
|
||||
|| token->type == CPP_ELLIPSIS)
|
||||
have_arg_list = 1;
|
||||
}
|
||||
recognized_function (pfile->token_buffer + prev_id_start,
|
||||
prev_id_end - prev_id_start,
|
||||
recognized_function (prev_id,
|
||||
(saw_inline ? 'I'
|
||||
: in_extern_C_brace || current_extern_C
|
||||
? 'F' : 'f'),
|
||||
pfile->token_buffer, prev_id_start,
|
||||
have_arg_list,
|
||||
fbuf->nominal_fname, func_lineno);
|
||||
token = cpp_get_non_space_token (pfile);
|
||||
if (token == CPP_OPEN_BRACE)
|
||||
? 'F' : 'f'), have_arg_list,
|
||||
CPP_BUFFER (pfile)->nominal_fname);
|
||||
token = cpp_get_token (pfile);
|
||||
if (token->type == CPP_OPEN_BRACE)
|
||||
{
|
||||
/* skip body of (normally) inline function */
|
||||
skip_to_closing_brace (pfile);
|
||||
goto new_statement;
|
||||
}
|
||||
goto maybe_handle_comma;
|
||||
if (token->type == CPP_SEMICOLON)
|
||||
goto new_statement;
|
||||
}
|
||||
break;
|
||||
case CPP_OTHER:
|
||||
if (CPP_WRITTEN (pfile) == (size_t) start_written + 1
|
||||
&& (CPP_PWRITTEN (pfile)[-1] == '*'
|
||||
|| CPP_PWRITTEN (pfile)[-1] == '&'))
|
||||
declarator_start = start_written;
|
||||
else
|
||||
goto handle_statement;
|
||||
break;
|
||||
case CPP_COMMA:
|
||||
case CPP_SEMICOLON:
|
||||
if (prev_id_start && saw_extern)
|
||||
{
|
||||
recognized_extern (pfile->token_buffer + prev_id_start,
|
||||
prev_id_end - prev_id_start,
|
||||
pfile->token_buffer,
|
||||
prev_id_start);
|
||||
}
|
||||
/* ... fall through ... */
|
||||
maybe_handle_comma:
|
||||
if (token != CPP_COMMA)
|
||||
goto new_statement;
|
||||
|
||||
/* Handle multiple declarators in a single declaration,
|
||||
as in: extern char *strcpy (), *strcat (), ... ; */
|
||||
if (declarator_start == 0)
|
||||
declarator_start = prev_id_start;
|
||||
CPP_SET_WRITTEN (pfile, declarator_start);
|
||||
break;
|
||||
case CPP_NAME:
|
||||
/* "inline" and "extern" are recognized but skipped */
|
||||
if (!cpp_idcmp (pfile->token_buffer,
|
||||
CPP_WRITTEN (pfile), "inline"))
|
||||
if (!cpp_idcmp (token->val.name.text, token->val.name.len, "inline"))
|
||||
{
|
||||
saw_inline = 1;
|
||||
CPP_SET_WRITTEN (pfile, start_written);
|
||||
}
|
||||
else if (!cpp_idcmp (pfile->token_buffer,
|
||||
CPP_WRITTEN (pfile), "extern"))
|
||||
else if (!cpp_idcmp (token->val.name.text,
|
||||
token->val.name.len, "extern"))
|
||||
{
|
||||
saw_extern = 1;
|
||||
CPP_SET_WRITTEN (pfile, start_written);
|
||||
token = cpp_get_non_space_token (pfile);
|
||||
if (token == CPP_STRING
|
||||
&& strcmp (pfile->token_buffer, "\"C\"") == 0)
|
||||
token = cpp_get_token (pfile);
|
||||
if (token->type == CPP_STRING
|
||||
&& !cpp_idcmp (token->val.name.text,
|
||||
token->val.name.len, "C"))
|
||||
{
|
||||
CPP_SET_WRITTEN (pfile, start_written);
|
||||
current_extern_C = 1;
|
||||
token = cpp_get_non_space_token (pfile);
|
||||
if (token == CPP_OPEN_BRACE)
|
||||
token = cpp_get_token (pfile);
|
||||
if (token->type == CPP_OPEN_BRACE)
|
||||
{
|
||||
brace_nesting++;
|
||||
extern_C_braces[extern_C_braces_length++]
|
||||
|
@ -236,29 +221,9 @@ scan_decls (pfile, argc, argv)
|
|||
break;
|
||||
}
|
||||
/* This may be the name of a variable or function. */
|
||||
prev_id_start = start_written;
|
||||
prev_id_end = CPP_WRITTEN (pfile);
|
||||
prev_id = token;
|
||||
break;
|
||||
|
||||
case CPP_OPEN_BRACE: case CPP_CLOSE_BRACE: case CPP_DIRECTIVE:
|
||||
goto new_statement; /* handle_statement? */
|
||||
|
||||
case CPP_EOF:
|
||||
if (CPP_BUFFER (pfile) == NULL)
|
||||
return 0;
|
||||
/* else fall through */
|
||||
|
||||
case CPP_HSPACE: case CPP_VSPACE: case CPP_COMMENT:
|
||||
/* Skip initial white space. */
|
||||
if (start_written == 0)
|
||||
CPP_SET_WRITTEN (pfile, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
prev_id_start = 0;
|
||||
}
|
||||
|
||||
start_written = CPP_WRITTEN (pfile);
|
||||
token = cpp_get_token (pfile);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ struct fn_decl
|
|||
struct partial_proto *partial;
|
||||
};
|
||||
|
||||
struct cpp_token;
|
||||
|
||||
extern int lineno;
|
||||
extern void sstring_append _PARAMS((sstring *, sstring *));
|
||||
extern void make_sstring_space _PARAMS((sstring *, int));
|
||||
|
@ -58,8 +60,9 @@ extern int scan_ident _PARAMS((FILE *, sstring *, int));
|
|||
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 char *, int, int, const char *, int, int, const char *, int));
|
||||
extern void recognized_extern _PARAMS((const char *, int, const char *, int));
|
||||
extern void recognized_function _PARAMS((const struct cpp_token *, int, int,
|
||||
const char *));
|
||||
extern void recognized_extern _PARAMS((const struct cpp_token *));
|
||||
extern unsigned int hashstr _PARAMS((const char *, unsigned int));
|
||||
|
||||
struct cpp_reader;
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
2000-07-03 Zack Weinberg <zack@wolery.cumb.org>
|
||||
|
||||
* testsuite/gcc.dg/cpp/19951025-1.c: Adjust regexps.
|
||||
* testsuite/gcc.dg/cpp/19990703-1.c: Likewise.
|
||||
* testsuite/gcc.dg/cpp/20000625-1.c: Likewise.
|
||||
* testsuite/gcc.dg/cpp/20000625-2.c: Likewise.
|
||||
|
||||
* testsuite/gcc.dg/cpp/macro1.c,
|
||||
testsuite/gcc.dg/cpp/paste1.c, testsuite/gcc.dg/cpp/paste2.c,
|
||||
testsuite/gcc.dg/cpp/paste3.c, testsuite/gcc.dg/cpp/paste4.c,
|
||||
testsuite/gcc.dg/cpp/strify1.c,
|
||||
testsuite/gcc.dg/cpp/strify2.c: New tests.
|
||||
|
||||
2000-07-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gcc.c-torture/execute/20000703-1.c: New test.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* { dg-do preprocess } */
|
||||
/* { dg-error "include expects" "" { target *-*-* } 4 } */
|
||||
/* { dg-warning "no newline" "" { target *-*-* } 5 } */
|
||||
/* { dg-error "newline at end" "" { target *-*-* } 4 } */
|
||||
#include /\
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
int
|
||||
main(void)
|
||||
{
|
||||
char *x = SP1(0,MZ);
|
||||
char *x = SP1(0,MZ); /* { dg-warning "valid preprocessing token" "" } */
|
||||
char *y = "0-0"; /* should be the expansion of SP1(0,MZ) */
|
||||
|
||||
if(strcmp(x, y))
|
||||
|
|
|
@ -11,6 +11,6 @@ main(void)
|
|||
{
|
||||
goto socket;
|
||||
|
||||
ENTRY(socket)
|
||||
ENTRY(socket) /* { dg-warning "valid preprocessing token" "" } */
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define xstr(x) #x
|
||||
|
||||
const char a[] = str(symbol_version(getrlimit, GLIBC_2.0));
|
||||
/* { dg-warning "valid preprocessing token" "" { target *-*-* } 9 } */
|
||||
const char b[] = str(getrlimit@GLIBC_2.0);
|
||||
const char c[] = "getrlimit@GLIBC_2.0";
|
||||
|
||||
|
|
72
gcc/testsuite/gcc.dg/cpp/macro1.c
Normal file
72
gcc/testsuite/gcc.dg/cpp/macro1.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do run } */
|
||||
|
||||
/* Tests various macros are correctly expanded. */
|
||||
|
||||
extern int puts (const char *);
|
||||
extern void abort (void);
|
||||
#define err(str) do { puts(str); abort(); } while (0)
|
||||
|
||||
#define j(x, y) x + y
|
||||
#define k(x, y) j(x + 2, y +
|
||||
|
||||
int q(int x) {return x + 40;}
|
||||
int B(int x) {return x + 20;}
|
||||
int foo(int x) {return x + 10;}
|
||||
int bar(int x, int y) {return x + y;}
|
||||
int baz(int x, int y) {return x + y;}
|
||||
int toupper(int x) {return x + 32;}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
#define q(x) x
|
||||
if (q(q)(2) != 42)
|
||||
err ("q");
|
||||
|
||||
#define A(x) B(x)
|
||||
if (A(A(2)) != 42)
|
||||
err ("A");
|
||||
|
||||
#define E(x) A x
|
||||
#define F (22)
|
||||
if (E(F) != 42)
|
||||
err ("E(F)");
|
||||
|
||||
#define COMMA ,
|
||||
#define NASTY(a) j(a 37)
|
||||
if (NASTY (5 COMMA) != 42)
|
||||
err ("NASTY");
|
||||
|
||||
#define bar(x, y) foo(x(y, 0))
|
||||
#define apply(x, y) foo(x(y, 22))
|
||||
#define bam bar
|
||||
if (bar(bar, 32) != 42) /* foo(bar(32, 0)). */
|
||||
err ("bar bar");
|
||||
if (bar(bam, 32) != 42) /* Same. */
|
||||
err ("bar bam");
|
||||
if (apply(bar, baz) != 42) /* foo(foo(baz(22, 0))). */
|
||||
err ("apply bar baz");
|
||||
|
||||
#define __tobody(c, f) f (c)
|
||||
#define toupper(c) __tobody (c, toupper)
|
||||
if (toupper (10) != 42) /* toupper (10). */
|
||||
err ("toupper");
|
||||
|
||||
/* This looks like it has too many ')', but it hasn't. */
|
||||
if (k(1, 4) 35) != 42)
|
||||
err ("k");
|
||||
|
||||
/*#define B(x) Z B(x)
|
||||
#define XEXP(RTX, N) RTX->fld[N].rtx
|
||||
#define PATTERN(INSN) XEXP(INSN, 3)
|
||||
#define COST(X) XEXP (XEXP (x, 0), 0)
|
||||
#define M(a) OK M (a)
|
||||
#define stpcpy(a) M(a)
|
||||
#define C(x) A(x)
|
||||
XEXP (PATTERN (insn), i);
|
||||
XEXP (XEXP (insn, 3), i);
|
||||
COST (b)*/
|
||||
|
||||
return 0;
|
||||
}
|
10
gcc/testsuite/gcc.dg/cpp/paste1.c
Normal file
10
gcc/testsuite/gcc.dg/cpp/paste1.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do preprocess } */
|
||||
|
||||
/* Test operator ## semantics. */
|
||||
|
||||
#define bad1 ## owt /* { dg-error "cannot" "## at objlike start" } */
|
||||
#define bad2 owt ## /* { dg-error "cannot" "## at objlike end" } */
|
||||
#define bad3(x) ## x /* { dg-error "cannot" "## at funlike start" } */
|
||||
#define bad4(x) x ## /* { dg-error "cannot" "## at funlike end" } */
|
115
gcc/testsuite/gcc.dg/cpp/paste2.c
Normal file
115
gcc/testsuite/gcc.dg/cpp/paste2.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c99 -pedantic-errors" } */
|
||||
|
||||
/* Test ## behaviour and corner cases thoroughly. The macro expander
|
||||
failed many of these during development. */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __WCHAR_TYPE__
|
||||
#define __WCHAR_TYPE__ int
|
||||
#endif
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
|
||||
extern int puts (const char *);
|
||||
extern void abort (void);
|
||||
#define err(str) do { puts(str); abort(); } while (0)
|
||||
|
||||
#define EMPTY
|
||||
#define str(x) #x
|
||||
#define xstr(x) str(x)
|
||||
#define glue(x, y) x ## y
|
||||
#define xglue(x, y) glue (x, y)
|
||||
#define glue3(x, y, z) x ## y ## z
|
||||
#define glue_var(x, ...) x ## __VA_ARGS__
|
||||
|
||||
#define __muldi3 __NDW(mul, 3 = 50)
|
||||
#define __NDW(a,b) __ ## a ## di ## b
|
||||
#define m3 NDW()
|
||||
#define NDW(x) m3 ## x = 50
|
||||
#define five 5
|
||||
#define fifty int fif ## ty
|
||||
|
||||
/* Defines a function called glue, returning what it is passed. */
|
||||
int glue (glue,) (int x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
/* m3 and __muldi3 would sometimes cause an infinite loop. Ensure
|
||||
we only expand fifty once. */
|
||||
fifty = 50, m3, __muldi3;
|
||||
|
||||
/* General glue and macro expanding test. */
|
||||
int five0 = xglue (glue (fi, ve), 0);
|
||||
|
||||
/* Tests only first and last tokens are pasted, and pasting to form
|
||||
the != operator. Should expand to: if (five0 != 50). */
|
||||
if (glue3 (fi, ve0 !,= glue (EMPTY 5, 0)))
|
||||
err ("five0 != 50");
|
||||
|
||||
/* Test varags pasting, and pasting to form the >> operator. */
|
||||
if (glue_var(50 >, > 1 != 25))
|
||||
err ("Operator >> pasting");
|
||||
|
||||
/* The LHS should not attempt to expand twice, and thus becomes a
|
||||
call to the function glue, but the RHS should fully expand. */
|
||||
if (glue (gl, ue) (12) != glue (xgl, ue) (1, 2))
|
||||
err ("Recursive macros");
|
||||
|
||||
/* Test placemarker pasting. The glued lines should all appear
|
||||
neatly in the same column and below each other, though we don't
|
||||
test that here. */
|
||||
{
|
||||
int glue3(a, b, ) = 1, glue3(a,,) = 1;
|
||||
glue3(a, , b)++;
|
||||
glue3(, a, b)++;
|
||||
glue3(,a,)++;
|
||||
glue3(,,a)++;
|
||||
if (a != 3 || ab != 3 glue3(,,))
|
||||
err ("Placemarker pasting");
|
||||
}
|
||||
|
||||
/* Test that macros in arguments are not expanded. */
|
||||
{
|
||||
int glue (EMPTY,1) = 123, glue (T, EMPTY) = 123;
|
||||
if (EMPTY1 != 123 || TEMPTY != 123)
|
||||
err ("Pasted arguments macro expanding");
|
||||
}
|
||||
|
||||
/* Test various paste combinations. */
|
||||
{
|
||||
const wchar_t* wc_array = glue(L, "wide string");
|
||||
wchar_t wc = glue(L, 'w');
|
||||
const char * hh = xstr(xglue(glue(%, :), glue(%, :)));
|
||||
int array glue (<, :) 1 glue (:, >) = glue(<, %) 1 glue(%, >);
|
||||
int x = 4;
|
||||
|
||||
if (array[0] != 1)
|
||||
err ("Digraph pasting");
|
||||
|
||||
x glue (>>, =) 1; /* 2 */
|
||||
x glue (<<, =) 1; /* 4 */
|
||||
x glue (*, =) 2; /* 8 */
|
||||
x glue (+, =) 100; /* 108 */
|
||||
x glue (-, =) 50; /* 58 */
|
||||
x glue (/, =) 2; /* 29 */
|
||||
x glue (%, =) 20; /* 9 */
|
||||
x glue (&, =) 254; /* 8 */
|
||||
x glue (|, =) 16; /* 24 */
|
||||
x glue (^, =) 18; /* 10 */
|
||||
|
||||
if (x != 10 || 0 glue (>, =) 1 glue (|, |) 1 glue (<, =) 0)
|
||||
err ("Various operator pasting");
|
||||
if (strcmp (hh, "%:%:"))
|
||||
err ("Pasted digraph spelling");
|
||||
if ((glue (., 0) glue (=, =) .0) + (glue3 (1.0e, +, 1) == 10.0) != 2)
|
||||
err ("Pasted numbers");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
14
gcc/testsuite/gcc.dg/cpp/paste3.c
Normal file
14
gcc/testsuite/gcc.dg/cpp/paste3.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
|
||||
#define plus +
|
||||
|
||||
void foo()
|
||||
{
|
||||
int a, b = 1;
|
||||
|
||||
/* The correct "a = 1 + ++b" will compile.
|
||||
The incorrect "a = 1 +++b" won't. */
|
||||
a = 1 plus++b;
|
||||
}
|
14
gcc/testsuite/gcc.dg/cpp/paste4.c
Normal file
14
gcc/testsuite/gcc.dg/cpp/paste4.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
/* { dg-do compile } */
|
||||
|
||||
/* Since 1.0e and + form the pasted token, 1 is a separate token and
|
||||
so should be output with a preceding space. The old preprocessor
|
||||
gets this wrong. */
|
||||
|
||||
#define glue(x, y) x ## y
|
||||
|
||||
int main ()
|
||||
{
|
||||
double d = glue (1.0e, +1); /* { dg-error "floating const|parse error" } */
|
||||
return 0;
|
||||
}
|
10
gcc/testsuite/gcc.dg/cpp/strify1.c
Normal file
10
gcc/testsuite/gcc.dg/cpp/strify1.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do preprocess } */
|
||||
|
||||
/* Test operator # semantics. */
|
||||
|
||||
#define OK1 # /* No problem. */
|
||||
#define OK2(x) x#x /* No problem. */
|
||||
#define bad1(x) # /* { dg-error "followed by a macro parameter" "#1" } */
|
||||
#define bad2(x) #y /* { dg-error "followed by a macro parameter" "#2" } */
|
45
gcc/testsuite/gcc.dg/cpp/strify2.c
Normal file
45
gcc/testsuite/gcc.dg/cpp/strify2.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* Copyright (C) 2000 Free Software Foundation, Inc. */
|
||||
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-std=c99 -pedantic-errors" } */
|
||||
|
||||
/* Tests a whole bunch of things are correctly stringified. */
|
||||
|
||||
extern int strcmp (const char *, const char *);
|
||||
extern int puts (const char *);
|
||||
extern void abort (void);
|
||||
#define err(str) do { puts(str); abort(); } while (0)
|
||||
|
||||
#define str(x) #x
|
||||
#define xstr(x) str(x)
|
||||
#define strvar(...) #__VA_ARGS__
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
str (\); /* { dg-warning "valid string" "str(\)" } */
|
||||
str (\\\); /* { dg-warning "valid string" "str(\\\)" } */
|
||||
|
||||
/* This also serves as a useful test of the value of __INCLUDE_LEVEL. */
|
||||
if (strcmp (xstr (__INCLUDE_LEVEL__), "0"))
|
||||
err ("macro expansion");
|
||||
|
||||
if (strcmp(str (__INCLUDE_LEVEL__), "__INCLUDE_LEVEL__"))
|
||||
err ("macro name");
|
||||
|
||||
if (strcmp(str ("s\n"), "\"s\\n\""))
|
||||
err ("quoted string");
|
||||
|
||||
if (strcmp (str (a € b), "a \200 b"))
|
||||
err ("unprintable char");
|
||||
|
||||
if (strcmp (str ( a b@ c ), "a b@ c"))
|
||||
err ("internal whitespace");
|
||||
|
||||
if (strcmp (str(a \n), "a \n"))
|
||||
err ("backslash token");
|
||||
|
||||
if (strcmp (strvar (foo, bar), "foo, bar"))
|
||||
err ("variable arguments");
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue