Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Unified Diff: gcc/libcpp/macro.c

Issue 3050029: [gcc] GCC 4.5.0=>4.5.1 (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/nacl-toolchain.git
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gcc/libcpp/line-map.c ('k') | gcc/libcpp/makedepend.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 = &macro->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 = &macro->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);
« no previous file with comments | « gcc/libcpp/line-map.c ('k') | gcc/libcpp/makedepend.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698