diff options
author | Neil Booth <neil@daikokuya.demon.co.uk> | 2002-06-05 20:27:12 +0000 |
---|---|---|
committer | Neil Booth <neil@gcc.gnu.org> | 2002-06-05 20:27:12 +0000 |
commit | cbc69f844ef9dcec70f15d45467026c5fd937db2 (patch) | |
tree | b098c6dcb911ae0a74ccb0f807fc5136f1aaecd4 /gcc/cppmacro.c | |
parent | dbf87f32ae756cd4efd33b05003929206169bda3 (diff) | |
download | gcc-cbc69f844ef9dcec70f15d45467026c5fd937db2.zip gcc-cbc69f844ef9dcec70f15d45467026c5fd937db2.tar.gz gcc-cbc69f844ef9dcec70f15d45467026c5fd937db2.tar.bz2 |
cpphash.h (_cpp_create_definition): Update prototype.
* cpphash.h (_cpp_create_definition): Update prototype.
(_cpp_push_text_context, _cpp_create_trad_definition): New.
( cpp_lex_identifier_trad): New.
(_cpp_set_trad_context): New.
* cppinit.c (cpp_finish_options): Don't conditionalize builtins.
* cpplib.c (SEEN_EOL): Update.
(lex_macro_node): Update for -traditional.
(cpp_push_buffer, _cpp_pop_buffer): Similarly.
* cppmacro.c (_cpp_create_definition): Split into
create_iso_definition() and _cpp_create_trad_definition().
(warn_of_redefinition): Update prototype; handle traditional
macros.
(_cpp_push_text_context): New.
* cpptrad.c (skip_whitespace, push_replacement_text): New.
(lex_identifier): Call ht_lookup with correct start.
(_cpp_lex_identifier_tradm _cpp_create_trad_definition,
_cpp_set_trad_context): New.
(scan_out_logical_line): Update to handle changing contexts.
From-SVN: r54293
Diffstat (limited to 'gcc/cppmacro.c')
-rw-r--r-- | gcc/cppmacro.c | 152 |
1 files changed, 93 insertions, 59 deletions
diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index ae5dfa9..0b1f0ff 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.c @@ -62,13 +62,14 @@ static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **, static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, cpp_macro *, macro_arg *)); static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *)); +static bool create_iso_definition PARAMS ((cpp_reader *, cpp_macro *)); /* #define directive parsing and handling. */ static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *)); static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *)); -static int warn_of_redefinition PARAMS ((const cpp_hashnode *, - const cpp_macro *)); +static bool warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *, + const cpp_macro *)); static int save_parameter PARAMS ((cpp_reader *, cpp_macro *, cpp_hashnode *)); static int parse_params PARAMS ((cpp_reader *, cpp_macro *)); static void check_trad_stringification PARAMS ((cpp_reader *, @@ -917,6 +918,22 @@ push_token_context (pfile, macro, first, count) LAST (context).token = first + count; } +/* Push a traditional macro's replacement text. */ +void +_cpp_push_text_context (pfile, macro, start, end) + cpp_reader *pfile; + cpp_hashnode *macro; + const uchar *start, *end; +{ + cpp_context *context = next_context (pfile); + + context->direct_p = true; + context->macro = macro; + context->buff = NULL; + CUR (context) = start; + RLIMIT (context) = end; +} + /* Expand an argument ARG before replacing parameters in a function-like macro. This works by pushing a context with the argument's tokens, and then expanding that into a temporary buffer @@ -1127,8 +1144,9 @@ _cpp_backup_tokens (pfile, count) /* #define directive parsing and handling. */ /* Returns non-zero if a macro redefinition warning is required. */ -static int -warn_of_redefinition (node, macro2) +static bool +warn_of_redefinition (pfile, node, macro2) + cpp_reader *pfile; const cpp_hashnode *node; const cpp_macro *macro2; { @@ -1137,7 +1155,7 @@ warn_of_redefinition (node, macro2) /* Some redefinitions need to be warned about regardless. */ if (node->flags & NODE_WARN) - return 1; + return true; /* Redefinition of a macro is allowed if and only if the old and new definitions are the same. (6.10.3 paragraph 2). */ @@ -1148,19 +1166,22 @@ warn_of_redefinition (node, macro2) || macro1->paramc != macro2->paramc || macro1->fun_like != macro2->fun_like || macro1->variadic != macro2->variadic) - return 1; - - /* Check each token. */ - for (i = 0; i < macro1->count; i++) - if (! _cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) - return 1; + return true; /* Check parameter spellings. */ for (i = 0; i < macro1->paramc; i++) if (macro1->params[i] != macro2->params[i]) - return 1; + return true; - return 0; + /* Check the replacement text or tokens. */ + if (CPP_OPTION (pfile, traditional)) + return memcmp (macro1->exp.text, macro2->exp.text, macro1->count); + + for (i = 0; i < macro1->count; i++) + if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i])) + return true; + + return false; } /* Free the definition of hashnode H. */ @@ -1316,24 +1337,13 @@ lex_expansion_token (pfile, macro) return token; } -/* Parse a macro and save its expansion. Returns non-zero on success. */ -int -_cpp_create_definition (pfile, node) +static bool +create_iso_definition (pfile, macro) cpp_reader *pfile; - cpp_hashnode *node; + cpp_macro *macro; { - cpp_macro *macro; - cpp_token *token, *saved_cur_token; + cpp_token *token; const cpp_token *ctoken; - unsigned int i, ok = 1; - - macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro)); - macro->line = pfile->directive_line; - macro->params = 0; - macro->paramc = 0; - macro->variadic = 0; - macro->count = 0; - macro->fun_like = 0; /* Get the first token of the expansion (or the '(' of a function-like macro). */ @@ -1341,10 +1351,10 @@ _cpp_create_definition (pfile, node) if (ctoken->type == CPP_OPEN_PAREN && !(ctoken->flags & PREV_WHITE)) { - ok = parse_params (pfile, macro); + bool ok = parse_params (pfile, macro); macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff); if (!ok) - goto cleanup2; + return false; /* Success. Commit the parameter array. */ BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc]; @@ -1354,8 +1364,6 @@ _cpp_create_definition (pfile, node) cpp_error (pfile, DL_PEDWARN, "ISO C requires whitespace after the macro name"); - saved_cur_token = pfile->cur_token; - if (macro->fun_like) token = lex_expansion_token (pfile, macro); else @@ -1381,10 +1389,9 @@ _cpp_create_definition (pfile, node) /* Let assembler get away with murder. */ else if (CPP_OPTION (pfile, lang) != CLK_ASM) { - ok = 0; cpp_error (pfile, DL_ERROR, "'#' is not followed by a macro parameter"); - goto cleanup1; + return false; } } @@ -1401,10 +1408,9 @@ _cpp_create_definition (pfile, node) if (macro->count == 0 || token->type == CPP_EOF) { - ok = 0; cpp_error (pfile, DL_ERROR, "'##' cannot appear at either end of a macro expansion"); - goto cleanup1; + return false; } token[-1].flags |= PASTE_LEFT; @@ -1425,25 +1431,68 @@ _cpp_create_definition (pfile, node) /* Commit the memory. */ BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->exp.tokens[macro->count]; - /* Implement the macro-defined-to-itself optimisation. */ - if (macro->count == 1 && !macro->fun_like - && macro->exp.tokens[0].type == CPP_NAME - && macro->exp.tokens[0].val.node == node) - node->flags |= NODE_DISABLED; + return true; +} + +/* Parse a macro and save its expansion. Returns non-zero on success. */ +bool +_cpp_create_definition (pfile, node) + cpp_reader *pfile; + cpp_hashnode *node; +{ + cpp_macro *macro; + unsigned int i; + bool ok; + macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro)); + macro->line = pfile->directive_line; + macro->params = 0; + macro->paramc = 0; + macro->variadic = 0; + macro->count = 0; + macro->fun_like = 0; /* To suppress some diagnostics. */ macro->syshdr = pfile->map->sysp != 0; + if (CPP_OPTION (pfile, traditional)) + ok = _cpp_create_trad_definition (pfile, macro); + else + { + cpp_token *saved_cur_token = pfile->cur_token; + + ok = create_iso_definition (pfile, macro); + + /* Restore lexer position because of games lex_expansion_token() + plays lexing the macro. We set the type for SEEN_EOL() in + cpplib.c. + + Longer term we should lex the whole line before coming here, + and just copy the expansion. */ + saved_cur_token[-1].type = pfile->cur_token[-1].type; + pfile->cur_token = saved_cur_token; + + /* Stop the lexer accepting __VA_ARGS__. */ + pfile->state.va_args_ok = 0; + } + + /* Clear the fast argument lookup indices. */ + for (i = macro->paramc; i-- > 0; ) + macro->params[i]->arg_index = 0; + + if (!ok) + return ok; + if (node->type != NT_VOID) { - if (warn_of_redefinition (node, macro)) + if (warn_of_redefinition (pfile, node, macro)) { cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0, "\"%s\" redefined", NODE_NAME (node)); if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) - cpp_error_with_line (pfile, DL_PEDWARN, node->value.macro->line, 0, - "this is the location of the previous definition"); + cpp_error_with_line (pfile, DL_PEDWARN, + node->value.macro->line, 0, + "this is the location of the previous definition"); } _cpp_free_definition (node); } @@ -1454,21 +1503,6 @@ _cpp_create_definition (pfile, node) if (! ustrncmp (NODE_NAME (node), DSC ("__STDC_"))) node->flags |= NODE_WARN; - cleanup1: - - /* Set type for SEEN_EOL() in cpplib.c, restore the lexer position. */ - saved_cur_token[-1].type = pfile->cur_token[-1].type; - pfile->cur_token = saved_cur_token; - - cleanup2: - - /* Stop the lexer accepting __VA_ARGS__. */ - pfile->state.va_args_ok = 0; - - /* Clear the fast argument lookup indices. */ - for (i = macro->paramc; i-- > 0; ) - macro->params[i]->arg_index = 0; - return ok; } |