[PATCH] Macro body is trailing array

https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01037.html
	* include/cpplib.h (enum cpp_macro_kind): New.
	(struct cpp_macro): Make body trailing array.  Add kind field,
	delete traditional flag.
	* internal.h (_cpp_new_macro): Declare.
	(_cpp_reserve_room): New inline.
	(_cpp_commit_buf): Declare.
	(_cpp_create_trad_definition): Return new macro.
	* lex.c (_cpp_commit_buff): New.
	* macro.c (macro_real_token_count): Count backwards.
	(replace_args): Pointer equality not orderedness.
	(_cpp_save_parameter): Use _cpp_reserve_room.
	(alloc_expansion_token): Delete.
	(lex_expansion_token): Return macro pointer.  Use _cpp_reserve_room.
	(create_iso_definition): Allocate macro itself.  Adjust for
	different allocation ordering.
	(_cpp_new_macro): New.
	(_cpp_create_definition): Adjust for API changes.
	* traditional.c (push_replacement_text): Don't set traditional
	flag.
	(save_replacement_text): Likewise.
	(_cpp_create_trad_definition): Allocate macro itself, Adjust for
	different allocation ordering.

From-SVN: r263622
This commit is contained in:
Nathan Sidwell 2018-08-17 16:07:19 +00:00 committed by Nathan Sidwell
parent c5d725c0a8
commit 10f04917ab
8 changed files with 226 additions and 164 deletions

View File

@ -1,5 +1,7 @@
2018-08-17 Nathan Sidwell <nathan@acm.org>
* c-ada-spec.c (macro_length, dump_ada_macros): Constify.
* c-ada-spec.c: Don't #include "cpp-id-data.h"
* c-cppbuiltin.c: Likewise.

View File

@ -88,7 +88,7 @@ macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
for (j = 0; j < macro->count; j++)
{
cpp_token *token = &macro->exp.tokens[j];
const cpp_token *token = &macro->exp.tokens[j];
if (token->flags & PREV_WHITE)
(*buffer_len)++;
@ -274,7 +274,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
for (i = 0; supported && i < macro->count; i++)
{
cpp_token *token = &macro->exp.tokens[i];
const cpp_token *token = &macro->exp.tokens[i];
int is_one = 0;
if (token->flags & PREV_WHITE)

View File

@ -1,5 +1,28 @@
2018-08-17 Nathan Sidwell <nathan@acm.org>
* include/cpplib.h (enum cpp_macro_kind): New.
(struct cpp_macro): Make body trailing array. Add kind field,
delete traditional flag.
* internal.h (_cpp_new_macro): Declare.
(_cpp_reserve_room): New inline.
(_cpp_commit_buf): Declare.
(_cpp_create_trad_definition): Return new macro.
* lex.c (_cpp_commit_buff): New.
* macro.c (macro_real_token_count): Count backwards.
(replace_args): Pointer equality not orderedness.
(_cpp_save_parameter): Use _cpp_reserve_room.
(alloc_expansion_token): Delete.
(lex_expansion_token): Return macro pointer. Use _cpp_reserve_room.
(create_iso_definition): Allocate macro itself. Adjust for
different allocation ordering.
(_cpp_new_macro): New.
(_cpp_create_definition): Adjust for API changes.
* traditional.c (push_replacement_text): Don't set traditional
flag.
(save_replacement_text): Likewise.
(_cpp_create_trad_definition): Allocate macro itself, Adjust for
different allocation ordering.
* cpp-id-data.h (uchar, UC): Move to internal.h
(struct cpp_macro): Move to cpplib.h.
* internal.h (uchar, UC): From cpp-id-data.h.

View File

@ -671,6 +671,12 @@ struct cpp_dir
dev_t dev;
};
/* The kind of the cpp_macro. */
enum cpp_macro_kind {
cmk_macro, /* An ISO macro (token expansion). */
cmk_traditional, /* A traditional macro (text expansion). */
};
/* Each macro definition is recorded in a cpp_macro structure.
Variadic macros cannot occur with traditional cpp. */
struct GTY(()) cpp_macro {
@ -683,15 +689,6 @@ struct GTY(()) cpp_macro {
length ("%h.paramc")))
params;
/* Replacement tokens (ISO) or replacement text (traditional). See
comment at top of cpptrad.c for how traditional function-like
macros are encoded. */
union cpp_macro_u
{
cpp_token * GTY ((tag ("0"), length ("%0.count"))) tokens;
const unsigned char * GTY ((tag ("1"))) text;
} GTY ((desc ("%1.traditional"))) exp;
/* Definition line number. */
source_location line;
@ -701,6 +698,9 @@ struct GTY(()) cpp_macro {
/* Number of parameters. */
unsigned short paramc;
/* The kind of this macro (ISO, trad or assert) */
unsigned kind : 2;
/* If a function-like macro. */
unsigned int fun_like : 1;
@ -713,13 +713,23 @@ struct GTY(()) cpp_macro {
/* Nonzero if it has been expanded or had its existence tested. */
unsigned int used : 1;
/* Indicate which field of 'exp' is in use. */
unsigned int traditional : 1;
/* Indicate whether the tokens include extra CPP_PASTE tokens at the
end to track invalid redefinitions with consecutive CPP_PASTE
tokens. */
unsigned int extra_tokens : 1;
/* 1 bits spare (32-bit). 33 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;
};
/* The structure of a node in the hash table. The hash table has

View File

@ -633,6 +633,7 @@ inline void _cpp_maybe_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node)
if (!(node->flags & NODE_USED))
_cpp_notify_macro_use (pfile, node);
}
extern cpp_macro *_cpp_new_macro (cpp_reader *, cpp_macro_kind, void *);
extern void _cpp_free_definition (cpp_hashnode *);
extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *);
extern void _cpp_pop_context (cpp_reader *);
@ -697,6 +698,14 @@ extern void _cpp_init_tokenrun (tokenrun *, unsigned int);
extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *);
extern int _cpp_remaining_tokens_num_in_context (cpp_context *);
extern void _cpp_init_lexer (void);
static inline void *_cpp_reserve_room (cpp_reader *pfile, size_t have,
size_t extra)
{
if (BUFF_ROOM (pfile->a_buff) < (have + extra))
_cpp_extend_buff (pfile, &pfile->a_buff, extra);
return BUFF_FRONT (pfile->a_buff);
}
extern void *_cpp_commit_buff (cpp_reader *pfile, size_t size);
/* In init.c. */
extern void _cpp_maybe_push_include_file (cpp_reader *);
@ -733,7 +742,7 @@ extern bool _cpp_read_logical_line_trad (cpp_reader *);
extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *,
size_t);
extern void _cpp_remove_overlay (cpp_reader *);
extern bool _cpp_create_trad_definition (cpp_reader *, cpp_macro *);
extern cpp_macro *_cpp_create_trad_definition (cpp_reader *);
extern bool _cpp_expansions_different_trad (const cpp_macro *,
const cpp_macro *);
extern unsigned char *_cpp_copy_replacement_text (const cpp_macro *,

View File

@ -3725,6 +3725,25 @@ _cpp_aligned_alloc (cpp_reader *pfile, size_t len)
return result;
}
/* Commit or allocate storage from a buffer. */
void *
_cpp_commit_buff (cpp_reader *pfile, size_t size)
{
void *ptr = BUFF_FRONT (pfile->a_buff);
if (pfile->hash_table->alloc_subobject)
{
void *copy = pfile->hash_table->alloc_subobject (size);
memcpy (copy, ptr, size);
ptr = copy;
}
else
BUFF_FRONT (pfile->a_buff) += size;
return ptr;
}
/* Say which field of TOK is in use. */
enum cpp_token_fld_kind

View File

@ -308,12 +308,11 @@ static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
macro_arg *, source_location);
static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *,
_cpp_buff **, unsigned *);
static bool create_iso_definition (cpp_reader *, cpp_macro *);
static cpp_macro *create_iso_definition (cpp_reader *);
/* #define directive parsing and handling. */
static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *);
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 *);
@ -1235,13 +1234,14 @@ funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node,
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
@ -1773,7 +1773,7 @@ replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro,
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
{
@ -3078,10 +3078,9 @@ _cpp_save_parameter (cpp_reader *pfile, unsigned n, cpp_hashnode *node,
saved[n].canonical_node = node;
saved[n].value = node->value;
if (BUFF_ROOM (pfile->a_buff) < (n + 1) * sizeof (cpp_hashnode *))
_cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[n] = spelling;
void *base = _cpp_reserve_room (pfile, n * sizeof (cpp_hashnode *),
sizeof (cpp_hashnode *));
((cpp_hashnode **)base)[n] = spelling;
/* Morph into a macro arg. */
node->flags |= NODE_MACRO_ARG;
@ -3226,26 +3225,18 @@ parse_params (cpp_reader *pfile, unsigned *n_ptr, bool *varadic_ptr)
return ok;
}
/* Allocate room for a token from a macro's replacement list. */
static cpp_token *
alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro)
{
if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
_cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
return &((cpp_token *) BUFF_FRONT (pfile->a_buff))[macro->count++];
}
/* 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)
{
cpp_token *token, *saved_cur_token;
saved_cur_token = pfile->cur_token;
pfile->cur_token = alloc_expansion_token (pfile, macro);
token = _cpp_lex_direct (pfile);
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 = &macro->exp.tokens[macro->count];
cpp_token *token = _cpp_lex_direct (pfile);
pfile->cur_token = saved_cur_token;
/* Is this a parameter? */
@ -3261,52 +3252,45 @@ lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
&& (token->type == CPP_STRING || token->type == CPP_CHAR))
check_trad_stringification (pfile, macro, &token->val.str);
return token;
return macro;
}
static bool
create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
static cpp_macro *
create_iso_definition (cpp_reader *pfile)
{
cpp_token *token;
const cpp_token *ctoken;
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;
unsigned nparms = 0;
cpp_hashnode **params = NULL;
bool varadic = false;
bool ok = false;
cpp_macro *macro = NULL;
/* Get the first token of the expansion (or the '(' of a
function-like macro). */
ctoken = _cpp_lex_token (pfile);
/* Look at the first token, to see if this is a function-like
macro. */
cpp_token first;
cpp_token *saved_cur_token = pfile->cur_token;
pfile->cur_token = &first;
cpp_token *token = _cpp_lex_direct (pfile);
pfile->cur_token = saved_cur_token;
if (ctoken->flags & PREV_WHITE)
if (token->flags & PREV_WHITE)
/* Preceeded by space, must be part of expansion. */;
else if (ctoken->type == CPP_OPEN_PAREN)
else if (token->type == CPP_OPEN_PAREN)
{
/* An open-paren, get a parameter list. */
if (!parse_params (pfile, &nparms, &varadic))
goto out;
macro->variadic = varadic;
macro->paramc = nparms;
macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
/* Success. Commit or allocate the parameter array. */
if (pfile->hash_table->alloc_subobject)
{
cpp_hashnode **params =
(cpp_hashnode **) pfile->hash_table->alloc_subobject
(sizeof (cpp_hashnode *) * macro->paramc);
memcpy (params, macro->params,
sizeof (cpp_hashnode *) * macro->paramc);
macro->params = params;
}
else
BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
macro->fun_like = 1;
params = (cpp_hashnode **)_cpp_commit_buff
(pfile, sizeof (cpp_hashnode *) * nparms);
token = NULL;
}
else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
else if (token->type != CPP_EOF
&& !(token->type == CPP_COMMENT
&& ! CPP_OPTION (pfile, discard_comments_in_macro_exp)))
{
/* While ISO C99 requires whitespace before replacement text
in a macro definition, ISO C90 with TC1 allows characters
@ -3319,7 +3303,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
else
{
int warntype = CPP_DL_WARNING;
switch (ctoken->type)
switch (token->type)
{
case CPP_ATSIGN:
case CPP_AT_NAME:
@ -3330,7 +3314,7 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
case CPP_OTHER:
/* Basic character set sans letters, digits and _. */
if (strchr ("!\"#%&'()*+,-./:;<=>?[\\]^{|}~",
ctoken->val.str.text[0]) == NULL)
token->val.str.text[0]) == NULL)
warntype = CPP_DL_PEDWARN;
break;
default:
@ -3343,16 +3327,32 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
}
}
if (macro->fun_like)
token = lex_expansion_token (pfile, macro);
macro = _cpp_new_macro (pfile, cmk_macro,
_cpp_reserve_room (pfile, 0, sizeof (cpp_macro)));
if (!token)
{
macro->variadic = varadic;
macro->paramc = nparms;
macro->params = params;
macro->fun_like = true;
}
else
{
token = alloc_expansion_token (pfile, macro);
*token = *ctoken;
/* Preserve the token we peeked, there is already a single slot for it. */
macro->exp.tokens[0] = *token;
token = &macro->exp.tokens[0];
macro->count = 1;
}
for ( vaopt_state vaopt_tracker (pfile, macro->variadic, true);;)
for (vaopt_state vaopt_tracker (pfile, macro->variadic, true);; token = NULL)
{
if (!token)
{
macro = lex_expansion_token (pfile, macro);
token = &macro->exp.tokens[macro->count++];
}
/* Check the stringifying # constraint 6.10.3.2.1 of
function-like macros when lexing the subsequent token. */
if (macro->count > 1 && token[-1].type == CPP_HASH && macro->fun_like)
@ -3404,14 +3404,16 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
goto out;
}
if (token[-1].flags & PASTE_LEFT)
if (following_paste_op)
{
macro->extra_tokens = 1;
/* Consecutive paste operators. This one will be moved
to the end. */
num_extra_tokens++;
token->val.token_no = macro->count - 1;
}
else
{
/* Drop the paste operator. */
--macro->count;
token[-1].flags |= PASTE_LEFT;
if (token->flags & DIGRAPH)
@ -3419,79 +3421,64 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
if (token->flags & PREV_WHITE)
token[-1].flags |= SP_PREV_WHITE;
}
following_paste_op = true;
}
else
following_paste_op = false;
if (vaopt_tracker.update (token) == vaopt_state::ERROR)
goto out;
following_paste_op = (token->type == CPP_PASTE);
token = lex_expansion_token (pfile, macro);
}
/* We're committed to winning now. */
ok = true;
macro->exp.tokens = (cpp_token *) BUFF_FRONT (pfile->a_buff);
macro->traditional = 0;
/* Don't count the CPP_EOF. */
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)
macro->exp.tokens[0].flags &= ~PREV_WHITE;
/* Commit or allocate the memory. */
if (pfile->hash_table->alloc_subobject)
if (num_extra_tokens)
{
cpp_token *tokns =
(cpp_token *) pfile->hash_table->alloc_subobject (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;
/* 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. Remember, this is
extremely rare, so efficiency is not a priority. */
cpp_token *temp = (cpp_token *)_cpp_reserve_room
(pfile, 0, num_extra_tokens * sizeof (cpp_token));
unsigned extra_ix = 0, norm_ix = 0;
cpp_token *exp = macro->exp.tokens;
for (unsigned ix = 0; ix != macro->count; ix++)
if (exp[ix].type == CPP_PASTE)
temp[extra_ix++] = exp[ix];
else
exp[norm_ix++] = exp[ix];
memcpy (&exp[norm_ix], temp, num_extra_tokens * sizeof (cpp_token));
/* Record there are extra tokens. */
macro->extra_tokens = 1;
}
else
BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->exp.tokens[macro->count];
out:
pfile->state.va_args_ok = 0;
_cpp_unsave_parameters (pfile, nparms);
return ok;
return ok ? macro : NULL;
}
/* Parse a macro and save its expansion. Returns nonzero on success. */
bool
_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
cpp_macro *
_cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement)
{
cpp_macro *macro;
bool ok;
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->params = 0;
macro->paramc = 0;
@ -3503,15 +3490,26 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
/* To suppress some diagnostics. */
macro->syshdr = pfile->buffer && pfile->buffer->sysp != 0;
macro->kind = kind;
return macro;
}
/* Parse a macro and save its expansion. Returns nonzero on success. */
bool
_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
{
cpp_macro *macro;
if (CPP_OPTION (pfile, traditional))
ok = _cpp_create_trad_definition (pfile, macro);
macro = _cpp_create_trad_definition (pfile);
else
ok = create_iso_definition (pfile, macro);
macro = create_iso_definition (pfile);
if (!ok)
return ok;
if (!macro)
return false;
if (node->type == NT_MACRO)
if (cpp_macro_p (node))
{
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, node, NULL);
@ -3552,7 +3550,7 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
conditional flag */
node->flags &= ~NODE_CONDITIONAL;
return ok;
return true;
}
/* Notify the use of NODE in a macro-aware context (i.e. expanding it,
@ -3678,7 +3676,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
unsigned int count = macro_real_token_count (macro);
for (i = 0; i < count; i++)
{
cpp_token *token = &macro->exp.tokens[i];
const cpp_token *token = &macro->exp.tokens[i];
if (token->type == CPP_MACRO_ARG)
len += NODE_LEN (token->val.macro_arg.spelling);
@ -3742,7 +3740,7 @@ cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
unsigned int count = macro_real_token_count (macro);
for (i = 0; i < count; i++)
{
cpp_token *token = &macro->exp.tokens[i];
const cpp_token *token = &macro->exp.tokens[i];
if (token->flags & PREV_WHITE)
*buffer++ = ' ';

View File

@ -853,7 +853,6 @@ push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
cpp_macro *macro = node->value.macro;
macro->used = 1;
text = macro->exp.text;
macro->traditional = 1;
len = macro->count;
}
@ -1143,7 +1142,6 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
memcpy (exp, pfile->out.base, len);
exp[len] = '\n';
macro->exp.text = exp;
macro->traditional = 1;
macro->count = len;
}
else
@ -1159,7 +1157,6 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
exp = BUFF_FRONT (pfile->a_buff);
block = (struct block *) (exp + macro->count);
macro->exp.text = exp;
macro->traditional = 1;
/* Write out the block information. */
block->text_len = len;
@ -1179,13 +1176,15 @@ save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
/* Analyze and save the replacement text of a macro. Returns true on
success. */
bool
_cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
cpp_macro *
_cpp_create_trad_definition (cpp_reader *pfile)
{
const uchar *cur;
uchar *limit;
cpp_context *context = pfile->context;
unsigned nparms = 0;
int fun_like = 0;
cpp_hashnode **params = NULL;
/* The context has not been set up for command line defines, and CUR
has not been updated for the macro name for in-file defines. */
@ -1197,21 +1196,23 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
/* Is this a function-like macro? */
if (* CUR (context) == '(')
{
bool ok = scan_parameters (pfile, &nparms);
macro->paramc = nparms;
/* Remember the params so we can clear NODE_MACRO_ARG flags. */
macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
/* Setting macro to NULL indicates an error occurred, and
prevents unnecessary work in _cpp_scan_out_logical_line. */
if (!ok)
macro = NULL;
fun_like = +1;
if (scan_parameters (pfile, &nparms))
params = (cpp_hashnode **)_cpp_commit_buff
(pfile, sizeof (cpp_hashnode *) * nparms);
else
{
BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
macro->fun_like = 1;
}
fun_like = -1;
}
cpp_macro *macro = NULL;
if (fun_like >= 0)
{
macro = _cpp_new_macro (pfile, cmk_traditional,
_cpp_aligned_alloc (pfile, sizeof (cpp_macro)));
macro->params = params;
macro->paramc = nparms;
macro->fun_like = fun_like != 0;
}
/* Skip leading whitespace in the replacement text. */
@ -1225,18 +1226,18 @@ _cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
_cpp_unsave_parameters (pfile, nparms);
if (!macro)
return false;
if (macro)
{
/* Skip trailing white space. */
cur = pfile->out.base;
limit = pfile->out.cur;
while (limit > cur && is_space (limit[-1]))
limit--;
pfile->out.cur = limit;
save_replacement_text (pfile, macro, 0);
}
/* Skip trailing white space. */
cur = pfile->out.base;
limit = pfile->out.cur;
while (limit > cur && is_space (limit[-1]))
limit--;
pfile->out.cur = limit;
save_replacement_text (pfile, macro, 0);
return true;
return macro;
}
/* Copy SRC of length LEN to DEST, but convert all contiguous