aboutsummaryrefslogtreecommitdiff
path: root/libcpp/macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcpp/macro.c')
-rw-r--r--libcpp/macro.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 8fa9770..678bf2b 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -80,6 +80,15 @@ struct macro_arg_token_iter
#endif
};
+/* Saved data about an identifier being used as a macro argument
+ name. */
+struct macro_arg_saved_data {
+ /* The canonical (UTF-8) spelling of this identifier. */
+ cpp_hashnode *canonical_node;
+ /* The previous value of this identifier. */
+ union _cpp_hashnode_value value;
+};
+
/* Macro expansion. */
static int enter_macro_context (cpp_reader *, cpp_hashnode *,
@@ -590,7 +599,7 @@ paste_tokens (cpp_reader *pfile, source_location location,
len = cpp_token_len (*plhs) + cpp_token_len (rhs) + 1;
buf = (unsigned char *) alloca (len);
- end = lhsend = cpp_spell_token (pfile, *plhs, buf, false);
+ end = lhsend = cpp_spell_token (pfile, *plhs, buf, true);
/* Avoid comment headers, since they are still processed in stage 3.
It is simpler to insert a space here, rather than modifying the
@@ -600,7 +609,7 @@ paste_tokens (cpp_reader *pfile, source_location location,
*end++ = ' ';
/* In one obscure case we might see padding here. */
if (rhs->type != CPP_PADDING)
- end = cpp_spell_token (pfile, rhs, end, false);
+ end = cpp_spell_token (pfile, rhs, end, true);
*end = '\n';
cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true);
@@ -2748,10 +2757,12 @@ _cpp_free_definition (cpp_hashnode *h)
h->flags &= ~(NODE_BUILTIN | NODE_DISABLED | NODE_USED);
}
-/* Save parameter NODE to the parameter list of macro MACRO. Returns
- zero on success, nonzero if the parameter is a duplicate. */
+/* Save parameter NODE (spelling SPELLING) to the parameter list of
+ macro MACRO. Returns zero on success, nonzero if the parameter is
+ a duplicate. */
bool
-_cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node)
+_cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node,
+ cpp_hashnode *spelling)
{
unsigned int len;
/* Constraint 6.10.3.6 - duplicate parameter names. */
@@ -2766,17 +2777,20 @@ _cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node)
< (macro->paramc + 1) * sizeof (cpp_hashnode *))
_cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
- ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node;
+ ((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = spelling;
node->flags |= NODE_MACRO_ARG;
- len = macro->paramc * sizeof (union _cpp_hashnode_value);
+ len = macro->paramc * sizeof (struct macro_arg_saved_data);
if (len > pfile->macro_buffer_len)
{
pfile->macro_buffer = XRESIZEVEC (unsigned char, pfile->macro_buffer,
len);
pfile->macro_buffer_len = len;
}
- ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1]
- = node->value;
+ struct macro_arg_saved_data save;
+ save.value = node->value;
+ save.canonical_node = node;
+ ((struct macro_arg_saved_data *) pfile->macro_buffer)[macro->paramc - 1]
+ = save;
node->value.arg_index = macro->paramc;
return false;
@@ -2816,7 +2830,8 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
}
prev_ident = 1;
- if (_cpp_save_parameter (pfile, macro, token->val.node.node))
+ if (_cpp_save_parameter (pfile, macro, token->val.node.node,
+ token->val.node.spelling))
return false;
continue;
@@ -2839,6 +2854,7 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
if (!prev_ident)
{
_cpp_save_parameter (pfile, macro,
+ pfile->spec_nodes.n__VA_ARGS__,
pfile->spec_nodes.n__VA_ARGS__);
pfile->state.va_args_ok = 1;
if (! CPP_OPTION (pfile, c99)
@@ -2909,8 +2925,10 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
if (token->type == CPP_NAME
&& (token->val.node.node->flags & NODE_MACRO_ARG) != 0)
{
+ cpp_hashnode *spelling = token->val.node.spelling;
token->type = CPP_MACRO_ARG;
token->val.macro_arg.arg_no = token->val.node.node->value.arg_index;
+ token->val.macro_arg.spelling = spelling;
}
else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
&& (token->type == CPP_STRING || token->type == CPP_CHAR))
@@ -3162,9 +3180,11 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
/* Clear the fast argument lookup indices. */
for (i = macro->paramc; i-- > 0; )
{
- struct cpp_hashnode *node = macro->params[i];
+ struct macro_arg_saved_data *save =
+ &((struct macro_arg_saved_data *) pfile->macro_buffer)[i];
+ struct cpp_hashnode *node = save->canonical_node;
node->flags &= ~ NODE_MACRO_ARG;
- node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i];
+ node->value = save->value;
}
if (!ok)
@@ -3285,7 +3305,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
macro = node->value.macro;
/* Calculate length. */
- len = NODE_LEN (node) + 2; /* ' ' and NUL. */
+ len = NODE_LEN (node) * 10 + 2; /* ' ' and NUL. */
if (macro->fun_like)
{
len += 4; /* "()" plus possible final ".." of named
@@ -3305,7 +3325,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
cpp_token *token = &macro->exp.tokens[i];
if (token->type == CPP_MACRO_ARG)
- len += NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
+ len += NODE_LEN (token->val.macro_arg.spelling);
else
len += cpp_token_len (token);
@@ -3327,8 +3347,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
/* Fill in the buffer. Start with the macro name. */
buffer = pfile->macro_buffer;
- memcpy (buffer, NODE_NAME (node), NODE_LEN (node));
- buffer += NODE_LEN (node);
+ buffer = _cpp_spell_ident_ucns (buffer, node);
/* Parameter names. */
if (macro->fun_like)
@@ -3377,12 +3396,12 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
if (token->type == CPP_MACRO_ARG)
{
memcpy (buffer,
- 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]);
+ NODE_NAME (token->val.macro_arg.spelling),
+ NODE_LEN (token->val.macro_arg.spelling));
+ buffer += NODE_LEN (token->val.macro_arg.spelling);
}
else
- buffer = cpp_spell_token (pfile, token, buffer, false);
+ buffer = cpp_spell_token (pfile, token, buffer, true);
if (token->flags & PASTE_LEFT)
{