cpp_macro *GTY ((tag ("true"))) next;
} GTY ((desc ("%1.kind == cmk_assert"))) parm;
- union cpp_exp_u
- {
- /* Replacement tokens (ISO), or assertion body value. */
- cpp_token * GTY ((tag ("false"), length ("%1.count"))) tokens;
-
- /* Replacement text (traditional). See comment at top of
- cpptrad.c for how traditional function-like macros are
- encoded. */
- const unsigned char * GTY ((tag ("true"))) text;
- } GTY ((desc ("%1.kind == cmk_traditional"))) exp;
-
/* Definition line number. */
source_location line;
unsigned int extra_tokens : 1;
/* 9 bits spare (32-bit). 41 on 64-bit target. */
+
+ union cpp_exp_u
+ {
+ /* Trailing array of replacement tokens (ISO), or assertion body value. */
+ cpp_token GTY ((tag ("false"), length ("%1.count"))) tokens[1];
+
+ /* Pointer to replacement text (traditional). See comment at top
+ of cpptrad.c for how traditional function-like macros are
+ encoded. */
+ const unsigned char *GTY ((tag ("true"))) text;
+ } GTY ((desc ("%1.kind == cmk_traditional"))) exp;
};
/* #define directive parsing and handling. */
-static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *);
+static cpp_macro *lex_expansion_token (cpp_reader *, cpp_macro *);
static bool warn_of_redefinition (cpp_reader *, cpp_hashnode *,
const cpp_macro *);
static bool parse_params (cpp_reader *, unsigned *, bool *);
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 ();
+
+ for (unsigned i = macro->count; i--;)
+ if (macro->exp.tokens[i].type != CPP_PASTE)
+ return i + 1;
+
+ return 0;
}
/* Push the context of a macro with hash entry NODE onto the context
arg->stringified = stringify_arg (pfile, arg);
}
else if ((src->flags & PASTE_LEFT)
- || (src > macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
+ || (src != macro->exp.tokens && (src[-1].flags & PASTE_LEFT)))
total += arg->count - 1;
else
{
/* Lex a token from the expansion of MACRO, but mark parameters as we
find them and warn of traditional stringification. */
-static cpp_token *
+static cpp_macro *
lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
{
- void *base = _cpp_reserve_room (pfile, macro->count * sizeof (cpp_token),
- sizeof (cpp_token));
+ macro = (cpp_macro *)_cpp_reserve_room (pfile,
+ sizeof (cpp_macro) - sizeof (cpp_token)
+ + macro->count * sizeof (cpp_token),
+ sizeof (cpp_token));
cpp_token *saved_cur_token = pfile->cur_token;
- pfile->cur_token = &((cpp_token *) base)[macro->count++];
+ pfile->cur_token = ¯o->exp.tokens[macro->count];
cpp_token *token = _cpp_lex_direct (pfile);
pfile->cur_token = saved_cur_token;
&& (token->type == CPP_STRING || token->type == CPP_CHAR))
check_trad_stringification (pfile, macro, &token->val.str);
- return token;
+ return macro;
}
static cpp_macro *
}
}
- macro = _cpp_new_macro (pfile, cmk_macro);
+ macro = _cpp_construct_macro (pfile, cmk_macro,
+ _cpp_reserve_room (pfile, 0,
+ sizeof (cpp_macro)));
+
if (!token)
{
macro->variadic = varadic;
}
else
{
- /* Preserve the token we peeked. */
- void *base = _cpp_reserve_room (pfile, 0, sizeof (cpp_token));
- *(cpp_token *)base = *token;
- token = (cpp_token *)base;
+ /* Preserve the token we peeked, there is already a single slot for it. */
+ macro->exp.tokens[0] = *token;
+ token = ¯o->exp.tokens[0];
macro->count = 1;
}
for (vaopt_state vaopt_tracker (pfile, macro->variadic, true);; token = NULL)
{
if (!token)
- token = lex_expansion_token (pfile, macro);
+ {
+ macro = lex_expansion_token (pfile, macro);
+ token = ¯o->exp.tokens[macro->count++];
+ }
/* Check the stringifying # constraint 6.10.3.2.1 of
function-like macros when lexing the subsequent token. */
/* Don't count the CPP_EOF. */
macro->count--;
- macro->exp.tokens = (cpp_token *)_cpp_commit_buff
- (pfile, sizeof (cpp_token) * macro->count);
+ macro = (cpp_macro *)_cpp_commit_buff
+ (pfile, sizeof (cpp_macro) - sizeof (cpp_token)
+ + sizeof (cpp_token) * macro->count);
/* Clear whitespace on first token for warn_of_redefinition(). */
if (macro->count)
}
cpp_macro *
-_cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind)
+_cpp_construct_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement)
{
- cpp_macro *macro;
+ cpp_macro *macro = (cpp_macro *) placement;
- if (pfile->hash_table->alloc_subobject)
- macro = (cpp_macro *) pfile->hash_table->alloc_subobject
- (sizeof (cpp_macro));
- else
- macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
macro->line = pfile->directive_line;
macro->parm.params = 0;
macro->paramc = 0;
return macro;
}
+cpp_macro *
+_cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind)
+{
+ void *placement;
+
+ if (pfile->hash_table->alloc_subobject)
+ placement = pfile->hash_table->alloc_subobject (sizeof (cpp_macro));
+ else
+ placement = _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
+ return _cpp_construct_macro (pfile, kind, placement);
+}
+
/* Parse a macro and save its expansion. Returns nonzero on success. */
bool
_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
unsigned int count = macro_real_token_count (macro);
for (i = 0; i < count; i++)
{
- cpp_token *token = ¯o->exp.tokens[i];
+ const cpp_token *token = ¯o->exp.tokens[i];
if (token->type == CPP_MACRO_ARG)
len += NODE_LEN (token->val.macro_arg.spelling);
unsigned int count = macro_real_token_count (macro);
for (i = 0; i < count; i++)
{
- cpp_token *token = ¯o->exp.tokens[i];
+ const cpp_token *token = ¯o->exp.tokens[i];
if (token->flags & PREV_WHITE)
*buffer++ = ' ';