From: neil Date: Mon, 8 Oct 2001 06:15:14 +0000 (+0000) Subject: * cppmacro.c (funlike_invocation_p): Move some logic to caller X-Git-Tag: upstream/4.9.2~91747 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2b0e25fe65dede4404ac7020f59775c1ec5ed6b4;p=platform%2Fupstream%2Flinaro-gcc.git * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46070 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f7804a2..559df72 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2001-10-08 Neil Booth + + * 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 * ChangeLog.2, c-decl.c, config/i386/i386.md, doc/gcc.texi, gcc.c, diff --git a/gcc/cppmacro.c b/gcc/cppmacro.c index f9fb0e1..221682e 100644 --- a/gcc/cppmacro.c +++ b/gcc/cppmacro.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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3fdd1e6..a314286 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-10-08 Neil Booth + + * gcc.dg/cpp/spacing1.c: Update test. + 2001-10-07 Joseph S. Myers * gcc.c-torture/unsorted/unsorted.exp, lib/file-format.exp: Fix diff --git a/gcc/testsuite/gcc.dg/cpp/spacing1.c b/gcc/testsuite/gcc.dg/cpp/spacing1.c index 9a3933b..ad1af4e 100644 --- a/gcc/testsuite/gcc.dg/cpp/spacing1.c +++ b/gcc/testsuite/gcc.dg/cpp/spacing1.c @@ -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" } } */