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); |