2018-08-06 Nathan Sidwell <nathan@acm.org>
+ Macro laziness now a property of cpp_macro.
+ libcpp/
+ * include/cpp-id-data.h (cpp_macro): Add lazy field.
+ * include/libcpp.h (struct cpp_callbacks): Rename and retype
+ user_builtin_macro to user_lazy_macro.
+ (cpp_define_lazily): Adjust,
+ (cpp_define_lazy): Delete.
+ (enum cpp_builtin_type): Remove BT_FIRST_USER, BT_LAST_USER.
+ * internal.h (_cpp_do_lazy_macro): Declare.
+ (_cpp_maybe_lazy_macro): Inline fn.
+ * macro.c (enter_macro_context, warn_of_redefinition): Use
+ _cpp_maybe_lazy_macro.
+ (_cpp_new_macro): Initialize lazy field.
+ (cpp_define_lazily): Adjust.
+ (_cpp_do_lazy_macro): Define.
+ (cpp_macro_definition): Simplify.
+ * pch.c (write_macrodef, save_macros): Likewise.
+ * directives.c (do_ifdef, do_ifndef): Use _cpp_maybe_lazy_macro.
+ * expr.c (parse_defined): Likewise.
+ gcc/c-family/
+ * c-cppbuiltin.c (lazy_hex_fp_value): Adjust for API changes.
+ (builtin_define_with_hex_fp_valye): Likewise.
+
Merge trunk r263332.
2018-08-03 Nathan Sidwell <nathan@acm.org>
struct GTY(()) lazy_hex_fp_value_struct
{
const char *hex_str;
- cpp_macro *macro;
machine_mode mode;
int digits;
const char *fp_suffix;
#define LAZY_HEX_FP_VALUES_CNT (4 * (3 + NUM_FLOATN_NX_TYPES))
static GTY(()) struct lazy_hex_fp_value_struct
lazy_hex_fp_values[LAZY_HEX_FP_VALUES_CNT];
-static GTY(()) int lazy_hex_fp_value_count;
+static GTY(()) unsigned lazy_hex_fp_value_count;
-static bool
-lazy_hex_fp_value (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
+static void
+lazy_hex_fp_value (cpp_reader *, cpp_macro *macro, unsigned num)
{
REAL_VALUE_TYPE real;
char dec_str[64], buf1[256];
- if (num < unsigned (BT_FIRST_USER)
- || num >= unsigned (BT_FIRST_USER + lazy_hex_fp_value_count))
- return false;
- num -= BT_FIRST_USER;
+ gcc_checking_assert (num < lazy_hex_fp_value_count);
+
real_from_string (&real, lazy_hex_fp_values[num].hex_str);
real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str),
lazy_hex_fp_values[num].digits, 0,
size_t len
= sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[num].fp_suffix);
gcc_assert (len < sizeof (buf1));
- cpp_macro *macro = lazy_hex_fp_values[num].macro;
for (unsigned idx = 0; idx < macro->count; idx++)
if (macro->exp.tokens[idx].type == CPP_NUMBER)
{
macro->exp.tokens[idx].val.str.len = len;
macro->exp.tokens[idx].val.str.text
= (const unsigned char *) ggc_strdup (buf1);
- break;
+ return;
}
- cpp_define_lazy (pfile, node, macro);
-
- return true;
+ /* We must have replaced a token. */
+ gcc_unreachable ();
}
/* Pass an object-like macro a hexadecimal floating-point value. */
&& flag_dump_macros == 0
&& !cpp_get_options (parse_in)->traditional)
{
- struct cpp_hashnode *node;
if (lazy_hex_fp_value_count == 0)
- cpp_get_callbacks (parse_in)->user_builtin_macro = lazy_hex_fp_value;
+ cpp_get_callbacks (parse_in)->user_lazy_macro = lazy_hex_fp_value;
sprintf (buf2, fp_cast, "1.1");
sprintf (buf1, "%s=%s", macro, buf2);
cpp_define (parse_in, buf1);
- node = C_CPP_HASHNODE (get_identifier (macro));
+ struct cpp_hashnode *node = C_CPP_HASHNODE (get_identifier (macro));
lazy_hex_fp_values[lazy_hex_fp_value_count].hex_str
= ggc_strdup (hex_str);
lazy_hex_fp_values[lazy_hex_fp_value_count].mode = TYPE_MODE (type);
lazy_hex_fp_values[lazy_hex_fp_value_count].digits = digits;
lazy_hex_fp_values[lazy_hex_fp_value_count].fp_suffix = fp_suffix;
- lazy_hex_fp_values[lazy_hex_fp_value_count].macro
- = cpp_define_lazily (parse_in, node,
- BT_FIRST_USER + lazy_hex_fp_value_count);
- lazy_hex_fp_value_count++;
+ cpp_define_lazily (parse_in, node, lazy_hex_fp_value_count++);
return;
}
node->flags |= NODE_USED;
if (node->type == NT_MACRO)
{
- if ((node->flags & NODE_BUILTIN)
- && pfile->cb.user_builtin_macro)
- pfile->cb.user_builtin_macro (pfile, node,
- node->value.builtin);
+ _cpp_maybe_lazy_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
node->flags |= NODE_USED;
if (node->type == NT_MACRO)
{
- if ((node->flags & NODE_BUILTIN)
- && pfile->cb.user_builtin_macro)
- pfile->cb.user_builtin_macro (pfile, node,
- node->value.builtin);
+ _cpp_maybe_lazy_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
node->flags |= NODE_USED;
if (node->type == NT_MACRO)
{
- if ((node->flags & NODE_BUILTIN)
- && pfile->cb.user_builtin_macro)
- pfile->cb.user_builtin_macro (pfile, node, node->value.builtin);
+ _cpp_maybe_lazy_macro (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
/* Number of parameters. */
unsigned short paramc;
+ /* Non-zero if this is a user-lazy macro, value provided by user. */
+ unsigned char lazy;
+
/* The kind of this macro (ISO, trad or assert) */
unsigned kind : 2;
tokens. */
unsigned int extra_tokens : 1;
- /* 9 bits spare (32-bit). 41 on 64-bit target. */
+ /* 1 bits spare (32-bit). 33 on 64-bit target. */
union cpp_exp_u
{
/* Callback to identify whether an attribute exists. */
int (*has_attribute) (cpp_reader *);
- /* Callback that can change a user builtin into normal macro. */
- bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *, unsigned);
+ /* Callback that can change a user lazy into normal macro. */
+ void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned);
/* Callback to parse SOURCE_DATE_EPOCH from environment. */
time_t (*get_source_date_epoch) (cpp_reader *);
BT_PRAGMA, /* `_Pragma' operator */
BT_TIMESTAMP, /* `__TIMESTAMP__' */
BT_COUNTER, /* `__COUNTER__' */
- BT_HAS_ATTRIBUTE, /* `__has_attribute__(x)' */
- BT_FIRST_USER, /* User defined builtin macros. */
- BT_LAST_USER = BT_FIRST_USER + 63
+ BT_HAS_ATTRIBUTE /* `__has_attribute__(x)' */
};
#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
extern void cpp_unassert (cpp_reader *, const char *);
/* Mark a node as a lazily defined macro. */
-extern cpp_macro *cpp_define_lazily (cpp_reader *, cpp_hashnode *node, int);
-/* Supply the definition of a lazily-defined macro. */
-extern void cpp_define_lazy (cpp_reader *, cpp_hashnode *node, cpp_macro *);
+extern void cpp_define_lazily (cpp_reader *, cpp_hashnode *node, unsigned N);
/* Undefine all macros and assertions. */
extern void cpp_undef_all (cpp_reader *);
}
/* In macro.c */
+extern cpp_macro *_cpp_do_lazy_macro (cpp_reader *pfile, cpp_macro *macro);
+inline cpp_macro *_cpp_maybe_lazy_macro (cpp_reader *pfile, cpp_hashnode *node)
+{
+ cpp_macro *macro = (node->flags & NODE_BUILTIN) ? NULL : node->value.macro;
+ if (macro && macro->lazy)
+ macro = _cpp_do_lazy_macro (pfile, macro);
+ return macro;
+}
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 *);
function where set this flag to FALSE. */
pfile->about_to_expand_macro_p = true;
- if ((node->flags & NODE_BUILTIN) && !(node->flags & NODE_USED))
+ if (!(node->flags & NODE_BUILTIN))
{
- node->flags |= NODE_USED;
- if ((!pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, node, node->value.builtin))
- && pfile->cb.used_define)
- pfile->cb.used_define (pfile, pfile->directive_line, node);
- }
-
- /* Handle standard macros. */
- if (! (node->flags & NODE_BUILTIN))
- {
- cpp_macro *macro = node->value.macro;
+ cpp_macro *macro = _cpp_maybe_lazy_macro (pfile, node);
_cpp_buff *pragma_buff = NULL;
if (macro->fun_like)
warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
const cpp_macro *macro2)
{
- const cpp_macro *macro1;
unsigned int i;
/* Some redefinitions need to be warned about regardless. */
/* Suppress warnings for builtins that lack the NODE_WARN flag,
unless Wbuiltin-macro-redefined. */
- if (node->flags & NODE_BUILTIN
- && (!pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, node, node->value.builtin)))
+ if (node->flags & NODE_BUILTIN)
return CPP_OPTION (pfile, warn_builtin_macro_redefined);
/* Redefinitions of conditional (context-sensitive) macros, on
if (node->flags & NODE_CONDITIONAL)
return false;
+ const cpp_macro *macro1 = _cpp_maybe_lazy_macro (pfile, node);
+
/* Redefinition of a macro is allowed if and only if the old and new
definitions are the same. (6.10.3 paragraph 2). */
- macro1 = node->value.macro;
/* Don't check count here as it can be different in valid
traditional redefinitions with just whitespace differences. */
macro->line = pfile->directive_line;
macro->parm.params = 0;
+ macro->lazy = 0;
macro->paramc = 0;
macro->variadic = 0;
macro->used = !CPP_OPTION (pfile, warn_unused_macros);
return true;
}
-extern cpp_macro *
-cpp_define_lazily (cpp_reader *, cpp_hashnode *node, int num)
+extern void
+cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
{
cpp_macro *macro = node->value.macro;
- node->type = NT_MACRO;
- node->flags |= NODE_BUILTIN;
+ gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < 255);
- node->value.builtin = (enum cpp_builtin_type) (num);
-
- return macro;
+ macro->lazy = num + 1;
}
-extern void
-cpp_define_lazy (cpp_reader *, cpp_hashnode *node, cpp_macro *macro)
+extern cpp_macro *
+_cpp_do_lazy_macro (cpp_reader *pfile, cpp_macro *macro)
{
- node->flags &= ~(NODE_BUILTIN | NODE_USED);
- node->value.macro = macro;
+ unsigned num = macro->lazy - 1;
+ macro->lazy = 0;
+ pfile->cb.user_lazy_macro (pfile, macro, num);
+
+ return macro;
}
/* Warn if a token in STRING matches one of a function-like MACRO's
cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
{
unsigned int i, len;
- const cpp_macro *macro;
unsigned char *buffer;
- if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
- {
- if (node->type != NT_MACRO
- || !pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, node, node->value.builtin))
- {
- cpp_error (pfile, CPP_DL_ICE,
- "invalid hash type %d in cpp_macro_definition",
- node->type);
- return 0;
- }
- }
+ gcc_checking_assert (node->type == NT_MACRO);
+
+ const cpp_macro *macro = node->value.macro;
- macro = node->value.macro;
/* Calculate length. */
len = NODE_LEN (node) * 10 + 2; /* ' ' and NUL. */
if (macro->fun_like)
write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
{
FILE *f = (FILE *) file_p;
+ bool is_void = false;
switch (hn->type)
{
case NT_VOID:
if (! (hn->flags & NODE_POISONED))
return 1;
- /* XXX Really fallthru? */
- /* FALLTHRU */
+ is_void = true;
+ goto poisoned;
case NT_MACRO:
- if (hn->flags & NODE_BUILTIN)
+ if (!(hn->flags & NODE_BUILTIN)
+ && hn->value.macro->kind != cmk_assert)
{
- if (!pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, hn, hn->value.builtin))
- return 1;
- }
- else if (hn->value.macro->kind == cmk_assert)
- return 1;
+ poisoned:
+ struct macrodef_struct s;
+ const unsigned char *defn;
- {
- struct macrodef_struct s;
- const unsigned char *defn;
+ s.name_length = NODE_LEN (hn);
+ s.flags = hn->flags & NODE_POISONED;
- s.name_length = NODE_LEN (hn);
- s.flags = hn->flags & NODE_POISONED;
-
- if (hn->type == NT_MACRO)
- {
- defn = cpp_macro_definition (pfile, hn);
- s.definition_length = ustrlen (defn);
- }
- else
- {
- defn = NODE_NAME (hn);
- s.definition_length = s.name_length;
- }
+ if (is_void)
+ {
+ defn = NODE_NAME (hn);
+ s.definition_length = s.name_length;
+ }
+ else
+ {
+ defn = cpp_macro_definition (pfile, hn);
+ s.definition_length = ustrlen (defn);
+ }
- if (fwrite (&s, sizeof (s), 1, f) != 1
- || fwrite (defn, 1, s.definition_length, f) != s.definition_length)
- {
- cpp_errno (pfile, CPP_DL_ERROR,
- "while writing precompiled header");
- return 0;
- }
- }
+ if (fwrite (&s, sizeof (s), 1, f) != 1
+ || fwrite (defn, 1, s.definition_length, f) != s.definition_length)
+ {
+ cpp_errno (pfile, CPP_DL_ERROR,
+ "while writing precompiled header");
+ return 0;
+ }
+ }
return 1;
default:
{
struct save_macro_data *data = (struct save_macro_data *)data_p;
- if (h->type != NT_MACRO)
- return 1;
-
- if (h->flags & NODE_BUILTIN)
- {
- if (r->cb.user_builtin_macro)
- r->cb.user_builtin_macro (r, h, h->value.builtin);
- }
- else if (h->value.macro->kind == cmk_assert)
- return 1;
- else
+ if (h->type == NT_MACRO
+ && !(h->flags & NODE_BUILTIN)
+ && h->value.macro->kind != cmk_assert)
{
if (data->count == data->array_size)
{