mirror of git://gcc.gnu.org/git/gcc.git
cpphash.h (struct _cpp_buff, [...]): New.
* cpphash.h (struct _cpp_buff, _cpp_get_buff, _cpp_release_buff, _cpp_extend_buff, _cpp_free_buff): New. (struct cpp_reader): New member free_buffs. * cppinit.c (cpp_destroy): Free buffers. * cpplex.c (new_buff, _cpp_release_buff, _cpp_get_buff, _cpp_extend_buff, _cpp_free_buff): New. * cpplib.h (struct cpp_options): Remove unused member. * cppmacro.c (collect_args): New. Combines the old parse_arg and parse_args. Use _cpp_buff for memory allocation. (funlike_invocation_p, replace_args): Update. From-SVN: r45827
This commit is contained in:
parent
9c383523a3
commit
b8af0ca5c7
|
|
@ -1,3 +1,16 @@
|
||||||
|
2001-09-26 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||||
|
|
||||||
|
* cpphash.h (struct _cpp_buff, _cpp_get_buff, _cpp_release_buff,
|
||||||
|
_cpp_extend_buff, _cpp_free_buff): New.
|
||||||
|
(struct cpp_reader): New member free_buffs.
|
||||||
|
* cppinit.c (cpp_destroy): Free buffers.
|
||||||
|
* cpplex.c (new_buff, _cpp_release_buff, _cpp_get_buff,
|
||||||
|
_cpp_extend_buff, _cpp_free_buff): New.
|
||||||
|
* cpplib.h (struct cpp_options): Remove unused member.
|
||||||
|
* cppmacro.c (collect_args): New. Combines the old parse_arg
|
||||||
|
and parse_args. Use _cpp_buff for memory allocation.
|
||||||
|
(funlike_invocation_p, replace_args): Update.
|
||||||
|
|
||||||
Wed Sep 26 13:20:51 CEST 2001 Jan Hubicka <jh@suse.cz>
|
Wed Sep 26 13:20:51 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||||
|
|
||||||
* final.c (final_scan_insn): Use delete_insn instead of delete_note.
|
* final.c (final_scan_insn): Use delete_insn instead of delete_note.
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,21 @@ struct cpp_pool
|
||||||
unsigned int locks;
|
unsigned int locks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* A generic memory buffer. */
|
||||||
|
|
||||||
|
typedef struct _cpp_buff _cpp_buff;
|
||||||
|
struct _cpp_buff
|
||||||
|
{
|
||||||
|
struct _cpp_buff *next;
|
||||||
|
char *base, *cur, *limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern _cpp_buff *_cpp_get_buff PARAMS ((cpp_reader *, unsigned int));
|
||||||
|
extern void _cpp_release_buff PARAMS ((cpp_reader *, _cpp_buff *));
|
||||||
|
extern _cpp_buff *_cpp_extend_buff PARAMS ((cpp_reader *, _cpp_buff *,
|
||||||
|
unsigned int));
|
||||||
|
extern void _cpp_free_buff PARAMS ((_cpp_buff *));
|
||||||
|
|
||||||
/* List of directories to look for include files in. */
|
/* List of directories to look for include files in. */
|
||||||
struct search_path
|
struct search_path
|
||||||
{
|
{
|
||||||
|
|
@ -254,6 +269,9 @@ struct cpp_reader
|
||||||
cpp_pool macro_pool; /* For macro definitions. Permanent. */
|
cpp_pool macro_pool; /* For macro definitions. Permanent. */
|
||||||
cpp_pool argument_pool; /* For macro arguments. Temporary. */
|
cpp_pool argument_pool; /* For macro arguments. Temporary. */
|
||||||
|
|
||||||
|
/* Memory buffers. */
|
||||||
|
_cpp_buff *free_buffs;
|
||||||
|
|
||||||
/* Context stack. */
|
/* Context stack. */
|
||||||
struct cpp_context base_context;
|
struct cpp_context base_context;
|
||||||
struct cpp_context *context;
|
struct cpp_context *context;
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,7 @@ cpp_destroy (pfile)
|
||||||
_cpp_free_pool (&pfile->ident_pool);
|
_cpp_free_pool (&pfile->ident_pool);
|
||||||
_cpp_free_pool (&pfile->macro_pool);
|
_cpp_free_pool (&pfile->macro_pool);
|
||||||
_cpp_free_pool (&pfile->argument_pool);
|
_cpp_free_pool (&pfile->argument_pool);
|
||||||
|
_cpp_free_buff (pfile->free_buffs);
|
||||||
|
|
||||||
for (run = &pfile->base_run; run; run = runn)
|
for (run = &pfile->base_run; run; run = runn)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
92
gcc/cpplex.c
92
gcc/cpplex.c
|
|
@ -107,6 +107,7 @@ static tokenrun *next_tokenrun PARAMS ((tokenrun *));
|
||||||
static cpp_chunk *new_chunk PARAMS ((unsigned int));
|
static cpp_chunk *new_chunk PARAMS ((unsigned int));
|
||||||
static int chunk_suitable PARAMS ((cpp_pool *, cpp_chunk *, unsigned int));
|
static int chunk_suitable PARAMS ((cpp_pool *, cpp_chunk *, unsigned int));
|
||||||
static unsigned int hex_digit_value PARAMS ((unsigned int));
|
static unsigned int hex_digit_value PARAMS ((unsigned int));
|
||||||
|
static _cpp_buff *new_buff PARAMS ((unsigned int));
|
||||||
|
|
||||||
/* Utility routine:
|
/* Utility routine:
|
||||||
|
|
||||||
|
|
@ -2114,7 +2115,7 @@ cpp_interpret_charconst (pfile, token, warn_multi, traditional, pchars_seen)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Memory pools. */
|
/* Memory buffers. */
|
||||||
|
|
||||||
struct dummy
|
struct dummy
|
||||||
{
|
{
|
||||||
|
|
@ -2127,6 +2128,95 @@ struct dummy
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_ALIGNMENT (offsetof (struct dummy, u))
|
#define DEFAULT_ALIGNMENT (offsetof (struct dummy, u))
|
||||||
|
#define CPP_ALIGN(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
|
||||||
|
|
||||||
|
/* Create a new allocation buffer. */
|
||||||
|
static _cpp_buff *
|
||||||
|
new_buff (len)
|
||||||
|
unsigned int len;
|
||||||
|
{
|
||||||
|
_cpp_buff *result;
|
||||||
|
char *base;
|
||||||
|
|
||||||
|
if (len < 4000)
|
||||||
|
len = 4000;
|
||||||
|
len = CPP_ALIGN (len, DEFAULT_ALIGNMENT);
|
||||||
|
|
||||||
|
base = xmalloc (len + sizeof (_cpp_buff));
|
||||||
|
result = (_cpp_buff *) (base + len);
|
||||||
|
result->base = base;
|
||||||
|
result->cur = base;
|
||||||
|
result->limit = base + len;
|
||||||
|
result->next = NULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Place a chain of unwanted allocation buffers on the free list. */
|
||||||
|
void
|
||||||
|
_cpp_release_buff (pfile, buff)
|
||||||
|
cpp_reader *pfile;
|
||||||
|
_cpp_buff *buff;
|
||||||
|
{
|
||||||
|
_cpp_buff *end = buff;
|
||||||
|
|
||||||
|
while (end->next)
|
||||||
|
end = end->next;
|
||||||
|
end->next = pfile->free_buffs;
|
||||||
|
pfile->free_buffs = buff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a free buffer of size at least MIN_SIZE. */
|
||||||
|
_cpp_buff *
|
||||||
|
_cpp_get_buff (pfile, min_size)
|
||||||
|
cpp_reader *pfile;
|
||||||
|
unsigned int min_size;
|
||||||
|
{
|
||||||
|
_cpp_buff *result, **p;
|
||||||
|
|
||||||
|
for (p = &pfile->free_buffs;; p = &(*p)->next)
|
||||||
|
{
|
||||||
|
if (*p == NULL || (*p)->next == NULL)
|
||||||
|
return new_buff (min_size);
|
||||||
|
result = (*p)->next;
|
||||||
|
if ((unsigned int) (result->limit - result->base) > min_size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = result->next;
|
||||||
|
result->next = NULL;
|
||||||
|
result->cur = result->base;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a buffer chained on the end of BUFF. Copy to it the
|
||||||
|
uncommitted remaining bytes of BUFF, with at least MIN_EXTRA more
|
||||||
|
bytes. */
|
||||||
|
_cpp_buff *
|
||||||
|
_cpp_extend_buff (pfile, buff, min_extra)
|
||||||
|
cpp_reader *pfile;
|
||||||
|
_cpp_buff *buff;
|
||||||
|
unsigned int min_extra;
|
||||||
|
{
|
||||||
|
unsigned int size = min_extra + (buff->limit - buff->cur) * 2;
|
||||||
|
|
||||||
|
buff->next = _cpp_get_buff (pfile, size);
|
||||||
|
memcpy (buff->next->base, buff->cur, buff->limit - buff->cur);
|
||||||
|
return buff->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free a chain of buffers starting at BUFF. */
|
||||||
|
void
|
||||||
|
_cpp_free_buff (buff)
|
||||||
|
_cpp_buff *buff;
|
||||||
|
{
|
||||||
|
_cpp_buff *next;
|
||||||
|
|
||||||
|
for (; buff; buff = next)
|
||||||
|
{
|
||||||
|
next = buff->next;
|
||||||
|
free (buff->base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
chunk_suitable (pool, chunk, size)
|
chunk_suitable (pool, chunk, size)
|
||||||
|
|
|
||||||
|
|
@ -236,9 +236,6 @@ struct cpp_options
|
||||||
/* The language we're preprocessing. */
|
/* The language we're preprocessing. */
|
||||||
enum c_lang lang;
|
enum c_lang lang;
|
||||||
|
|
||||||
/* Nonzero means to return spacing characters for stand-alone CPP. */
|
|
||||||
unsigned char spacing;
|
|
||||||
|
|
||||||
/* Non-0 means -v, so print the full set of include dirs. */
|
/* Non-0 means -v, so print the full set of include dirs. */
|
||||||
unsigned char verbose;
|
unsigned char verbose;
|
||||||
|
|
||||||
|
|
|
||||||
245
gcc/cppmacro.c
245
gcc/cppmacro.c
|
|
@ -62,8 +62,7 @@ static void push_token_context
|
||||||
PARAMS ((cpp_reader *, cpp_macro *, const cpp_token *, unsigned int));
|
PARAMS ((cpp_reader *, cpp_macro *, const cpp_token *, unsigned int));
|
||||||
static void push_ptoken_context
|
static void push_ptoken_context
|
||||||
PARAMS ((cpp_reader *, cpp_macro *, const cpp_token **, unsigned int));
|
PARAMS ((cpp_reader *, cpp_macro *, const cpp_token **, unsigned int));
|
||||||
static enum cpp_ttype parse_arg PARAMS ((cpp_reader *, macro_arg *, int));
|
static _cpp_buff *collect_args PARAMS ((cpp_reader *, const cpp_hashnode *));
|
||||||
static macro_arg *parse_args PARAMS ((cpp_reader *, const cpp_hashnode *));
|
|
||||||
static cpp_context *next_context PARAMS ((cpp_reader *));
|
static cpp_context *next_context PARAMS ((cpp_reader *));
|
||||||
static const cpp_token *padding_token
|
static const cpp_token *padding_token
|
||||||
PARAMS ((cpp_reader *, const cpp_token *));
|
PARAMS ((cpp_reader *, const cpp_token *));
|
||||||
|
|
@ -461,116 +460,131 @@ paste_all_tokens (pfile, lhs)
|
||||||
push_token_context (pfile, NULL, pasted, 1);
|
push_token_context (pfile, NULL, pasted, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reads the unexpanded tokens of a macro argument into ARG. VAR_ARGS
|
/* Reads and returns the arguments to a function-like macro invocation.
|
||||||
is non-zero if this is a variadic macro. Returns the type of the
|
Assumes the opening parenthesis has been processed. If there is an
|
||||||
token that caused reading to finish. */
|
error, emits an appropriate diagnostic and returns NULL. */
|
||||||
static enum cpp_ttype
|
static _cpp_buff *
|
||||||
parse_arg (pfile, arg, variadic)
|
collect_args (pfile, node)
|
||||||
cpp_reader *pfile;
|
|
||||||
struct macro_arg *arg;
|
|
||||||
int variadic;
|
|
||||||
{
|
|
||||||
enum cpp_ttype result;
|
|
||||||
unsigned int paren = 0;
|
|
||||||
|
|
||||||
arg->first = (const cpp_token **) POOL_FRONT (&pfile->argument_pool);
|
|
||||||
for (;; arg->count++)
|
|
||||||
{
|
|
||||||
const cpp_token *token;
|
|
||||||
const cpp_token **ptoken = &arg->first[arg->count];
|
|
||||||
if ((unsigned char *) (ptoken + 2) >= POOL_LIMIT (&pfile->argument_pool))
|
|
||||||
{
|
|
||||||
_cpp_next_chunk (&pfile->argument_pool, 2 * sizeof (cpp_token *),
|
|
||||||
(unsigned char **) &arg->first);
|
|
||||||
ptoken = &arg->first[arg->count];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drop leading padding. */
|
|
||||||
do
|
|
||||||
token = cpp_get_token (pfile);
|
|
||||||
while (arg->count == 0 && token->type == CPP_PADDING);
|
|
||||||
*ptoken++ = token;
|
|
||||||
result = token->type;
|
|
||||||
|
|
||||||
if (result == CPP_OPEN_PAREN)
|
|
||||||
paren++;
|
|
||||||
else if (result == CPP_CLOSE_PAREN && paren-- == 0)
|
|
||||||
break;
|
|
||||||
/* Commas are not terminators within parantheses or variadic. */
|
|
||||||
else if (result == CPP_COMMA && paren == 0 && !variadic)
|
|
||||||
break;
|
|
||||||
else if (result == CPP_EOF)
|
|
||||||
{
|
|
||||||
/* We still need the EOF (added below) to end pre-expansion
|
|
||||||
and directives. */
|
|
||||||
if (pfile->context->prev || pfile->state.in_directive)
|
|
||||||
_cpp_backup_tokens (pfile, 1);
|
|
||||||
/* Error reported by caller. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (result == CPP_HASH && token->flags & BOL)
|
|
||||||
{
|
|
||||||
/* 6.10.3 paragraph 11: If there are sequences of
|
|
||||||
preprocessing tokens within the list of arguments that
|
|
||||||
would otherwise act as preprocessing directives, the
|
|
||||||
behavior is undefined.
|
|
||||||
|
|
||||||
This implementation will report a hard error, terminate
|
|
||||||
the macro invocation, and proceed to process the
|
|
||||||
directive. */
|
|
||||||
cpp_error (pfile,
|
|
||||||
"directives may not be used inside a macro argument");
|
|
||||||
_cpp_backup_tokens (pfile, 1);
|
|
||||||
result = CPP_EOF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drop trailing padding. */
|
|
||||||
while (arg->count > 0 && arg->first[arg->count - 1]->type == CPP_PADDING)
|
|
||||||
arg->count--;
|
|
||||||
|
|
||||||
/* Commit the memory used to store the arguments. We make the last
|
|
||||||
argument a CPP_EOF, so that it terminates macro pre-expansion,
|
|
||||||
but it is not included in arg->count. */
|
|
||||||
arg->first[arg->count] = &pfile->eof;
|
|
||||||
POOL_COMMIT (&pfile->argument_pool, (arg->count + 1) * sizeof (cpp_token *));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse the arguments making up a macro invocation. */
|
|
||||||
static macro_arg *
|
|
||||||
parse_args (pfile, node)
|
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
const cpp_hashnode *node;
|
const cpp_hashnode *node;
|
||||||
{
|
{
|
||||||
cpp_macro *macro = node->value.macro;
|
_cpp_buff *buff, *base_buff;
|
||||||
macro_arg *args, *cur;
|
cpp_macro *macro;
|
||||||
enum cpp_ttype type;
|
macro_arg *args, *arg;
|
||||||
int argc, error = 0;
|
const cpp_token *token;
|
||||||
|
unsigned int argc;
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
/* Allocate room for at least one argument, and zero it out. */
|
macro = node->value.macro;
|
||||||
argc = macro->paramc ? macro->paramc: 1;
|
if (macro->paramc)
|
||||||
args = xcnewvec (macro_arg, argc);
|
argc = macro->paramc;
|
||||||
|
else
|
||||||
|
argc = 1;
|
||||||
|
buff = _cpp_get_buff (pfile, argc * (50 * sizeof (cpp_token *)
|
||||||
|
+ sizeof (macro_arg)));
|
||||||
|
base_buff = buff;
|
||||||
|
args = (macro_arg *) buff->base;
|
||||||
|
memset (args, 0, argc * sizeof (macro_arg));
|
||||||
|
buff->cur = (char *) &args[argc];
|
||||||
|
arg = args, argc = 0;
|
||||||
|
|
||||||
for (cur = args, argc = 0; ;)
|
/* Collect the tokens making up each argument. We don't yet know
|
||||||
|
how many arguments have been supplied, whether too many or too
|
||||||
|
few. Hence the slightly bizarre usage of "argc" and "arg". */
|
||||||
|
do
|
||||||
{
|
{
|
||||||
|
unsigned int paren_depth = 0;
|
||||||
|
unsigned int ntokens = 0;
|
||||||
|
|
||||||
argc++;
|
argc++;
|
||||||
|
arg->first = (const cpp_token **) buff->cur;
|
||||||
|
|
||||||
type = parse_arg (pfile, cur, argc == macro->paramc && macro->variadic);
|
for (;;)
|
||||||
if (type == CPP_CLOSE_PAREN || type == CPP_EOF)
|
{
|
||||||
break;
|
/* Require space for 2 new tokens (including a CPP_EOF). */
|
||||||
|
if ((char *) &arg->first[ntokens + 2] > buff->limit)
|
||||||
/* Re-use the last argument for excess arguments. */
|
{
|
||||||
if (argc < macro->paramc)
|
buff = _cpp_extend_buff (pfile, buff,
|
||||||
cur++;
|
1000 * sizeof (cpp_token *));
|
||||||
|
arg->first = (const cpp_token **) buff->cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == CPP_EOF)
|
token = cpp_get_token (pfile);
|
||||||
|
|
||||||
|
if (token->type == CPP_PADDING)
|
||||||
{
|
{
|
||||||
|
/* Drop leading padding. */
|
||||||
|
if (ntokens == 0)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (token->type == CPP_OPEN_PAREN)
|
||||||
|
paren_depth++;
|
||||||
|
else if (token->type == CPP_CLOSE_PAREN)
|
||||||
|
{
|
||||||
|
if (paren_depth-- == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (token->type == CPP_COMMA)
|
||||||
|
{
|
||||||
|
/* A comma does not terminate an argument within
|
||||||
|
parentheses or as part of a variable argument. */
|
||||||
|
if (paren_depth == 0
|
||||||
|
&& ! (macro->variadic && argc == macro->paramc))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (token->type == CPP_EOF
|
||||||
|
|| (token->type == CPP_HASH && token->flags & BOL))
|
||||||
|
break;
|
||||||
|
|
||||||
|
arg->first[ntokens++] = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drop trailing padding. */
|
||||||
|
while (ntokens > 0 && arg->first[ntokens - 1]->type == CPP_PADDING)
|
||||||
|
ntokens--;
|
||||||
|
|
||||||
|
arg->count = ntokens;
|
||||||
|
arg->first[ntokens] = &pfile->eof;
|
||||||
|
|
||||||
|
/* Terminate the argument. Excess arguments loop back and
|
||||||
|
overwrite the final legitimate argument, before failing. */
|
||||||
|
if (argc <= macro->paramc)
|
||||||
|
{
|
||||||
|
buff->cur = (char *) &arg->first[ntokens + 1];
|
||||||
|
if (argc != macro->paramc)
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (token->type != CPP_CLOSE_PAREN
|
||||||
|
&& token->type != CPP_EOF
|
||||||
|
&& token->type != CPP_HASH);
|
||||||
|
|
||||||
|
if (token->type == CPP_EOF || token->type == CPP_HASH)
|
||||||
|
{
|
||||||
|
bool step_back = false;
|
||||||
|
|
||||||
|
/* 6.10.3 paragraph 11: If there are sequences of preprocessing
|
||||||
|
tokens within the list of arguments that would otherwise act
|
||||||
|
as preprocessing directives, the behavior is undefined.
|
||||||
|
|
||||||
|
This implementation will report a hard error, terminate the
|
||||||
|
macro invocation, and proceed to process the directive. */
|
||||||
|
if (token->type == CPP_HASH)
|
||||||
|
{
|
||||||
|
cpp_error (pfile,
|
||||||
|
"directives may not be used inside a macro argument");
|
||||||
|
step_back = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* We still need the CPP_EOF to end directives, and to end
|
||||||
|
pre-expansion of a macro argument. */
|
||||||
|
step_back = (pfile->context->prev || pfile->state.in_directive);
|
||||||
|
|
||||||
|
if (step_back)
|
||||||
|
_cpp_backup_tokens (pfile, 1);
|
||||||
cpp_error (pfile, "unterminated argument list invoking macro \"%s\"",
|
cpp_error (pfile, "unterminated argument list invoking macro \"%s\"",
|
||||||
NODE_NAME (node));
|
NODE_NAME (node));
|
||||||
error = 1;
|
error = true;
|
||||||
}
|
}
|
||||||
else if (argc < macro->paramc)
|
else if (argc < macro->paramc)
|
||||||
{
|
{
|
||||||
|
|
@ -592,28 +606,26 @@ parse_args (pfile, node)
|
||||||
cpp_error (pfile,
|
cpp_error (pfile,
|
||||||
"macro \"%s\" requires %u arguments, but only %u given",
|
"macro \"%s\" requires %u arguments, but only %u given",
|
||||||
NODE_NAME (node), macro->paramc, argc);
|
NODE_NAME (node), macro->paramc, argc);
|
||||||
error = 1;
|
error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (argc > macro->paramc)
|
else if (argc > macro->paramc)
|
||||||
{
|
{
|
||||||
/* Empty argument to a macro taking no arguments is OK. */
|
/* Empty argument to a macro taking no arguments is OK. */
|
||||||
if (argc != 1 || cur->count)
|
if (argc != 1 || arg->count)
|
||||||
{
|
{
|
||||||
cpp_error (pfile,
|
cpp_error (pfile,
|
||||||
"macro \"%s\" passed %u arguments, but takes just %u",
|
"macro \"%s\" passed %u arguments, but takes just %u",
|
||||||
NODE_NAME (node), argc, macro->paramc);
|
NODE_NAME (node), argc, macro->paramc);
|
||||||
error = 1;
|
error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error)
|
if (!error)
|
||||||
{
|
return base_buff;
|
||||||
free (args);
|
|
||||||
args = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return args;
|
_cpp_release_buff (pfile, base_buff);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -622,7 +634,7 @@ funlike_invocation_p (pfile, node)
|
||||||
const cpp_hashnode *node;
|
const cpp_hashnode *node;
|
||||||
{
|
{
|
||||||
const cpp_token *maybe_paren;
|
const cpp_token *maybe_paren;
|
||||||
macro_arg *args = 0;
|
_cpp_buff *buff = NULL;
|
||||||
|
|
||||||
pfile->state.prevent_expansion++;
|
pfile->state.prevent_expansion++;
|
||||||
pfile->keep_tokens++;
|
pfile->keep_tokens++;
|
||||||
|
|
@ -634,7 +646,7 @@ funlike_invocation_p (pfile, node)
|
||||||
pfile->state.parsing_args = 2;
|
pfile->state.parsing_args = 2;
|
||||||
|
|
||||||
if (maybe_paren->type == CPP_OPEN_PAREN)
|
if (maybe_paren->type == CPP_OPEN_PAREN)
|
||||||
args = parse_args (pfile, node);
|
buff = collect_args (pfile, node);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_cpp_backup_tokens (pfile, 1);
|
_cpp_backup_tokens (pfile, 1);
|
||||||
|
|
@ -648,14 +660,14 @@ funlike_invocation_p (pfile, node)
|
||||||
pfile->keep_tokens--;
|
pfile->keep_tokens--;
|
||||||
pfile->state.prevent_expansion--;
|
pfile->state.prevent_expansion--;
|
||||||
|
|
||||||
if (args)
|
if (buff)
|
||||||
{
|
{
|
||||||
if (node->value.macro->paramc > 0)
|
if (node->value.macro->paramc > 0)
|
||||||
replace_args (pfile, node->value.macro, args);
|
replace_args (pfile, node->value.macro, (macro_arg *) buff->base);
|
||||||
free (args);
|
_cpp_release_buff (pfile, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
return args != 0;
|
return buff != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Push the context of a macro onto the context stack. TOKEN is the
|
/* Push the context of a macro onto the context stack. TOKEN is the
|
||||||
|
|
@ -694,8 +706,8 @@ enter_macro_context (pfile, node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Take the expansion of a function-like MACRO, replacing parameters
|
/* Take the expansion of a function-like MACRO, replacing parameters
|
||||||
with the actual arguments. Each instance is first macro-expanded,
|
with the actual arguments. Each argument is macro-expanded before
|
||||||
unless that paramter is operated upon by the # or ## operators. */
|
replacement, unless operated upon by the # or ## operators. */
|
||||||
static void
|
static void
|
||||||
replace_args (pfile, macro, args)
|
replace_args (pfile, macro, args)
|
||||||
cpp_reader *pfile;
|
cpp_reader *pfile;
|
||||||
|
|
@ -904,7 +916,6 @@ expand_arg (pfile, arg)
|
||||||
{
|
{
|
||||||
unsigned int capacity;
|
unsigned int capacity;
|
||||||
|
|
||||||
arg->expanded_count = 0;
|
|
||||||
if (arg->count == 0)
|
if (arg->count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue