Commit 800c0e98 by Nathan Sidwell Committed by Nathan Sidwell

[PATCH] Adjust lazy macro definition

https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01072.html
	libcpp/
	* include/cpplib.h (struct cpp_callbacks): Replace
	user_builtin_macro with user_lazy_macro.
	(struct cpp_macro): add lazy field.
	(enum cpp_builtin_type): Remove BT_FIRST_USER, BT_LAST_USER.
	(cpp_define_lazily): Declare.
	* macro.c (enter_macro_context) Use _cpp_maybe_notify_macro_use.
	(warn_of_redefinition): Use cpp_builtin_macro_p, directly call
	user_lazy_macro hook.
	(_cpp_new_macro): Clear lazy field.
	(cpp_define_lazily): Define.
	(_cpp_notify_macro_use): Adjust lazy definition code.
	(cpp_macro_definition): No need to do lazy definition here.
	* pch.c (write_macdef, save_macros): Likewise.
	gcc/c-family/
	* c-cppbuiltin.c (struct lazy_hex_fp_value_struct): Remove macro
	field.
	(laxy_hex_fp_value_count): Make unsigned.
	(lazy_hex_fp_value): Provided with macro & lazy number.  Directly
	manipulate the macro.
	(builtin_defin_with_hex_fp_value): Adjust callback name, use
	cpp_define_lazily.

From-SVN: r263640
parent 6f0821f4
2018-08-17 Nathan Sidwell <nathan@acm.org>
* c-cppbuiltin.c (struct lazy_hex_fp_value_struct): Remove macro
field.
(laxy_hex_fp_value_count): Make unsigned.
(lazy_hex_fp_value): Provided with macro & lazy number. Directly
manipulate the macro.
(builtin_defin_with_hex_fp_value): Adjust callback name, use
cpp_define_lazily.
2018-08-17 David Malcolm <dmalcolm@redhat.com> 2018-08-17 David Malcolm <dmalcolm@redhat.com>
* c-format.c (enum format_type): Add gcc_dump_printf_format_type. * c-format.c (enum format_type): Add gcc_dump_printf_format_type.
......
...@@ -1570,7 +1570,6 @@ builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value) ...@@ -1570,7 +1570,6 @@ builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value)
struct GTY(()) lazy_hex_fp_value_struct struct GTY(()) lazy_hex_fp_value_struct
{ {
const char *hex_str; const char *hex_str;
cpp_macro *macro;
machine_mode mode; machine_mode mode;
int digits; int digits;
const char *fp_suffix; const char *fp_suffix;
...@@ -1583,36 +1582,35 @@ struct GTY(()) lazy_hex_fp_value_struct ...@@ -1583,36 +1582,35 @@ struct GTY(()) lazy_hex_fp_value_struct
#define LAZY_HEX_FP_VALUES_CNT (4 * (3 + NUM_FLOATN_NX_TYPES)) #define LAZY_HEX_FP_VALUES_CNT (4 * (3 + NUM_FLOATN_NX_TYPES))
static GTY(()) struct lazy_hex_fp_value_struct static GTY(()) struct lazy_hex_fp_value_struct
lazy_hex_fp_values[LAZY_HEX_FP_VALUES_CNT]; 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 static void
lazy_hex_fp_value (cpp_reader *pfile ATTRIBUTE_UNUSED, lazy_hex_fp_value (cpp_reader *, cpp_macro *macro, unsigned num)
cpp_hashnode *node)
{ {
REAL_VALUE_TYPE real; REAL_VALUE_TYPE real;
char dec_str[64], buf1[256]; 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)
return false;
idx = node->value.builtin - BT_FIRST_USER; gcc_checking_assert (num < lazy_hex_fp_value_count);
real_from_string (&real, lazy_hex_fp_values[idx].hex_str);
real_from_string (&real, lazy_hex_fp_values[num].hex_str);
real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str), real_to_decimal_for_mode (dec_str, &real, sizeof (dec_str),
lazy_hex_fp_values[idx].digits, 0, lazy_hex_fp_values[num].digits, 0,
lazy_hex_fp_values[idx].mode); lazy_hex_fp_values[num].mode);
sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[idx].fp_suffix); size_t len
node->flags &= ~(NODE_BUILTIN | NODE_USED); = sprintf (buf1, "%s%s", dec_str, lazy_hex_fp_values[num].fp_suffix);
node->value.macro = lazy_hex_fp_values[idx].macro; gcc_assert (len < sizeof (buf1));
for (idx = 0; idx < node->value.macro->count; idx++) for (unsigned idx = 0; idx < macro->count; idx++)
if (node->value.macro->exp.tokens[idx].type == CPP_NUMBER) if (macro->exp.tokens[idx].type == CPP_NUMBER)
break; {
gcc_assert (idx < node->value.macro->count); macro->exp.tokens[idx].val.str.len = len;
node->value.macro->exp.tokens[idx].val.str.len = strlen (buf1); macro->exp.tokens[idx].val.str.text
node->value.macro->exp.tokens[idx].val.str.text = (const unsigned char *) ggc_strdup (buf1);
= (const unsigned char *) ggc_strdup (buf1); return;
return true; }
/* We must have replaced a token. */
gcc_unreachable ();
} }
/* Pass an object-like macro a hexadecimal floating-point value. */ /* Pass an object-like macro a hexadecimal floating-point value. */
...@@ -1631,23 +1629,18 @@ builtin_define_with_hex_fp_value (const char *macro, ...@@ -1631,23 +1629,18 @@ builtin_define_with_hex_fp_value (const char *macro,
&& flag_dump_macros == 0 && flag_dump_macros == 0
&& !cpp_get_options (parse_in)->traditional) && !cpp_get_options (parse_in)->traditional)
{ {
struct cpp_hashnode *node;
if (lazy_hex_fp_value_count == 0) 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 (buf2, fp_cast, "1.1");
sprintf (buf1, "%s=%s", macro, buf2); sprintf (buf1, "%s=%s", macro, buf2);
cpp_define (parse_in, buf1); 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 lazy_hex_fp_values[lazy_hex_fp_value_count].hex_str
= ggc_strdup (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].mode = TYPE_MODE (type);
lazy_hex_fp_values[lazy_hex_fp_value_count].digits = digits; 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].fp_suffix = fp_suffix;
lazy_hex_fp_values[lazy_hex_fp_value_count].macro = node->value.macro; cpp_define_lazily (parse_in, node, lazy_hex_fp_value_count++);
node->flags |= NODE_BUILTIN;
node->value.builtin
= (enum cpp_builtin_type) (BT_FIRST_USER + lazy_hex_fp_value_count);
lazy_hex_fp_value_count++;
return; return;
} }
......
2018-08-17 Nathan Sidwell <nathan@acm.org> 2018-08-17 Nathan Sidwell <nathan@acm.org>
* include/cpplib.h (struct cpp_callbacks): Replace
user_builtin_macro with user_lazy_macro.
(struct cpp_macro): add lazy field.
(enum cpp_builtin_type): Remove BT_FIRST_USER, BT_LAST_USER.
(cpp_define_lazily): Declare.
* macro.c (enter_macro_context) Use _cpp_maybe_notify_macro_use.
(warn_of_redefinition): Use cpp_builtin_macro_p, directly call
user_lazy_macro hook.
(_cpp_new_macro): Clear lazy field.
(cpp_define_lazily): Define.
(_cpp_notify_macro_use): Adjust lazy definition code.
(cpp_macro_definition): No need to do lazy definition here.
* pch.c (write_macdef, save_macros): Likewise.
* include/cpplib.h (enum cpp_macro_kind): New. * include/cpplib.h (enum cpp_macro_kind): New.
(struct cpp_macro): Make body trailing array. Add kind field, (struct cpp_macro): Make body trailing array. Add kind field,
delete traditional flag. delete traditional flag.
......
...@@ -605,8 +605,8 @@ struct cpp_callbacks ...@@ -605,8 +605,8 @@ struct cpp_callbacks
/* Callback to identify whether an attribute exists. */ /* Callback to identify whether an attribute exists. */
int (*has_attribute) (cpp_reader *); int (*has_attribute) (cpp_reader *);
/* Callback that can change a user builtin into normal macro. */ /* Callback that can change a user lazy into normal macro. */
bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); void (*user_lazy_macro) (cpp_reader *, cpp_macro *, unsigned);
/* Callback to parse SOURCE_DATE_EPOCH from environment. */ /* Callback to parse SOURCE_DATE_EPOCH from environment. */
time_t (*get_source_date_epoch) (cpp_reader *); time_t (*get_source_date_epoch) (cpp_reader *);
...@@ -698,6 +698,9 @@ struct GTY(()) cpp_macro { ...@@ -698,6 +698,9 @@ struct GTY(()) cpp_macro {
/* Number of parameters. */ /* Number of parameters. */
unsigned short paramc; 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) */ /* The kind of this macro (ISO, trad or assert) */
unsigned kind : 2; unsigned kind : 2;
...@@ -778,9 +781,7 @@ enum cpp_builtin_type ...@@ -778,9 +781,7 @@ enum cpp_builtin_type
BT_PRAGMA, /* `_Pragma' operator */ BT_PRAGMA, /* `_Pragma' operator */
BT_TIMESTAMP, /* `__TIMESTAMP__' */ BT_TIMESTAMP, /* `__TIMESTAMP__' */
BT_COUNTER, /* `__COUNTER__' */ BT_COUNTER, /* `__COUNTER__' */
BT_HAS_ATTRIBUTE, /* `__has_attribute__(x)' */ BT_HAS_ATTRIBUTE /* `__has_attribute__(x)' */
BT_FIRST_USER, /* User defined builtin macros. */
BT_LAST_USER = BT_FIRST_USER + 63
}; };
#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) #define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE))
...@@ -1001,6 +1002,9 @@ extern void cpp_assert (cpp_reader *, const char *); ...@@ -1001,6 +1002,9 @@ extern void cpp_assert (cpp_reader *, const char *);
extern void cpp_undef (cpp_reader *, const char *); extern void cpp_undef (cpp_reader *, const char *);
extern void cpp_unassert (cpp_reader *, const char *); extern void cpp_unassert (cpp_reader *, const char *);
/* Mark a node as a lazily defined macro. */
extern void cpp_define_lazily (cpp_reader *, cpp_hashnode *node, unsigned N);
/* Undefine all macros and assertions. */ /* Undefine all macros and assertions. */
extern void cpp_undef_all (cpp_reader *); extern void cpp_undef_all (cpp_reader *);
......
...@@ -1273,15 +1273,6 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, ...@@ -1273,15 +1273,6 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
function where set this flag to FALSE. */ function where set this flag to FALSE. */
pfile->about_to_expand_macro_p = true; pfile->about_to_expand_macro_p = true;
if ((node->flags & NODE_BUILTIN) && !(node->flags & NODE_USED))
{
node->flags |= NODE_USED;
if ((!pfile->cb.user_builtin_macro
|| !pfile->cb.user_builtin_macro (pfile, node))
&& pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
if (cpp_user_macro_p (node)) if (cpp_user_macro_p (node))
{ {
cpp_macro *macro = node->value.macro; cpp_macro *macro = node->value.macro;
...@@ -1328,13 +1319,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, ...@@ -1328,13 +1319,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
/* Disable the macro within its expansion. */ /* Disable the macro within its expansion. */
node->flags |= NODE_DISABLED; node->flags |= NODE_DISABLED;
if (!(node->flags & NODE_USED)) /* Laziness can only affect the expansion tokens of the macro,
{ not its fun-likeness or parameters. */
node->flags |= NODE_USED; _cpp_maybe_notify_macro_use (pfile, node);
if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node);
}
if (pfile->cb.used) if (pfile->cb.used)
pfile->cb.used (pfile, location, node); pfile->cb.used (pfile, location, node);
...@@ -2993,7 +2980,6 @@ static bool ...@@ -2993,7 +2980,6 @@ static bool
warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
const cpp_macro *macro2) const cpp_macro *macro2)
{ {
const cpp_macro *macro1;
unsigned int i; unsigned int i;
/* Some redefinitions need to be warned about regardless. */ /* Some redefinitions need to be warned about regardless. */
...@@ -3002,9 +2988,7 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, ...@@ -3002,9 +2988,7 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
/* Suppress warnings for builtins that lack the NODE_WARN flag, /* Suppress warnings for builtins that lack the NODE_WARN flag,
unless Wbuiltin-macro-redefined. */ unless Wbuiltin-macro-redefined. */
if (node->flags & NODE_BUILTIN if (cpp_builtin_macro_p (node))
&& (!pfile->cb.user_builtin_macro
|| !pfile->cb.user_builtin_macro (pfile, node)))
return CPP_OPTION (pfile, warn_builtin_macro_redefined); return CPP_OPTION (pfile, warn_builtin_macro_redefined);
/* Redefinitions of conditional (context-sensitive) macros, on /* Redefinitions of conditional (context-sensitive) macros, on
...@@ -3012,9 +2996,17 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node, ...@@ -3012,9 +2996,17 @@ warn_of_redefinition (cpp_reader *pfile, cpp_hashnode *node,
if (node->flags & NODE_CONDITIONAL) if (node->flags & NODE_CONDITIONAL)
return false; return false;
cpp_macro *macro1 = node->value.macro;
if (macro1->lazy)
{
/* We don't want to mark MACRO as used, but do need to finalize
its laziness. */
pfile->cb.user_lazy_macro (pfile, macro1, macro1->lazy - 1);
macro1->lazy = 0;
}
/* Redefinition of a macro is allowed if and only if the old and new /* Redefinition of a macro is allowed if and only if the old and new
definitions are the same. (6.10.3 paragraph 2). */ 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 /* Don't check count here as it can be different in valid
traditional redefinitions with just whitespace differences. */ traditional redefinitions with just whitespace differences. */
...@@ -3481,6 +3473,7 @@ _cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement) ...@@ -3481,6 +3473,7 @@ _cpp_new_macro (cpp_reader *pfile, cpp_macro_kind kind, void *placement)
macro->line = pfile->directive_line; macro->line = pfile->directive_line;
macro->params = 0; macro->params = 0;
macro->lazy = 0;
macro->paramc = 0; macro->paramc = 0;
macro->variadic = 0; macro->variadic = 0;
macro->used = !CPP_OPTION (pfile, warn_unused_macros); macro->used = !CPP_OPTION (pfile, warn_unused_macros);
...@@ -3553,6 +3546,16 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node) ...@@ -3553,6 +3546,16 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
return true; return true;
} }
extern void
cpp_define_lazily (cpp_reader *pfile, cpp_hashnode *node, unsigned num)
{
cpp_macro *macro = node->value.macro;
gcc_checking_assert (pfile->cb.user_lazy_macro && macro && num < 255);
macro->lazy = num + 1;
}
/* Notify the use of NODE in a macro-aware context (i.e. expanding it, /* Notify the use of NODE in a macro-aware context (i.e. expanding it,
or testing its existance). Also applies any lazy definition. */ or testing its existance). Also applies any lazy definition. */
...@@ -3563,9 +3566,15 @@ _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node) ...@@ -3563,9 +3566,15 @@ _cpp_notify_macro_use (cpp_reader *pfile, cpp_hashnode *node)
switch (node->type) switch (node->type)
{ {
case NT_MACRO: case NT_MACRO:
if ((node->flags & NODE_BUILTIN) if (!(node->flags & NODE_BUILTIN))
&& pfile->cb.user_builtin_macro) {
pfile->cb.user_builtin_macro (pfile, node); cpp_macro *macro = node->value.macro;
if (macro->lazy)
{
pfile->cb.user_lazy_macro (pfile, macro, macro->lazy - 1);
macro->lazy = 0;
}
}
if (pfile->cb.used_define) if (pfile->cb.used_define)
pfile->cb.used_define (pfile, pfile->directive_line, node); pfile->cb.used_define (pfile, pfile->directive_line, node);
...@@ -3641,23 +3650,12 @@ const unsigned char * ...@@ -3641,23 +3650,12 @@ const unsigned char *
cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node) cpp_macro_definition (cpp_reader *pfile, cpp_hashnode *node)
{ {
unsigned int i, len; unsigned int i, len;
const cpp_macro *macro;
unsigned char *buffer; unsigned char *buffer;
if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN)) gcc_checking_assert (cpp_user_macro_p (node));
{
if (node->type != NT_MACRO const cpp_macro *macro = node->value.macro;
|| !pfile->cb.user_builtin_macro
|| !pfile->cb.user_builtin_macro (pfile, node))
{
cpp_error (pfile, CPP_DL_ICE,
"invalid hash type %d in cpp_macro_definition",
node->type);
return 0;
}
}
macro = node->value.macro;
/* Calculate length. */ /* Calculate length. */
len = NODE_LEN (node) * 10 + 2; /* ' ' and NUL. */ len = NODE_LEN (node) * 10 + 2; /* ' ' and NUL. */
if (macro->fun_like) if (macro->fun_like)
......
...@@ -59,9 +59,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) ...@@ -59,9 +59,7 @@ write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
/* FALLTHRU */ /* FALLTHRU */
case NT_MACRO: case NT_MACRO:
if ((hn->flags & NODE_BUILTIN) if (hn->flags & NODE_BUILTIN)
&& (!pfile->cb.user_builtin_macro
|| !pfile->cb.user_builtin_macro (pfile, hn)))
return 1; return 1;
{ {
...@@ -760,11 +758,6 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p) ...@@ -760,11 +758,6 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
{ {
struct save_macro_data *data = (struct save_macro_data *)data_p; struct save_macro_data *data = (struct save_macro_data *)data_p;
if ((h->flags & NODE_BUILTIN)
&& h->type == NT_MACRO
&& r->cb.user_builtin_macro)
r->cb.user_builtin_macro (r, h);
if (h->type != NT_VOID if (h->type != NT_VOID
&& (h->flags & NODE_BUILTIN) == 0) && (h->flags & NODE_BUILTIN) == 0)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment