aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2018-08-17 16:07:19 +0000
committerNathan Sidwell <nathan@acm.org>2018-08-17 16:07:19 +0000
commitd1297589e153881bafba8d64238b190721cccbc6 (patch)
treed1b399c099142510b8abea59d95c27a5dd4ecf58 /libcpp
parent60643e31798c8ae385816f5b027bf7be9259ddf7 (diff)
[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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@263622 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog23
-rw-r--r--libcpp/include/cpplib.h34
-rw-r--r--libcpp/internal.h11
-rw-r--r--libcpp/lex.c19
-rw-r--r--libcpp/macro.c236
-rw-r--r--libcpp/traditional.c59
6 files changed, 221 insertions, 161 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 978b32e37c6..c79866f502a 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -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.
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 2b3440d251d..a0d0c53c090 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -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
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 0c2395a2dcd..e40b20f267c 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -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 *,
diff --git a/libcpp/lex.c b/libcpp/lex.c
index fa465beadb0..892cfc4494d 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -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
diff --git a/libcpp/macro.c b/libcpp/macro.c
index 52098efe63c..25f4a361189 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -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++ = ' ';
diff --git a/libcpp/traditional.c b/libcpp/traditional.c
index f4842369c3a..3c3b8ac3f1a 100644
--- a/libcpp/traditional.c
+++ b/libcpp/traditional.c
@@ -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;
+ fun_like = +1;
+ if (scan_parameters (pfile, &nparms))
+ params = (cpp_hashnode **)_cpp_commit_buff
+ (pfile, sizeof (cpp_hashnode *) * nparms);
+ else
+ fun_like = -1;
+ }
- /* Remember the params so we can clear NODE_MACRO_ARG flags. */
- macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
+ cpp_macro *macro = NULL;
- /* Setting macro to NULL indicates an error occurred, and
- prevents unnecessary work in _cpp_scan_out_logical_line. */
- if (!ok)
- macro = NULL;
- else
- {
- BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
- macro->fun_like = 1;
- }
+ 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;
-
- /* 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);
+ 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);
+ }
- return true;
+ return macro;
}
/* Copy SRC of length LEN to DEST, but convert all contiguous