cppmacro.c (funlike_invocation_p): Move some logic to caller in enter_macro_context.
* cppmacro.c (funlike_invocation_p): Move some logic to caller in enter_macro_context. Create a padding token in its own context if necessary when the search for '(' fails. (enter_macro_context): Update. * gcc.dg/cpp/spacing1.c: Update test. From-SVN: r46070
This commit is contained in:
parent
7f8fa05dae
commit
d6da836d4f
4 changed files with 73 additions and 34 deletions
|
@ -1,3 +1,10 @@
|
|||
2001-10-08 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* cppmacro.c (funlike_invocation_p): Move some logic to caller
|
||||
in enter_macro_context. Create a padding token in its own context
|
||||
if necessary when the search for '(' fails.
|
||||
(enter_macro_context): Update.
|
||||
|
||||
2001-10-07 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* ChangeLog.2, c-decl.c, config/i386/i386.md, doc/gcc.texi, gcc.c,
|
||||
|
|
|
@ -75,8 +75,8 @@ static const cpp_token *stringify_arg PARAMS ((cpp_reader *, macro_arg *));
|
|||
static void paste_all_tokens PARAMS ((cpp_reader *, const cpp_token *));
|
||||
static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
|
||||
const cpp_token *));
|
||||
static int funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, macro_arg *));
|
||||
static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
|
||||
/* #define directive parsing and handling. */
|
||||
|
||||
|
@ -616,46 +616,41 @@ collect_args (pfile, node)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
/* Search for an opening parenthesis to the macro of NODE, in such a
|
||||
way that, if none is found, we don't lose the information in any
|
||||
intervening padding tokens. If we find the parenthesis, collect
|
||||
the arguments and return the buffer containing them. */
|
||||
static _cpp_buff *
|
||||
funlike_invocation_p (pfile, node)
|
||||
cpp_reader *pfile;
|
||||
cpp_hashnode *node;
|
||||
{
|
||||
const cpp_token *maybe_paren;
|
||||
_cpp_buff *buff = NULL;
|
||||
const cpp_token *token, *padding = NULL;
|
||||
|
||||
pfile->state.prevent_expansion++;
|
||||
pfile->keep_tokens++;
|
||||
|
||||
pfile->state.parsing_args = 1;
|
||||
do
|
||||
maybe_paren = cpp_get_token (pfile);
|
||||
while (maybe_paren->type == CPP_PADDING);
|
||||
pfile->state.parsing_args = 2;
|
||||
|
||||
if (maybe_paren->type == CPP_OPEN_PAREN)
|
||||
buff = collect_args (pfile, node);
|
||||
else
|
||||
for (;;)
|
||||
{
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
|
||||
cpp_warning (pfile,
|
||||
"function-like macro \"%s\" must be used with arguments in traditional C",
|
||||
NODE_NAME (node));
|
||||
token = cpp_get_token (pfile);
|
||||
if (token->type != CPP_PADDING)
|
||||
break;
|
||||
if (padding == NULL
|
||||
|| (!(padding->flags & PREV_WHITE) && token->val.source == NULL))
|
||||
padding = token;
|
||||
}
|
||||
|
||||
pfile->state.parsing_args = 0;
|
||||
pfile->keep_tokens--;
|
||||
pfile->state.prevent_expansion--;
|
||||
|
||||
if (buff)
|
||||
if (token->type == CPP_OPEN_PAREN)
|
||||
{
|
||||
if (node->value.macro->paramc > 0)
|
||||
replace_args (pfile, node, (macro_arg *) buff->base);
|
||||
_cpp_release_buff (pfile, buff);
|
||||
pfile->state.parsing_args = 2;
|
||||
return collect_args (pfile, node);
|
||||
}
|
||||
|
||||
return buff != 0;
|
||||
/* Back up. We may have skipped padding, in which case backing up
|
||||
more than one token when expanding macros is in general too
|
||||
difficult. We re-insert it in its own context. */
|
||||
_cpp_backup_tokens (pfile, 1);
|
||||
if (padding)
|
||||
push_token_context (pfile, NULL, padding, 1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Push the context of a macro onto the context stack. TOKEN is the
|
||||
|
@ -675,8 +670,32 @@ enter_macro_context (pfile, node)
|
|||
{
|
||||
cpp_macro *macro = node->value.macro;
|
||||
|
||||
if (macro->fun_like && !funlike_invocation_p (pfile, node))
|
||||
return 0;
|
||||
if (macro->fun_like)
|
||||
{
|
||||
_cpp_buff *buff;
|
||||
|
||||
pfile->state.prevent_expansion++;
|
||||
pfile->keep_tokens++;
|
||||
pfile->state.parsing_args = 1;
|
||||
buff = funlike_invocation_p (pfile, node);
|
||||
pfile->state.parsing_args = 0;
|
||||
pfile->keep_tokens--;
|
||||
pfile->state.prevent_expansion--;
|
||||
|
||||
if (buff == NULL)
|
||||
{
|
||||
if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
|
||||
cpp_warning (pfile,
|
||||
"function-like macro \"%s\" must be used with arguments in traditional C",
|
||||
NODE_NAME (node));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (node->value.macro->paramc > 0)
|
||||
replace_args (pfile, node, (macro_arg *) buff->base);
|
||||
_cpp_release_buff (pfile, buff);
|
||||
}
|
||||
|
||||
/* Disable the macro within its expansion. */
|
||||
node->flags |= NODE_DISABLED;
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2001-10-08 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* gcc.dg/cpp/spacing1.c: Update test.
|
||||
|
||||
2001-10-07 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* gcc.c-torture/unsorted/unsorted.exp, lib/file-format.exp: Fix
|
||||
|
|
|
@ -14,11 +14,18 @@
|
|||
#define f(x) x
|
||||
#define glue(x, y) x ## y
|
||||
#define EMPTY
|
||||
/* These are based on PR 4492, we mustn't lose padding tokens when
|
||||
scanning ahead for a '(' and failing to find it. */
|
||||
#define A(x) B x
|
||||
#define B(x)
|
||||
#define C A
|
||||
#define D() A
|
||||
|
||||
/* The correct output is shown here. Note the spaces, and the way
|
||||
everything after the invocation of f appears on the same line.
|
||||
|
||||
44 ;
|
||||
B Q B Q A Q A:
|
||||
f
|
||||
bar
|
||||
g "1 2" bam baz
|
||||
|
@ -26,6 +33,7 @@ g "1 2" bam baz
|
|||
*/
|
||||
|
||||
glue (EMPTY 4, 4) EMPTY;
|
||||
A(Q) C(Q) D()Q D():
|
||||
f
|
||||
bar
|
||||
f (g) str
|
||||
|
@ -37,10 +45,11 @@ f (g) str
|
|||
|
||||
/*
|
||||
{ dg-final { if ![file exists spacing1.i] { return } } }
|
||||
{ dg-final { if \{ [grep spacing1.i " 44 ;"] != "" \} \{ } }
|
||||
{ dg-final { if \{ [grep spacing1.i " 44 ;"] != "" \} \{ } }
|
||||
{ dg-final { if \{ [grep spacing1.i "B Q B Q A Q A:"] != "" \} \{ } }
|
||||
{ dg-final { if \{ [grep spacing1.i "f.*bar"] == "" \} \{ } }
|
||||
{ dg-final { if \{ [grep spacing1.i "^bar"] != "" \} \{ } }
|
||||
{ dg-final { if \{ [grep spacing1.i "g \"1 2\" bam baz"] != "" \} \{ } }
|
||||
{ dg-final { return \} \} \} \} } }
|
||||
{ dg-final { return \} \} \} \} \} } }
|
||||
{ dg-final { fail "spacing1.c: spacing and new-line preservation" } }
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue