| Index: gcc/libcpp/macro.c
|
| diff --git a/gcc/libcpp/macro.c b/gcc/libcpp/macro.c
|
| index d74b80fad3b942fdf3eb02244b617864e6e48f5f..6647db567145461789353fe893a6307bc6f86dfc 100644
|
| --- a/gcc/libcpp/macro.c
|
| +++ b/gcc/libcpp/macro.c
|
| @@ -369,7 +369,9 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg)
|
|
|
| if (token->type == CPP_PADDING)
|
| {
|
| - if (source == NULL)
|
| + if (source == NULL
|
| + || (!(source->flags & PREV_WHITE)
|
| + && token->val.source == NULL))
|
| source = token->val.source;
|
| continue;
|
| }
|
| @@ -377,7 +379,8 @@ stringify_arg (cpp_reader *pfile, macro_arg *arg)
|
| escape_it = (token->type == CPP_STRING || token->type == CPP_CHAR
|
| || token->type == CPP_WSTRING || token->type == CPP_WCHAR
|
| || token->type == CPP_STRING32 || token->type == CPP_CHAR32
|
| - || token->type == CPP_STRING16 || token->type == CPP_CHAR16);
|
| + || token->type == CPP_STRING16 || token->type == CPP_CHAR16
|
| + || token->type == CPP_UTF8STRING);
|
|
|
| /* Room for each char being written in octal, initial space and
|
| final quote and NUL. */
|
| @@ -800,6 +803,19 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
|
| return NULL;
|
| }
|
|
|
| +/* Return the real number of tokens in the expansion of MACRO. */
|
| +static inline unsigned int
|
| +macro_real_token_count (const cpp_macro *macro)
|
| +{
|
| + unsigned int i;
|
| + if (__builtin_expect (!macro->extra_tokens, true))
|
| + return macro->count;
|
| + for (i = 0; i < macro->count; i++)
|
| + if (macro->exp.tokens[i].type == CPP_PASTE)
|
| + return i;
|
| + abort ();
|
| +}
|
| +
|
| /* Push the context of a macro with hash entry NODE onto the context
|
| stack. If we can successfully expand the macro, we push a context
|
| containing its yet-to-be-rescanned replacement list and return one.
|
| @@ -869,10 +885,14 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
|
| pfile->cb.used_define (pfile, pfile->directive_line, node);
|
| }
|
|
|
| + if (pfile->cb.used)
|
| + pfile->cb.used (pfile, result->src_loc, node);
|
| +
|
| macro->used = 1;
|
|
|
| if (macro->paramc == 0)
|
| - _cpp_push_token_context (pfile, node, macro->exp.tokens, macro->count);
|
| + _cpp_push_token_context (pfile, node, macro->exp.tokens,
|
| + macro_real_token_count (macro));
|
|
|
| if (pragma_buff)
|
| {
|
| @@ -912,13 +932,15 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
|
| const cpp_token **dest, **first;
|
| macro_arg *arg;
|
| _cpp_buff *buff;
|
| + unsigned int count;
|
|
|
| /* First, fully macro-expand arguments, calculating the number of
|
| tokens in the final expansion as we go. The ordering of the if
|
| statements below is subtle; we must handle stringification before
|
| pasting. */
|
| - total = macro->count;
|
| - limit = macro->exp.tokens + macro->count;
|
| + count = macro_real_token_count (macro);
|
| + total = count;
|
| + limit = macro->exp.tokens + count;
|
|
|
| for (src = macro->exp.tokens; src < limit; src++)
|
| if (src->type == CPP_MACRO_ARG)
|
| @@ -928,7 +950,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
|
|
|
| /* We have an argument. If it is not being stringified or
|
| pasted it is macro-replaced before insertion. */
|
| - arg = &args[src->val.arg_no - 1];
|
| + arg = &args[src->val.macro_arg.arg_no - 1];
|
|
|
| if (src->flags & STRINGIFY_ARG)
|
| {
|
| @@ -964,7 +986,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
|
| }
|
|
|
| paste_flag = 0;
|
| - arg = &args[src->val.arg_no - 1];
|
| + arg = &args[src->val.macro_arg.arg_no - 1];
|
| if (src->flags & STRINGIFY_ARG)
|
| count = 1, from = &arg->stringified;
|
| else if (src->flags & PASTE_LEFT)
|
| @@ -976,7 +998,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
|
| {
|
| if (dest[-1]->type == CPP_COMMA
|
| && macro->variadic
|
| - && src->val.arg_no == macro->paramc)
|
| + && src->val.macro_arg.arg_no == macro->paramc)
|
| {
|
| /* Swallow a pasted comma if from == NULL, otherwise
|
| drop the paste flag. */
|
| @@ -1017,7 +1039,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg
|
| "empty macro arguments are undefined"
|
| " in ISO C90 and ISO C++98",
|
| NODE_NAME (node),
|
| - src->val.arg_no);
|
| + src->val.macro_arg.arg_no);
|
| }
|
|
|
| /* Avoid paste on RHS (even case count == 0). */
|
| @@ -1243,7 +1265,7 @@ cpp_get_token (cpp_reader *pfile)
|
| if (result->type != CPP_NAME)
|
| break;
|
|
|
| - node = result->val.node;
|
| + node = result->val.node.node;
|
|
|
| if (node->type != NT_MACRO || (result->flags & NO_EXPAND))
|
| break;
|
| @@ -1535,7 +1557,7 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
|
| }
|
| prev_ident = 1;
|
|
|
| - if (_cpp_save_parameter (pfile, macro, token->val.node))
|
| + if (_cpp_save_parameter (pfile, macro, token->val.node.node))
|
| return false;
|
| continue;
|
|
|
| @@ -1608,10 +1630,10 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
|
|
|
| /* Is this a parameter? */
|
| if (token->type == CPP_NAME
|
| - && (token->val.node->flags & NODE_MACRO_ARG) != 0)
|
| + && (token->val.node.node->flags & NODE_MACRO_ARG) != 0)
|
| {
|
| token->type = CPP_MACRO_ARG;
|
| - token->val.arg_no = token->val.node->value.arg_index;
|
| + token->val.macro_arg.arg_no = token->val.node.node->value.arg_index;
|
| }
|
| else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
|
| && (token->type == CPP_STRING || token->type == CPP_CHAR))
|
| @@ -1628,6 +1650,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
|
| bool following_paste_op = false;
|
| const char *paste_op_error_msg =
|
| N_("'##' cannot appear at either end of a macro expansion");
|
| + unsigned int num_extra_tokens = 0;
|
|
|
| /* Get the first token of the expansion (or the '(' of a
|
| function-like macro). */
|
| @@ -1705,6 +1728,10 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
|
| {
|
| if (token->type == CPP_MACRO_ARG)
|
| {
|
| + if (token->flags & PREV_WHITE)
|
| + token->flags |= SP_PREV_WHITE;
|
| + if (token[-1].flags & DIGRAPH)
|
| + token->flags |= SP_DIGRAPH;
|
| token->flags &= ~PREV_WHITE;
|
| token->flags |= STRINGIFY_ARG;
|
| token->flags |= token[-1].flags & PREV_WHITE;
|
| @@ -1744,8 +1771,21 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
|
| return false;
|
| }
|
|
|
| - --macro->count;
|
| - token[-1].flags |= PASTE_LEFT;
|
| + if (token[-1].flags & PASTE_LEFT)
|
| + {
|
| + macro->extra_tokens = 1;
|
| + num_extra_tokens++;
|
| + token->val.token_no = macro->count - 1;
|
| + }
|
| + else
|
| + {
|
| + --macro->count;
|
| + token[-1].flags |= PASTE_LEFT;
|
| + if (token->flags & DIGRAPH)
|
| + token[-1].flags |= SP_DIGRAPH;
|
| + if (token->flags & PREV_WHITE)
|
| + token[-1].flags |= SP_PREV_WHITE;
|
| + }
|
| }
|
|
|
| following_paste_op = (token->type == CPP_PASTE);
|
| @@ -1768,7 +1808,27 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
|
| cpp_token *tokns =
|
| (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token)
|
| * macro->count);
|
| - memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
|
| + if (num_extra_tokens)
|
| + {
|
| + /* Place second and subsequent ## or %:%: tokens in
|
| + sequences of consecutive such tokens at the end of the
|
| + list to preserve information about where they appear, how
|
| + they are spelt and whether they are preceded by
|
| + whitespace without otherwise interfering with macro
|
| + expansion. */
|
| + cpp_token *normal_dest = tokns;
|
| + cpp_token *extra_dest = tokns + macro->count - num_extra_tokens;
|
| + unsigned int i;
|
| + for (i = 0; i < macro->count; i++)
|
| + {
|
| + if (macro->exp.tokens[i].type == CPP_PASTE)
|
| + *extra_dest++ = macro->exp.tokens[i];
|
| + else
|
| + *normal_dest++ = macro->exp.tokens[i];
|
| + }
|
| + }
|
| + else
|
| + memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
|
| macro->exp.tokens = tokns;
|
| }
|
| else
|
| @@ -1797,6 +1857,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
|
| macro->used = !CPP_OPTION (pfile, warn_unused_macros);
|
| macro->count = 0;
|
| macro->fun_like = 0;
|
| + macro->extra_tokens = 0;
|
| /* To suppress some diagnostics. */
|
| macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;
|
|
|
| @@ -1833,11 +1894,13 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
|
|
|
| if (warn_of_redefinition (pfile, node, macro))
|
| {
|
| - cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0,
|
| - "\"%s\" redefined", NODE_NAME (node));
|
| + bool warned;
|
| + warned = cpp_error_with_line (pfile, CPP_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, CPP_DL_PEDWARN,
|
| + if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
|
| + cpp_error_with_line (pfile, CPP_DL_NOTE,
|
| node->value.macro->line, 0,
|
| "this is the location of the previous definition");
|
| }
|
| @@ -1942,12 +2005,13 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
|
| len += _cpp_replacement_text_len (macro);
|
| else
|
| {
|
| - for (i = 0; i < macro->count; i++)
|
| + unsigned int count = macro_real_token_count (macro);
|
| + for (i = 0; i < count; i++)
|
| {
|
| cpp_token *token = ¯o->exp.tokens[i];
|
|
|
| if (token->type == CPP_MACRO_ARG)
|
| - len += NODE_LEN (macro->params[token->val.arg_no - 1]);
|
| + len += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
|
| else
|
| len += cpp_token_len (token);
|
|
|
| @@ -2006,7 +2070,8 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
|
| else if (macro->count)
|
| /* Expansion tokens. */
|
| {
|
| - for (i = 0; i < macro->count; i++)
|
| + unsigned int count = macro_real_token_count (macro);
|
| + for (i = 0; i < count; i++)
|
| {
|
| cpp_token *token = ¯o->exp.tokens[i];
|
|
|
| @@ -2018,9 +2083,9 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
|
| if (token->type == CPP_MACRO_ARG)
|
| {
|
| memcpy (buffer,
|
| - NODE_NAME (macro->params[token->val.arg_no - 1]),
|
| - NODE_LEN (macro->params[token->val.arg_no - 1]));
|
| - buffer += NODE_LEN (macro->params[token->val.arg_no - 1]);
|
| + NODE_NAME (macro->params[token->val.macro_arg.arg_no - 1]),
|
| + NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]));
|
| + buffer += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
|
| }
|
| else
|
| buffer = cpp_spell_token (pfile, token, buffer, false);
|
|
|