+2018-08-03 Nathan Sidwell <nathan@acm.org>
+
+ An API for lazy builtin macros.
+ libcpp/
+ * include/libcpp.h (struct cpp_callbacks): Adjust
+ user_builtin_macro callback.
+ (cpp_define_lazily, cpp_define_lazy): Declare.
+ * macro.c (enter_macro_context, warn_of_redefinition): Adjust.
+ (cpp_define_lazily, cpp_define_lazy): Define.
+ (cpp_macro_definition): Adjust.
+ * pch.c (write_macrdef, save_macros): Likewise.
+ * directives.c (do_ifdef, do_ifndef): Adjust.
+ * 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.
+
2018-08-02 Nathan Sidwell <nathan@acm.org>
libcpp/
static GTY(()) int lazy_hex_fp_value_count;
static bool
-lazy_hex_fp_value (cpp_reader *pfile ATTRIBUTE_UNUSED,
- cpp_hashnode *node)
+lazy_hex_fp_value (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
{
REAL_VALUE_TYPE real;
char dec_str[64], buf1[256];
- unsigned int idx;
- if (node->value.builtin < BT_FIRST_USER
- || (int) node->value.builtin >= BT_FIRST_USER + lazy_hex_fp_value_count)
+ if (num < unsigned (BT_FIRST_USER)
+ || num >= unsigned (BT_FIRST_USER + lazy_hex_fp_value_count))
return false;
- idx = node->value.builtin - BT_FIRST_USER;
- real_from_string (&real, lazy_hex_fp_values[idx].hex_str);
+ num -= BT_FIRST_USER;
+ 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[idx].digits, 0,
- lazy_hex_fp_values[idx].mode);
-
- sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[idx].fp_suffix);
- node->flags &= ~(NODE_BUILTIN | NODE_USED);
- node->value.macro = lazy_hex_fp_values[idx].macro;
- for (idx = 0; idx < node->value.macro->count; idx++)
- if (node->value.macro->exp.tokens[idx].type == CPP_NUMBER)
- break;
- gcc_assert (idx < node->value.macro->count);
- node->value.macro->exp.tokens[idx].val.str.len = strlen (buf1);
- node->value.macro->exp.tokens[idx].val.str.text
- = (const unsigned char *) ggc_strdup (buf1);
+ lazy_hex_fp_values[num].digits, 0,
+ lazy_hex_fp_values[num].mode);
+
+ 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;
+ }
+
+ cpp_define_lazy (pfile, node, macro);
+
return true;
}
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 = node->value.macro;
- node->flags |= NODE_BUILTIN;
- node->value.builtin
- = (enum cpp_builtin_type) (BT_FIRST_USER + lazy_hex_fp_value_count);
+ 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++;
return;
}
{
if ((node->flags & NODE_BUILTIN)
&& pfile->cb.user_builtin_macro)
- pfile->cb.user_builtin_macro (pfile, node);
+ pfile->cb.user_builtin_macro (pfile, node,
+ node->value.builtin);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
{
if ((node->flags & NODE_BUILTIN)
&& pfile->cb.user_builtin_macro)
- pfile->cb.user_builtin_macro (pfile, node);
+ pfile->cb.user_builtin_macro (pfile, node,
+ node->value.builtin);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
{
if ((node->flags & NODE_BUILTIN)
&& pfile->cb.user_builtin_macro)
- pfile->cb.user_builtin_macro (pfile, node);
+ pfile->cb.user_builtin_macro (pfile, node, node->value.builtin);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
int (*has_attribute) (cpp_reader *);
/* Callback that can change a user builtin into normal macro. */
- bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *);
+ bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *, unsigned);
/* Callback to parse SOURCE_DATE_EPOCH from environment. */
time_t (*get_source_date_epoch) (cpp_reader *);
/* Callback for providing suggestions for misspelled directives. */
- const char *(*get_suggestion) (cpp_reader *, const char *, const char *const *);
+ const char *(*get_suggestion) (cpp_reader *, const char *,
+ const char *const *);
/* Callback for when a comment is encountered, giving the location
of the opening slash, a pointer to the content (which is not
extern void cpp_undef (cpp_reader *, const char *);
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 *);
+
/* Undefine all macros and assertions. */
extern void cpp_undef_all (cpp_reader *);
{
node->flags |= NODE_USED;
if ((!pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, node))
+ || !pfile->cb.user_builtin_macro (pfile, node, node->value.builtin))
&& pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
unless Wbuiltin-macro-redefined. */
if (node->flags & NODE_BUILTIN
&& (!pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, node)))
+ || !pfile->cb.user_builtin_macro (pfile, node, node->value.builtin)))
return CPP_OPTION (pfile, warn_builtin_macro_redefined);
/* Redefinitions of conditional (context-sensitive) macros, on
return true;
}
+extern cpp_macro *
+cpp_define_lazily (cpp_reader *, cpp_hashnode *node, int num)
+{
+ cpp_macro *macro = node->value.macro;
+
+ node->type = NT_MACRO;
+ node->flags |= NODE_BUILTIN;
+
+ node->value.builtin = (enum cpp_builtin_type) (num);
+
+ return macro;
+}
+
+extern void
+cpp_define_lazy (cpp_reader *, cpp_hashnode *node, cpp_macro *macro)
+{
+ node->flags &= ~(NODE_BUILTIN | NODE_USED);
+ node->value.macro = macro;
+}
+
/* Warn if a token in STRING matches one of a function-like MACRO's
parameters. */
static void
{
if (node->type != NT_MACRO
|| !pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, node))
+ || !pfile->cb.user_builtin_macro (pfile, node, node->value.builtin))
{
cpp_error (pfile, CPP_DL_ICE,
"invalid hash type %d in cpp_macro_definition",
if (hn->flags & NODE_BUILTIN)
{
if (!pfile->cb.user_builtin_macro
- || !pfile->cb.user_builtin_macro (pfile, hn))
+ || !pfile->cb.user_builtin_macro (pfile, hn, hn->value.builtin))
return 1;
}
else if (hn->value.macro->kind == cmk_assert)
if (h->flags & NODE_BUILTIN)
{
if (r->cb.user_builtin_macro)
- r->cb.user_builtin_macro (r, h);
+ r->cb.user_builtin_macro (r, h, h->value.builtin);
}
else if (h->value.macro->kind == cmk_assert)
return 1;